]> Kevux Git Server - fll/commitdiff
Feature: allow trimmed output
authorKevin Day <thekevinday@gmail.com>
Sun, 8 Mar 2020 23:16:38 +0000 (18:16 -0500)
committerKevin Day <thekevinday@gmail.com>
Sun, 8 Mar 2020 23:16:38 +0000 (18:16 -0500)
New functions added for trimming leading and trailing whitespace from some string.

build/level_1/settings
build/monolithic/settings
level_1/fl_print/c/print.c [new file with mode: 0644]
level_1/fl_print/c/print.h [new file with mode: 0644]
level_1/fl_print/data/build/dependencies [new file with mode: 0644]
level_1/fl_print/data/build/settings [new file with mode: 0644]

index 505dd925a2ad810f0fdefae2e978c19964ea3213..63263ce13804bc2219c961fdf40036fa068b8268 100644 (file)
@@ -12,9 +12,9 @@ build_linker ar
 build_libraries -lc
 build_libraries_fll -lfll_0
 build_libraries_fll-level -lfll_0
-build_sources_library color.c console.c directory.c file.c fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c serialized.c socket.c status.c string.c utf.c
+build_sources_library color.c console.c directory.c file.c fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c print.c serialized.c socket.c status.c string.c utf.c
 build_sources_program 
-build_sources_headers color.h console.h directory.h file.h fss.h fss_basic.h fss_basic_list.h fss_status.h fss_extended.h fss_extended_list.h fss_macro.h serialized.h socket.h status.h string.h utf.h
+build_sources_headers color.h console.h directory.h file.h fss.h fss_basic.h fss_basic_list.h fss_status.h fss_extended.h fss_extended_list.h fss_macro.h print.h serialized.h socket.h status.h string.h utf.h
 build_shared yes
 build_static yes
 
index 757a45385dc450f85a3d9b020fbf8b0a19b2a4c4..f3d5fee25640305ef6725b06fc06eb862c966fb4 100644 (file)
@@ -11,9 +11,9 @@ build_compiler gcc
 build_linker ar
 build_libraries -lc
 build_libraries_fll
-build_sources_library level_0/console.c level_0/conversion.c level_0/file.c level_0/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_1/color.c level_1/console.c level_1/directory.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/utf.c level_2/execute.c level_2/file.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
+build_sources_library level_0/console.c level_0/conversion.c level_0/file.c level_0/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_1/color.c level_1/console.c level_1/directory.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/utf.c level_1/print.c level_2/execute.c level_2/file.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
 build_sources_program
-build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/file.h level_0/fss.h level_0/memory.h level_0/path_fll.h level_0/path_filesystem.h level_0/pipe.h level_0/print.h level_0/serialized.h level_0/socket.h level_0/status.h level_0/string.h level_0/type.h level_0/type_array.h level_0/utf.h level_1/color.h level_1/console.h level_1/directory.h level_1/file.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_status.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/serialized.h level_1/socket.h level_1/status.h level_1/string.h level_1/utf.h level_2/execute.h level_2/file.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/program.h level_2/status.h
+build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/file.h level_0/fss.h level_0/memory.h level_0/path_fll.h level_0/path_filesystem.h level_0/pipe.h level_0/print.h level_0/serialized.h level_0/socket.h level_0/status.h level_0/string.h level_0/type.h level_0/type_array.h level_0/utf.h level_1/color.h level_1/console.h level_1/directory.h level_1/file.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_status.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/serialized.h level_1/socket.h level_1/status.h level_1/string.h level_1/utf.h level_1/print.h level_2/execute.h level_2/file.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/program.h level_2/status.h
 build_sources_bash
 build_sources_settings
 build_shared yes
diff --git a/level_1/fl_print/c/print.c b/level_1/fl_print/c/print.c
new file mode 100644 (file)
index 0000000..b25777f
--- /dev/null
@@ -0,0 +1,523 @@
+#include <level_1/print.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fl_print_trim_string_
+  f_return_status fl_print_trim_string(FILE *output, const f_string string, const f_string_length length) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (length < 1) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    register f_string_length i = 0;
+    f_status status = f_none;
+    uint8_t width_max = 0;
+
+    for (; i < length; i++) {
+      width_max = (length - i) + 1;
+      status = f_utf_is_whitespace(string + i, width_max);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_false) break;
+    } // for
+
+    for (; i < length; i++) {
+      if (string[i] == f_string_eos) continue;
+
+      width_max = (length - i) + 1;
+      status = f_utf_is_whitespace(string + i, width_max);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_true) {
+        f_string_length j = i + 1;
+
+        if (j == length) {
+          return f_none;
+        }
+
+        for (; j < length; j++) {
+          width_max = (length - j) + 1;
+          status = f_utf_is_whitespace(string + j, width_max);
+
+          if (f_status_is_error(status)) {
+            if (f_status_set_fine(status) == f_maybe) {
+              return f_status_set_error(f_invalid_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == f_false) {
+            for (; i < j; i++) {
+              if (string[i] == f_string_eos) continue;
+
+              if (fputc(string[i], output) == 0) {
+                return f_status_set_error(f_error_output);
+              }
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == f_true) {
+          break;
+        }
+      }
+
+      if (fputc(string[i], output) == 0) {
+        return f_status_set_error(f_error_output);
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_fl_print_trim_string_
+
+#ifndef _di_fl_print_trim_string_dynamic_
+  f_return_status fl_print_trim_string_dynamic(FILE *output, const f_string_dynamic buffer) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    register f_string_length i = 0;
+    f_status status = f_none;
+    uint8_t width_max = 0;
+
+    for (; i < buffer.used; i++) {
+      width_max = (buffer.used - i) + 1;
+      status = f_utf_is_whitespace(buffer.string + i, width_max);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_false) break;
+    } // for
+
+    for (; i < buffer.used; i++) {
+      if (buffer.string[i] == f_string_eos) continue;
+
+      width_max = (buffer.used - i) + 1;
+      status = f_utf_is_whitespace(buffer.string + i, width_max);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_true) {
+        f_string_length j = i + 1;
+
+        if (j == buffer.used) {
+          return f_none;
+        }
+
+        for (; j < buffer.used; j++) {
+          width_max = (buffer.used - j) + 1;
+          status = f_utf_is_whitespace(buffer.string + j, width_max);
+
+          if (f_status_is_error(status)) {
+            if (f_status_set_fine(status) == f_maybe) {
+              return f_status_set_error(f_invalid_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == f_false) {
+            for (; i < j; i++) {
+              if (buffer.string[i] == f_string_eos) continue;
+
+              if (fputc(buffer.string[i], output) == 0) {
+                return f_status_set_error(f_error_output);
+              }
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == f_true) {
+          break;
+        }
+      }
+
+      if (fputc(buffer.string[i], output) == 0) {
+        return f_status_set_error(f_error_output);
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_fl_print_trim_string_dynamic_
+
+#ifndef _di_fl_print_trim_string_dynamic_partial_
+  f_return_status fl_print_trim_string_dynamic_partial(FILE *output, const f_string_dynamic buffer, const f_string_location location) {
+    #ifndef _di_level_1_parameter_checking_
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start >= buffer.used) return f_status_set_error(f_invalid_parameter);
+      if (location.stop >= buffer.used) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    register f_string_length i = location.start;
+    f_status status = f_none;
+    uint8_t width_max = 0;
+
+    for (; i <= location.stop; i++) {
+      width_max = (location.stop - i) + 1;
+      status = f_utf_is_whitespace(buffer.string + i, width_max);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_false) break;
+    } // for
+
+    for (; i <= location.stop; i++) {
+      if (buffer.string[i] == f_string_eos) continue;
+
+      width_max = (location.stop - i) + 1;
+      status = f_utf_is_whitespace(buffer.string + i, width_max);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_true) {
+        f_string_length j = i + 1;
+
+        if (j == location.stop) {
+          return f_none;
+        }
+
+        for (; j <= location.stop; j++) {
+          width_max = (location.stop - j) + 1;
+          status = f_utf_is_whitespace(buffer.string + j, width_max);
+
+          if (f_status_is_error(status)) {
+            if (f_status_set_fine(status) == f_maybe) {
+              return f_status_set_error(f_invalid_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == f_false) {
+            for (; i <= j; i++) {
+              if (buffer.string[i] == f_string_eos) continue;
+
+              if (fputc(buffer.string[i], output) == 0) {
+                return f_status_set_error(f_error_output);
+              }
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == f_true) {
+          break;
+        }
+      }
+
+      if (fputc(buffer.string[i], output) == 0) {
+        return f_status_set_error(f_error_output);
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_fl_print_trim_string_dynamic_partial_
+
+#ifndef _di_fl_print_trim_utf_string_
+  f_return_status fl_print_trim_utf_string(FILE *output, const f_utf_string string, const f_utf_string_length length) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string == 0) return f_status_set_error(f_invalid_parameter);
+      if (length < 1) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    register f_string_length i = 0;
+    f_status status = f_none;
+
+    for (; i < length; i++) {
+      status = f_utf_character_is_whitespace(string[i]);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_false) break;
+    } // for
+
+    for (; i < length; i++) {
+      if (string[i] == f_string_eos) continue;
+
+      status = f_utf_character_is_whitespace(string[i]);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_true) {
+        f_string_length j = i + 1;
+
+        if (j == length) {
+          return f_none;
+        }
+
+        for (; j < length; j++) {
+          status = f_utf_character_is_whitespace(string[j]);
+
+          if (f_status_is_error(status)) {
+            if (f_status_set_fine(status) == f_maybe) {
+              return f_status_set_error(f_invalid_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == f_false) {
+            for (; i < j; i++) {
+              if (string[i] == f_string_eos) continue;
+
+              if (fputc(string[i], output) == 0) {
+                return f_status_set_error(f_error_output);
+              }
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == f_true) {
+          break;
+        }
+      }
+
+      if (fputc(string[i], output) == 0) {
+        return f_status_set_error(f_error_output);
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_fl_print_trim_utf_string_
+
+#ifndef _di_fl_print_trim_utf_string_dynamic_
+  f_return_status fl_print_trim_utf_string_dynamic(FILE *output, const f_utf_string_dynamic buffer) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    register f_utf_string_length i = 0;
+    f_status status = f_none;
+
+    for (; i < buffer.used; i++) {
+      status = f_utf_character_is_whitespace(buffer.string[i]);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_false) break;
+    } // for
+
+    for (; i < buffer.used; i++) {
+      if (buffer.string[i] == f_string_eos) continue;
+
+      status = f_utf_character_is_whitespace(buffer.string[i]);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_true) {
+        f_string_length j = i + 1;
+
+        if (j == buffer.used) {
+          return f_none;
+        }
+
+        for (; j < buffer.used; j++) {
+          status = f_utf_character_is_whitespace(buffer.string[j]);
+
+          if (f_status_is_error(status)) {
+            if (f_status_set_fine(status) == f_maybe) {
+              return f_status_set_error(f_invalid_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == f_false) {
+            for (; i < j; i++) {
+              if (buffer.string[i] == f_string_eos) continue;
+
+              if (fputc(buffer.string[i], output) == 0) {
+                return f_status_set_error(f_error_output);
+              }
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == f_true) {
+          break;
+        }
+      }
+
+      if (fputc(buffer.string[i], output) == 0) {
+        return f_status_set_error(f_error_output);
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_fl_print_trim_utf_string_dynamic_
+
+#ifndef _di_fl_print_trim_utf_string_dynamic_partial_
+  f_return_status fl_print_trim_utf_string_dynamic_partial(FILE *output, const f_utf_string_dynamic buffer, const f_utf_string_location location) {
+    #ifndef _di_level_1_parameter_checking_
+      if (location.start < 0) return f_status_set_error(f_invalid_parameter);
+      if (location.stop < location.start) return f_status_set_error(f_invalid_parameter);
+      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
+      if (location.start >= buffer.used) return f_status_set_error(f_invalid_parameter);
+      if (location.stop >= buffer.used) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    register f_string_length i = location.start;
+    f_status status = f_none;
+
+    for (; i <= location.stop; i++) {
+      status = f_utf_character_is_whitespace(buffer.string[i]);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_false) break;
+    } // for
+
+    for (; i <= location.stop; i++) {
+      if (buffer.string[i] == f_string_eos) continue;
+
+      status = f_utf_character_is_whitespace(buffer.string[i]);
+
+      if (f_status_is_error(status)) {
+        if (f_status_set_fine(status) == f_maybe) {
+          return f_status_set_error(f_invalid_utf);
+        }
+
+        return status;
+      }
+
+      if (status == f_true) {
+        f_string_length j = i + 1;
+
+        if (j == location.stop) {
+          return f_none;
+        }
+
+        for (; j <= location.stop; j++) {
+          status = f_utf_character_is_whitespace(buffer.string[j]);
+
+          if (f_status_is_error(status)) {
+            if (f_status_set_fine(status) == f_maybe) {
+              return f_status_set_error(f_invalid_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == f_false) {
+            for (; i <= j; i++) {
+              if (buffer.string[i] == f_string_eos) continue;
+
+              if (fputc(buffer.string[i], output) == 0) {
+                return f_status_set_error(f_error_output);
+              }
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == f_true) {
+          break;
+        }
+      }
+
+      if (fputc(buffer.string[i], output) == 0) {
+        return f_status_set_error(f_error_output);
+      }
+    } // for
+
+    return f_none;
+  }
+#endif // _di_fl_print_trim_utf_string_dynamic_partial_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_1/fl_print/c/print.h b/level_1/fl_print/c/print.h
new file mode 100644 (file)
index 0000000..4a83b27
--- /dev/null
@@ -0,0 +1,191 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Print
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides some standard printing functions not available in a libc.
+ *
+ * Functions provided here are UTF-8 aware.
+ */
+#ifndef _FL_print_h
+#define _FL_print_h
+
+// fll-0 includes
+#include <level_0/conversion.h>
+#include <level_0/status.h>
+#include <level_0/string.h>
+#include <level_0/type.h>
+#include <level_0/utf.h>
+
+// fll-1 includes
+#include <level_1/string.h>
+#include <level_1/status.h>
+#include <level_1/print.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print a string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param length
+ *   The total number of characters to print.
+ *
+ * @return
+ *   f_none on success.
+ *   f_error_output (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_utf (with error bit) if character is an invalid UTF-8 character.
+ *   f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ */
+#ifndef _di_fl_print_trim_string_
+  extern f_return_status fl_print_trim_string(FILE *output, const f_string string, const f_string_length length);
+#endif // _di_fl_print_trim_string_
+
+/**
+ * Print a dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the entire dynamic string, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ *
+ * @return
+ *   f_none on success.
+ *   f_error_output (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_utf (with error bit) if character is an invalid UTF-8 character.
+ *   f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ */
+#ifndef _di_fl_print_trim_string_dynamic_
+  extern f_return_status fl_print_trim_string_dynamic(FILE *output, const f_string_dynamic buffer);
+#endif // _di_fl_print_trim_string_dynamic_
+
+/**
+ * Print a partial dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the only the buffer range specified by location, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ * @param location
+ *   The range within the provided string to print.
+ *
+ * @return
+ *   f_none on success.
+ *   f_error_output (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_utf (with error bit) if character is an invalid UTF-8 character.
+ *   f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ */
+#ifndef _di_fl_print_trim_string_dynamic_partial_
+  extern f_return_status fl_print_trim_string_dynamic_partial(FILE *output, const f_string_dynamic buffer, const f_string_location location);
+#endif // _di_fl_print_trim_string_dynamic_partial_
+
+/**
+ * Print a string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param length
+ *   The total number of characters to print.
+ *
+ * @return
+ *   f_none on success.
+ *   f_error_output (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_utf (with error bit) if character is an invalid UTF-8 character.
+ *   f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ */
+#ifndef _di_fl_print_trim_utf_string_
+  extern f_return_status fl_print_trim_utf_string(FILE *output, const f_utf_string string, const f_utf_string_length length);
+#endif // _di_fl_print_trim_utf_string_
+
+/**
+ * Print a dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the entire dynamic string, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ *
+ * @return
+ *   f_none on success.
+ *   f_error_output (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_utf (with error bit) if character is an invalid UTF-8 character.
+ *   f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ */
+#ifndef _di_fl_print_trim_utf_string_dynamic_
+  extern f_return_status fl_print_trim_utf_string_dynamic(FILE *output, const f_utf_string_dynamic buffer);
+#endif // _di_fl_print_trim_utf_string_dynamic_
+
+/**
+ * Print a partial dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the only the buffer range specified by location, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ * @param location
+ *   The range within the provided string to print.
+ *
+ * @return
+ *   f_none on success.
+ *   f_error_output (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_invalid_utf (with error bit) if character is an invalid UTF-8 character.
+ *   f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ */
+#ifndef _di_fl_print_trim_utf_string_dynamic_partial_
+  extern f_return_status fl_print_trim_utf_string_dynamic_partial(FILE *output, const f_utf_string_dynamic buffer, const f_utf_string_location location);
+#endif // _di_fl_print_trim_utf_string_dynamic_partial_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FL_print_h
diff --git a/level_1/fl_print/data/build/dependencies b/level_1/fl_print/data/build/dependencies
new file mode 100644 (file)
index 0000000..c6a7da6
--- /dev/null
@@ -0,0 +1,7 @@
+f_type
+f_status
+f_memory
+f_string
+f_conversion
+f_utf
+f_print
diff --git a/level_1/fl_print/data/build/settings b/level_1/fl_print/data/build/settings
new file mode 100644 (file)
index 0000000..4c16e3a
--- /dev/null
@@ -0,0 +1,30 @@
+# fss-0000
+
+project_name fl_print
+project_level 1
+
+version_major 0
+version_minor 5
+version_micro 0
+
+build_compiler gcc
+build_linker ar
+build_libraries -lc
+build_libraries_fll -lf_print -lf_utf -lf_conversion -lf_memory
+build_sources_library print.c
+build_sources_program
+build_sources_headers print.h
+build_sources_bash
+build_sources_settings
+build_shared yes
+build_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE