]> Kevux Git Server - fll/commitdiff
Feature: implement string mash support
authorKevin Day <thekevinday@gmail.com>
Tue, 28 Apr 2020 05:46:11 +0000 (00:46 -0500)
committerKevin Day <thekevinday@gmail.com>
Wed, 29 Apr 2020 02:27:59 +0000 (21:27 -0500)
String mashing is a way to append a string to another with a glue string in between.
The idea is that a space could be placed between the two strings.
A string is primarily used as the mash character so that UTF-8 can be natively supported as the glue character.

level_1/fl_string/c/private-string.c
level_1/fl_string/c/private-string.h
level_1/fl_string/c/string.c
level_1/fl_string/c/string.h

index 99976c3721435d551266a6f473272bc42ec27c56..ee01f3f88748f83b51507679142fcef831295c46 100644 (file)
@@ -170,6 +170,43 @@ extern "C" {
   }
 #endif // !defined(_di_fl_string_compare_trim_) || !defined(_di_fl_string_dynamic_compare_trim_) || !defined(_di_fl_string_dynamic_partial_compare_trim_)
 
+#if !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_)
+  f_return_status private_fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination) {
+    f_status status = f_none;
+
+    if (destination->used == 0) {
+      if (source_length > f_string_max_size) return f_status_set_error(f_string_too_large);
+
+      f_macro_string_dynamic_resize(status, (*destination), source_length);
+      if (f_status_is_error(status)) return status;
+
+      memcpy(destination->string, source, source_length);
+
+      destination->used = source_length;
+    }
+    else {
+      f_string_length total = destination->used + source_length + glue_length;
+
+      if (total > f_string_max_size) return f_status_set_error(f_string_too_large);
+
+      if (total > destination->size) {
+        f_macro_string_dynamic_resize(status, (*destination), total);
+        if (f_status_is_error(status)) return status;
+      }
+
+      for (f_string_length i = 0; i < glue_length; i++) {
+        destination->string[destination->used + i] = glue[i];
+      } // for
+
+      memcpy(destination->string + destination->used + glue_length, source, source_length);
+
+      destination->used = total;
+    }
+
+    return f_none;
+  }
+#endif // !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_)
+
 #if !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_)
   f_return_status private_fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) {
     // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations.
index cb7e011dd74f79391779bcb286d05910bae7cc57..6c339fe340a781bf80ac490b356be0864e56dd49 100644 (file)
@@ -80,6 +80,37 @@ extern "C" {
 #endif // !defined(_di_fl_string_compare_trim_) || !defined(_di_fl_string_dynamic_compare_trim_) || !defined(_di_fl_string_dynamic_partial_compare_trim_)
 
 /**
+ * Private implementation of fl_string_mash().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param glue
+ *   A string to append between the source and destination, such as a space: ' '.
+ * @param glue_length
+ *   The number of bytes the glue takes up.
+ * @param source
+ *   The source string to append.
+ * @param source_length
+ *   Total number of bytes to copy from source string.
+ * @param destination
+ *   The destination string the source and glue are appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on memory allocation error.
+ *   f_error_reallocation (with error bit) on memory reallocation error.
+ *
+ * @see fl_string_mash()
+ * @see fl_string_dynamic_mash()
+ * @see fl_string_dynamic_partial_mash()
+ */
+#if !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_)
+  extern f_return_status private_fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_)
+
+/**
  * Private implementation of fl_string_rip().
  *
  * Intended to be shared to each of the different implementation variations.
index 2b87b86de217ed8dec1db18ae991d222deab330e..4b3c1c0b4883828bb2d8d53ae309b1bbb2350f8b 100644 (file)
@@ -49,6 +49,18 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_compare_trim_
 
+#ifndef _di_fl_string_dynamic_mash_
+  f_return_status fl_string_dynamic_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
+      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_mash(glue, glue_length, source.string, source.used, destination);
+  }
+#endif // _di_fl_string_dynamic_mash_
+
 #ifndef _di_fl_string_dynamic_partial_compare_
   f_return_status fl_string_dynamic_partial_compare(const f_string_dynamic string1, const f_string_dynamic string2, const f_string_location offset1, const f_string_location offset2) {
     #ifndef _di_level_1_parameter_checking_
@@ -83,6 +95,21 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_partial_compare_trim_
 
+#ifndef _di_fl_string_dynamic_partial_mash_
+  f_return_status fl_string_dynamic_partial_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
+      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+
+      if (offset.start > offset.stop) return f_status_set_error(f_invalid_parameter);
+      if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_mash(glue, glue_length, source.string + offset.start, (offset.stop - offset.start) + 1, destination);
+  }
+#endif // _di_fl_string_dynamic_partial_mash_
+
 #ifndef _di_fl_string_dynamic_rip_
   f_return_status fl_string_dynamic_rip(const f_string_dynamic buffer, const f_string_location location, f_string_dynamic *result) {
     #ifndef _di_level_1_parameter_checking_
@@ -413,6 +440,18 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_seek_to_utf_character_
 
+#ifndef _di_fl_string_mash_
+  f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
+      if (source_length < 1) return f_status_set_error(f_invalid_parameter);
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_mash(glue, glue_length, source, source_length, destination);
+  }
+#endif // _di_fl_string_mash_
+
 #ifndef _di_fl_string_rip_
   f_return_status fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) {
     #ifndef _di_level_1_parameter_checking_
index 81434fe12c085bfa3a900b1e43209386eb5d2b86..1a1bf94408b69eb4f46918f610013a03f00d8c6e 100644 (file)
@@ -145,6 +145,35 @@ extern "C" {
 #endif // _di_fl_string_dynamic_compare_trim_
 
 /**
+ * Append the source string onto the destination with the glue in between.
+ *
+ * If the destination string is empty, then no glue is appended.
+ *
+ * @param glue
+ *   A string to append between the source and destination, such as a space: ' '.
+ * @param glue_length
+ *   The number of bytes the glue takes up.
+ * @param source
+ *   The source string to append.
+ * @param destination
+ *   The destination string the source and glue are appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on memory allocation error.
+ *   f_error_reallocation (with error bit) on memory reallocation error.
+ *
+ * @see fl_string_mash()
+ * @see fl_string_dynamic_mash()
+ * @see fl_string_dynamic_partial_mash()
+ */
+#ifndef _di_fl_string_dynamic_mash_
+  extern f_return_status fl_string_dynamic_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_mash_
+
+/**
  * Compare two strings, similar to strncmp(), but restricted to the given ranges.
  *
  * This does not stop on NULL.
@@ -204,6 +233,37 @@ extern "C" {
 #endif // _di_fl_string_dynamic_partial_compare_trim_
 
 /**
+ * Append the source string onto the destination with the glue in between.
+ *
+ * If the destination string is empty, then no glue is appended.
+ *
+ * @param glue
+ *   A string to append between the source and destination, such as a space: ' '.
+ * @param glue_length
+ *   The number of bytes the glue takes up.
+ * @param source
+ *   The source string to append.
+ * @param offset
+ *   A range within the source to restrict the append from.
+ * @param destination
+ *   The destination string the source and glue are appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on memory allocation error.
+ *   f_error_reallocation (with error bit) on memory reallocation error.
+ *
+ * @see fl_string_mash()
+ * @see fl_string_dynamic_mash()
+ * @see fl_string_dynamic_partial_mash()
+ */
+#ifndef _di_fl_string_dynamic_partial_mash_
+  extern f_return_status fl_string_dynamic_partial_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_partial_mash_
+
+/**
  * Allocate a new string from the provided range in the buffer.
  *
  * @param buffer
@@ -422,6 +482,37 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_to_utf_character_
 
 /**
+ * Append the source string onto the destination with the glue in between.
+ *
+ * If the destination string is empty, then no glue is appended.
+ *
+ * @param glue
+ *   A string to append between the source and destination, such as a space: ' '.
+ * @param glue_length
+ *   The number of bytes the glue takes up.
+ * @param source
+ *   The source string to append.
+ * @param source_length
+ *   Total number of bytes to copy from source string.
+ * @param destination
+ *   The destination string the source and glue are appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   f_string_max_size (with error bit) if the combined string is too large.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on memory allocation error.
+ *   f_error_reallocation (with error bit) on memory reallocation error.
+ *
+ * @see fl_string_mash()
+ * @see fl_string_dynamic_mash()
+ * @see fl_string_dynamic_partial_mash()
+ */
+#ifndef _di_fl_string_mash_
+  extern f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination);
+#endif // _di_fl_string_mash_
+
+/**
  * Allocate a new string from the provided range in the string.
  *
  * @param string