]> Kevux Git Server - fll/commitdiff
Bugfix: Fix problems exposed by unit testing.
authorKevin Day <thekevinday@gmail.com>
Sun, 16 Jan 2022 20:30:13 +0000 (14:30 -0600)
committerKevin Day <thekevinday@gmail.com>
Sun, 16 Jan 2022 20:30:13 +0000 (14:30 -0600)
The default f_color_format_t_initialize should still be provided.

Remove redundant context->set.warning assignments.

Change the logic to not require format strings to be defined thereby avoiding potential segfaults.

Avoid using strnlen() and instead use memcpy().
More memory is used when specifying the sizes, but strnlen() calls probably does this to some extent.
Doing this reduces the number of calls to copying ranges of strings.

Update comments to reflect latest practices.

level_0/f_color/c/color-common.h
level_0/f_color/c/color.c
level_0/f_color/c/color.h

index efd11b614d4f0142c19fc6d14f22141224e3378a..c5e20bbb4ef5cb5ac0fe32a833f1a686d5fbf416 100644 (file)
@@ -154,6 +154,7 @@ extern "C" {
     const char *medium;
   } f_color_format_t;
 
+  #define f_color_format_t_initialize           { 0, 0, 0 }
   #define f_color_format_t_initialize_linux     { f_color_string_begin_s, f_color_string_end_s, f_color_string_medium_s }
   #define f_color_format_t_initialize_xterminal { f_color_string_begin_s, f_color_string_end_s, f_color_string_medium_s }
 
index 8212ef1cda0957389a47e62e3f6426a97a17839a..89f6edc76768414a313e791d3e52c8c8016bccf1 100644 (file)
@@ -10,9 +10,7 @@ extern "C" {
       if (!context) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    f_status_t status = F_none;
-
-    // switch to the appropriate terminal color mode
+    // Switch to the appropriate terminal color mode.
     {
       char *environment = getenv("TERM");
 
@@ -24,7 +22,7 @@ extern "C" {
       }
     }
 
-    status = macro_fl_color_save_1(&context->reset, context->format, context->list.reset);
+    f_status_t status = macro_fl_color_save_1(&context->reset, context->format, context->list.reset);
 
     if (F_status_is_error_not(status)) {
       status = macro_fl_color_save_1(&context->warning, context->format, context->list.yellow);
@@ -105,9 +103,6 @@ extern "C" {
       context->set.normal.before = &context->normal;
       context->set.normal.after = &context->reset;
 
-      context->set.warning.before = &context->warning;
-      context->set.warning.after = &context->reset;
-
       context->set.normal_reset.before = &context->normal_reset;
       context->set.normal_reset.after = &context->reset;
     }
@@ -117,82 +112,220 @@ extern "C" {
 #endif // _di_f_color_load_context_
 
 #ifndef _di_f_color_save_
-  f_status_t f_color_save(f_string_dynamic_t *buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5) {
+  f_status_t f_color_save(f_string_dynamic_t * const buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5) {
     #ifndef _di_level_0_parameter_checking_
       if (!buffer) return F_status_set_error(F_parameter);
       if (!color1) return F_status_set_error(F_parameter);
 
-      // make sure all data is in the proper order.
-      if (!color2 && (color3 != 0 || color4 != 0 || color5 != 0)) return F_status_set_error(F_parameter);
-      if (!color3 && (color4 != 0 || color5 != 0))                return F_status_set_error(F_parameter);
-      if (!color4 && color5 != 0)                                 return F_status_set_error(F_parameter);
+      // Require all data to be in the proper order.
+      if (!color2 && (color3 || color4 || color5)) return F_status_set_error(F_parameter);
+      if (!color3 && (color4 || color5))           return F_status_set_error(F_parameter);
+      if (!color4 && color5)                       return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    f_array_length_t string_size = strnlen(format.begin, F_color_max_size_d) + strnlen(format.end, F_color_max_size_d) + 1;
+    f_array_length_t size_string = 0;
+    uint8_t size_begin = 0;
+    uint8_t size_medium = 0;
+    uint8_t size_end = 0;
+    uint8_t size_color1 = 0;
+    uint8_t size_color2 = 0;
+    uint8_t size_color3 = 0;
+    uint8_t size_color4 = 0;
+    uint8_t size_color5 = 0;
+
+    if (format.begin) {
+      size_begin = strnlen(format.begin, F_color_max_size_d);
+      size_string += size_begin;
+    }
 
-    if      (!color2) string_size += strnlen(color1, F_color_max_size_d);
-    else if (!color3) string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d);
-    else if (!color4) string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d) + strnlen(color3, F_color_max_size_d);
-    else if (!color5) string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d) + strnlen(color3, F_color_max_size_d) + strnlen(color4, F_color_max_size_d);
-    else              string_size += strnlen(color1, F_color_max_size_d) + strnlen(color2, F_color_max_size_d) + strnlen(color3, F_color_max_size_d) + strnlen(color4, F_color_max_size_d) + strnlen(color5, F_color_max_size_d);
+    if (format.medium) {
+      size_medium += strnlen(format.medium, F_color_max_size_d);
+    }
 
-    if (buffer->size - buffer->used - 1 < string_size) {
-      f_status_t status = F_none;
+    if (format.end) {
+      size_end = strnlen(format.end, F_color_max_size_d);
+      size_string += size_end;
+    }
 
-      macro_f_string_dynamic_t_resize(status, (*buffer), buffer->used + string_size + 1);
+    size_color1 = strnlen(color1, F_color_max_size_d);
+    size_string += size_color1;
 
-      if (F_status_is_error(status)) {
-        return status;
-      }
+    if (color2) {
+      size_color2 = strnlen(color2, F_color_max_size_d);
+      size_string += size_color2;
+    }
+
+    if (color3) {
+      size_color3 = strnlen(color3, F_color_max_size_d);
+      size_string += size_color3;
+    }
+
+    if (color4) {
+      size_color4 = strnlen(color4, F_color_max_size_d);
+      size_string += size_color4;
+    }
+
+    if (color5) {
+      size_color5 = strnlen(color5, F_color_max_size_d);
+      size_string += size_color5;
+    }
+
+    {
+      const f_status_t status = f_string_dynamic_increase_by(size_string + 1, buffer);
+      if (F_status_is_error(status)) return status;
     }
 
     if (!color2) {
-      strncat(buffer->string, format.begin, F_color_max_size_d);
-      strncat(buffer->string, color1, F_color_max_size_d);
-      strncat(buffer->string, format.end, F_color_max_size_d);
+      if (size_begin) {
+        memcpy(buffer->string + buffer->used, format.begin, size_begin);
+        buffer->used += size_begin;
+      }
+
+      memcpy(buffer->string + buffer->used, color1, size_color1);
+      buffer->used += size_color1;
+
+      if (size_end) {
+        memcpy(buffer->string + buffer->used, format.end, size_end);
+        buffer->used += size_end;
+      }
     }
     else if (!color3) {
-      strncat(buffer->string, format.begin, F_color_max_size_d);
-      strncat(buffer->string, color1, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color2, F_color_max_size_d);
-      strncat(buffer->string, format.end, F_color_max_size_d);
+      if (size_begin) {
+        memcpy(buffer->string + buffer->used, format.begin, size_begin);
+        buffer->used += size_begin;
+      }
+
+      memcpy(buffer->string + buffer->used, color1, size_color1);
+      buffer->used += size_color1;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color2, size_color2);
+      buffer->used += size_color2;
+
+      if (size_end) {
+        memcpy(buffer->string + buffer->used, format.end, size_end);
+        buffer->used += size_end;
+      }
     }
     else if (!color4) {
-      strncat(buffer->string, format.begin, F_color_max_size_d);
-      strncat(buffer->string, color1, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color2, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color3, F_color_max_size_d);
-      strncat(buffer->string, format.end, F_color_max_size_d);
+      if (size_begin) {
+        memcpy(buffer->string + buffer->used, format.begin, size_begin);
+        buffer->used += size_begin;
+      }
+
+      memcpy(buffer->string + buffer->used, color1, size_color1);
+      buffer->used += size_color1;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color2, size_color2);
+      buffer->used += size_color2;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color3, size_color3);
+      buffer->used += size_color3;
+
+      if (size_end) {
+        memcpy(buffer->string + buffer->used, format.end, size_end);
+        buffer->used += size_end;
+      }
     }
     else if (!color5) {
-      strncat(buffer->string, format.begin, F_color_max_size_d);
-      strncat(buffer->string, color1, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color2, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color3, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color4, F_color_max_size_d);
-      strncat(buffer->string, format.end, F_color_max_size_d);
+      if (size_begin) {
+        memcpy(buffer->string + buffer->used, format.begin, size_begin);
+        buffer->used += size_begin;
+      }
+
+      memcpy(buffer->string + buffer->used, color1, size_color1);
+      buffer->used += size_color1;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color2, size_color2);
+      buffer->used += size_color2;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color3, size_color3);
+      buffer->used += size_color3;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color4, size_color4);
+      buffer->used += size_color4;
+
+      if (size_end) {
+        memcpy(buffer->string + buffer->used, format.end, size_end);
+        buffer->used += size_end;
+      }
     }
     else {
-      strncat(buffer->string, format.begin, F_color_max_size_d);
-      strncat(buffer->string, color1, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color2, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color3, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color4, F_color_max_size_d);
-      strncat(buffer->string, format.medium, F_color_max_size_d);
-      strncat(buffer->string, color5, F_color_max_size_d);
-      strncat(buffer->string, format.end, F_color_max_size_d);
-    }
-
-    buffer->used += string_size;
+      if (size_begin) {
+        memcpy(buffer->string + buffer->used, format.begin, size_begin);
+        buffer->used += size_begin;
+      }
+
+      memcpy(buffer->string + buffer->used, color1, size_color1);
+      buffer->used += size_color1;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color2, size_color2);
+      buffer->used += size_color2;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color3, size_color3);
+      buffer->used += size_color3;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color4, size_color4);
+      buffer->used += size_color4;
+
+      if (size_medium) {
+        memcpy(buffer->string + buffer->used, format.medium, size_medium);
+        buffer->used += size_medium;
+      }
+
+      memcpy(buffer->string + buffer->used, color5, size_color5);
+      buffer->used += size_color5;
+
+      if (size_end) {
+        memcpy(buffer->string + buffer->used, format.end, size_end);
+        buffer->used += size_end;
+      }
+    }
+
     buffer->string[buffer->used] = 0;
 
     return F_none;
index 78b510e5e110e9f6c304a94ca3fb9b5f0ee8ee8f..658bcef56b3f1d964520ee63318847861f0762c1 100644 (file)
@@ -48,8 +48,11 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_color_save()
+ *
+ * @see f_color_save()
  */
 #ifndef _di_f_color_load_context_
   extern f_status_t f_color_load_context(f_color_context_t *context, const bool use_light_colors);
@@ -66,6 +69,7 @@ extern "C" {
  *
  * @param buffer
  *   The string to save the colors to.
+ *   The buffer will become NULL terminated after the appended string length.
  * @param format
  *   The color format parts.
  * @param color1
@@ -82,11 +86,14 @@ extern "C" {
  * @return
  *   F_none on success.
  *
- *   F_memory_not (with error bit) on out of memory.
  *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_string_dynamic_increase_by()
+ *
+ * @see f_string_dynamic_increase_by()
  */
 #ifndef _di_f_color_save_
-  extern f_status_t f_color_save(f_string_dynamic_t *buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5);
+  extern f_status_t f_color_save(f_string_dynamic_t * const buffer, const f_color_format_t format, const char *color1, const char *color2, const char *color3, const char *color4, const char *color5);
 
   #define macro_fl_color_save_1(buffer, format, color1)                                 f_color_save(buffer, format, color1, 0, 0, 0, 0);
   #define macro_fl_color_save_2(buffer, format, color1, color2)                         f_color_save(buffer, format, color1, color2, 0, 0, 0);