]> Kevux Git Server - fll/commitdiff
Bugfix: IKI variables are not substituting consistently.
authorKevin Day <thekevinday@gmail.com>
Fri, 14 Jan 2022 01:45:39 +0000 (19:45 -0600)
committerKevin Day <thekevinday@gmail.com>
Fri, 14 Jan 2022 01:50:05 +0000 (19:50 -0600)
There appears to be a logic flaw where when more than one IKI variables are present, they start overwriting.

I changed the logic to focus more on the content loop.
The arguments array is only incremented for the content row.
When the resulting row is empty and is not quoted, then do not increment the arguments array.

Remove unnecessary NULL insertions.
The only time the NULL needs to be inserted is at the end when done adding all of the characters to the argument buffer.

Always append using the nulless append functions.

level_3/fake/c/private-make-operate.c
level_3/fake/c/private-make-operate_process.c

index 712446b51794c4905180e0b56f207a798debe11a..2b78cf96bbca74fc503abbe7c3d8976b2442bb4c 100644 (file)
@@ -180,8 +180,7 @@ extern "C" {
     f_array_length_t k = 0;
     f_array_length_t l = 0;
 
-    f_array_length_t used_arguments = 0;
-    f_array_length_t previous = 0;
+    f_array_length_t used_content = 0;
 
     const f_string_t reserved_name[] = {
       fake_make_parameter_variable_build_s,
@@ -297,8 +296,6 @@ extern "C" {
 
       range = content.array[i];
 
-      used_arguments = arguments->used;
-
       *status = fl_iki_read(state, &data_make->buffer, &range, &iki_variable, &iki_vocabulary, &iki_content, &iki_delimits);
 
       if (F_status_is_error(*status)) {
@@ -309,20 +306,16 @@ extern "C" {
         break;
       }
 
-      for (k = 0; k < iki_delimits.used; ++k) {
-        data_make->buffer.string[iki_delimits.array[k]] = f_iki_syntax_placeholder_s[0];
+      // Apply the IKI delimits to the buffer.
+      for (j = 0; j < iki_delimits.used; ++j) {
+        data_make->buffer.string[iki_delimits.array[j]] = f_iki_syntax_placeholder_s[0];
       } // for
 
-      *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments);
-
-      if (F_status_is_error(*status)) {
-        fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true);
-
-        break;
-      }
-
       if (iki_variable.used) {
-        if (iki_variable.array[0].start > 0 && content.array[i].start < iki_variable.array[0].start) {
+        used_content = arguments->array[arguments->used].used;
+
+        // Copy everything up to the start of the first IKI variable.
+        if (iki_variable.array[0].start && content.array[i].start < iki_variable.array[0].start) {
           range.start = content.array[i].start;
           range.stop = iki_variable.array[0].start - 1;
 
@@ -335,23 +328,10 @@ extern "C" {
           }
         }
 
-        for (j = 0, previous = iki_variable.array[0].start; j < iki_variable.used; ++j) {
+        for (j = 0; j < iki_variable.used; ++j) {
 
           is = 0;
 
-          if (previous + 1 < iki_variable.array[j].start) {
-            range.start = previous + 1;
-            range.stop = iki_variable.array[j].start - 1;
-
-            *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]);
-
-            if (F_status_is_error(*status)) {
-              fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true);
-
-              break;
-            }
-          }
-
           *status = fl_string_dynamic_partial_compare(vocabulary_define, data_make->buffer, range_define, iki_vocabulary.array[j]);
 
           if (*status == F_equal_to) {
@@ -384,10 +364,10 @@ extern "C" {
             // Check against reserved parameter names and if matches use them instead.
             if (fl_string_dynamic_partial_compare_string(fake_make_parameter_variable_return_s, data_make->buffer, fake_make_parameter_variable_return_s_length, iki_content.array[j]) == F_equal_to) {
               if (data_make->setting_make.parameter.array[0].value.array[0].used) {
-                *status = f_string_dynamic_append(data_make->setting_make.parameter.array[0].value.array[0], &arguments->array[arguments->used]);
+                *status = f_string_dynamic_append_nulless(data_make->setting_make.parameter.array[0].value.array[0], &arguments->array[arguments->used]);
 
                 if (F_status_is_error(*status)) {
-                  fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true);
+                  fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true);
 
                   break;
                 }
@@ -402,15 +382,6 @@ extern "C" {
                 }
               }
 
-              *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]);
-
-              if (F_status_is_error(*status)) {
-                fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true);
-
-                break;
-              }
-
-              ++arguments->used;
               unmatched = F_false;
             }
             else {
@@ -427,7 +398,7 @@ extern "C" {
                 if (F_status_is_error(*status)) {
                   fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true);
 
-                  return;
+                  break;
                 }
 
                 for (l = 0; l < reserved_value[k]->used; ++l) {
@@ -444,36 +415,25 @@ extern "C" {
                     }
                   }
 
-                  *status = f_string_dynamic_append(reserved_value[k]->array[l], &arguments->array[arguments->used]);
+                  *status = f_string_dynamic_append_nulless(reserved_value[k]->array[l], &arguments->array[arguments->used]);
 
                   if (F_status_is_error(*status)) {
-                    fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true);
+                    fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true);
 
                     break;
                   }
                 } // for
 
-                if (F_status_is_error_not(*status) && !unmatched) {
-                  *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]);
-
-                  if (F_status_is_error(*status)) {
-                    fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true);
-
-                    break;
-                  }
-
-                  ++arguments->used;
-                }
-                else {
-                  break;
-                }
+                if (F_status_is_error(*status) || !unmatched) break;
               } // for
+
+              if (F_status_is_error(*status)) break;
             }
 
             if (unmatched && parameter->used) {
               for (k = 0; k < parameter->used; ++k) {
 
-                // Check against iki variable list.
+                // Check against IKI variable list.
                 *status = fl_string_dynamic_partial_compare_dynamic(parameter->array[k].name, data_make->buffer, iki_content.array[j]);
 
                 if (*status == F_equal_to) {
@@ -520,16 +480,6 @@ extern "C" {
 
                           break;
                         }
-
-                        *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]);
-
-                        if (F_status_is_error(*status)) {
-                          fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true);
-
-                          break;
-                        }
-
-                        ++arguments->used;
                       } // for
                     }
                   }
@@ -577,32 +527,29 @@ extern "C" {
             }
           }
 
-          previous = iki_variable.array[j].stop;
-        } // for
-
-        if (F_status_is_error(*status)) break;
-
-        if (iki_variable.array[iki_variable.used - 1].stop < content.array[i].stop) {
-          range.start = iki_variable.array[iki_variable.used - 1].stop + 1;
-          range.stop = content.array[i].stop;
-
-          // If arguments->used was not incremented, then use the value, otherwise arguments->used is past the value to append to, so subtract 1.
-          if (used_arguments == arguments->used) {
-            *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]);
-          }
-          else {
-            *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used - 1]);
+          // Make sure to copy and content between multiple IKI variables within the same content.
+          if (j + 1 < iki_variable.used) {
+            if (iki_variable.array[j].stop + 1 < iki_variable.array[j + 1].start && iki_variable.array[j + 1].stop <= content.array[i].stop) {
+              range.start = iki_variable.array[j].stop + 1;
+              range.stop = iki_variable.array[j + 1].start - 1;
 
-            if (F_status_is_error_not(*status)) {
-              *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used - 1]);
+              *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]);
 
               if (F_status_is_error(*status)) {
-                fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true);
+                fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true);
 
                 break;
               }
             }
           }
+        } // for
+
+        // Copy everything after the last IKI variable to the end of the content.
+        if (iki_variable.used && content.array[i].stop > iki_variable.array[iki_variable.used - 1].stop) {
+          range.start = iki_variable.array[iki_variable.used - 1].stop + 1;
+          range.stop = content.array[i].stop;
+
+          *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]);
 
           if (F_status_is_error(*status)) {
             fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true);
@@ -610,23 +557,33 @@ extern "C" {
             break;
           }
         }
+
+        *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]);
+
+        if (F_status_is_error(*status)) {
+          fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true);
+
+          break;
+        }
+
+        // Unquoted empty Content after IKI variable substitution are not used as an argument.
+        if (used_content < arguments->array[arguments->used].used || quotes.array[i]) {
+          ++arguments->used;
+        }
       }
       else {
         *status = f_string_dynamic_partial_append_nulless(data_make->buffer, content.array[i], &arguments->array[arguments->used]);
 
         if (F_status_is_error(*status)) {
-          fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append_nulless", F_true);
+          fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true);
 
           break;
         }
-      }
 
-      // If iki variable did not match (results in empty string) or iki variable is inside quotes, then increment.
-      if (used_arguments == arguments->used) {
         *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]);
 
         if (F_status_is_error(*status)) {
-          fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true);
+          fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true);
 
           break;
         }
index 9dd755f73b4c128d0221f09b29ad3ae89c4f59d0..1ca107b07809b60b80456232ed39a835f8558051 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
         }
         else {
 
-          // For all other cases, if the previous condition is false, then it is always false because "false && XX" is always false.
+          // For all other cases, if the previous condition is false, then it is always false because "false && X" is always false.
           if (state_process->block_result == fake_condition_result_false_e) {
             state_process->condition_result = state_process->block_result;