]> Kevux Git Server - fll/commitdiff
Progress: featureless make.
authorKevin Day <thekevinday@gmail.com>
Mon, 31 Aug 2020 02:10:34 +0000 (21:10 -0500)
committerKevin Day <thekevinday@gmail.com>
Mon, 31 Aug 2020 02:13:33 +0000 (21:13 -0500)
Continue work on the if operation section if conditions.
Looks like I needed some functionality in f_file, currently incomplete.

level_0/f_conversion/c/conversion.h
level_0/f_file/c/file.c
level_0/f_file/c/file.h
level_2/fll_program/c/program.h
level_3/byte_dump/c/byte_dump.c
level_3/fake/c/private-make.c
level_3/fake/c/private-make.h
level_3/fake/documents/fakefile.txt
level_3/fake/specifications/fakefile.txt

index ea32d6c378b9cacd2de10eca56fd017287574713..99038404eb7c871ed91d3d7c9563734a22834a8b 100644 (file)
@@ -28,7 +28,7 @@ extern "C" {
 /**
  * Provide custom conversion scale limits based on selected type sizes.
  *
- * Utilize the f_type_number_* defines to determine the expected sizes to use for the sxcales.
+ * Utilize the f_type_number_* defines to determine the expected sizes to use for the scales.
  *
  * 64-bit is the designed default.
  */
index b5f6e180d007dcfb1171706a8755848a8e4b8a8f..e932512c03d522b6945f24edd7019a8fba4f7fbb 100644 (file)
@@ -1180,6 +1180,50 @@ extern "C" {
   }
 #endif // _di_f_file_mode_from_string_
 
+#ifndef _di_f_file_mode_read_
+  f_return_status f_file_mode_read(const f_string path, mode_t *mode) {
+    #ifndef _di_level_0_parameter_checking_
+      if (path == 0) return F_status_set_error(F_parameter);
+      if (mode == 0) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    struct stat stat_file;
+
+    memset(&stat_file, 0, sizeof(struct stat));
+
+    f_status status = private_f_file_stat(path, F_true, &stat_file);
+    if (F_status_is_error(status)) {
+      return status;
+    }
+
+    *mode = stat_file.st_mode;
+
+    return F_none;
+  }
+#endif // _di_f_file_mode_read_
+
+#ifndef _di_f_file_mode_read_at_
+  f_return_status f_file_mode_read_at(const int at_id, const f_string path, mode_t *mode) {
+    #ifndef _di_level_0_parameter_checking_
+      if (path == 0) return F_status_set_error(F_parameter);
+      if (mode == 0) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    struct stat stat_file;
+
+    memset(&stat_file, 0, sizeof(struct stat));
+
+    f_status status = private_f_file_stat(path, F_true, &stat_file);
+    if (F_status_is_error(status)) {
+      return status;
+    }
+
+    *mode = stat_file.st_mode;
+
+    return F_none;
+  }
+#endif // _di_f_file_mode_read_at_
+
 #ifndef _di_f_file_mode_set_
   f_return_status f_file_mode_set(const f_string path, const mode_t mode) {
     #ifndef _di_level_0_parameter_checking_
@@ -1200,6 +1244,18 @@ extern "C" {
   }
 #endif // _di_f_file_mode_set_at_
 
+#ifndef _di_f_file_mode_determine_
+  f_return_status f_file_mode_to_mode(const f_file_mode mode_from, const uint8_t mode_replace, mode_t *mode_to) {
+    #ifndef _di_level_0_parameter_checking_
+      if (mode_to == 0) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    // @todo
+
+    return F_none;
+  }
+#endif // _di_f_file_mode_determine_
+
 #ifndef _di_f_file_name_base_
   f_return_status f_file_name_base(const f_string path, const f_string_length length, f_string_dynamic *name_base) {
     #ifndef _di_level_0_parameter_checking_
index f2e961e20d5a9b8666ff0a467335697eb5d041b3..550757149d416f3b94bdb13fd6595ae1bdb43a4d 100644 (file)
@@ -1169,7 +1169,7 @@ extern "C" {
  * @param mode_change
  *   The file mode values to change.
  * @param mode_replace
- *   The mode modes that should be replaced instead of simply changed.
+ *   The modes designated to be replaced instead of simply changed.
  * @param directory_is
  *   Set to TRUE if the file is a directory, FALSE otherwise.
  * @param mode
@@ -1248,6 +1248,8 @@ extern "C" {
  *
  * @fixme the possibilities are a bit extensive and this needs additional review; remove this fixme when this review is completed.
  *
+ * @fixme apparently "u+g" is valid such that the mode from the group (g) is applied to the user (u) mode.
+ *
  * @param string
  *   A NULL terminated string designating the desired mode, following the above string syntax.
  * @param umask
@@ -1273,6 +1275,58 @@ extern "C" {
 #endif // _di_f_file_mode_from_string_
 
 /**
+ * Get the current file mode as an f_file_mode.
+ *
+ * @param path
+ *   The path file name.
+ * @param mode
+ *   The read file mode.
+ *
+ * @return
+ *   F_none on success.
+ *   F_access_denied (with error bit) if access to the file was denied.
+ *   F_directory (with error bit) on invalid directory.
+ *   F_file_found_not (with error bit) if the file was not found.
+ *   F_loop (with error bit) on loop error.
+ *   F_memory_out (with error bit) if out of memory.
+ *   F_name (with error bit) on path name error.
+ *   F_number_overflow (with error bit) on overflow error.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fstat()
+ */
+#ifndef _di_f_file_mode_read_
+  extern f_return_status f_file_mode_read(const f_string path, mode_t *mode);
+#endif // _di_f_file_mode_read_
+
+/**
+ * Get the current file mode as an f_file_mode.
+ *
+ * @param at_id
+ *   The parent directory, as an open directory file descriptor, in which path is relative to.
+ * @param path
+ *   The path file name.
+ * @param mode
+ *   The read file mode.
+ *
+ * @return
+ *   F_none on success.
+ *   F_access_denied (with error bit) if access to the file was denied.
+ *   F_directory (with error bit) on invalid directory.
+ *   F_file_found_not (with error bit) if the file was not found.
+ *   F_loop (with error bit) on loop error.
+ *   F_memory_out (with error bit) if out of memory.
+ *   F_name (with error bit) on path name error.
+ *   F_number_overflow (with error bit) on overflow error.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fstatat()
+ */
+#ifndef _di_f_file_mode_read_at_
+  extern f_return_status f_file_mode_read_at(const int at_id, const f_string path, mode_t *mode);
+#endif // _di_f_file_mode_read_at_
+
+/**
  * Change mode of a given file at the specified path.
  *
  * This does not set mode based on umask(), be sure to apply umask if so desired.
@@ -1337,6 +1391,26 @@ extern "C" {
 #endif // _di_f_file_mode_set_at_
 
 /**
+ * Convert an f_file_mode type to a mode_t type.
+ *
+ * @param mode_from
+ *   The file mode to convert from.
+ * @param mode_replace
+ *   The modes designated to be replaced instead of simply changed.
+ * @param mode_to
+ *   The determined mode.
+ *
+ * @return
+ *   F_none on success.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see f_file_mode_from_string()
+ */
+#ifndef _di_f_file_mode_determine_
+  extern f_return_status f_file_mode_to_mode(const f_file_mode mode_from, const uint8_t mode_replace, mode_t *mode_to);
+#endif // _di_f_file_mode_determine_
+
+/**
  * Get the base name of a file path.
  *
  * @param path
index 4afe1cbd3dfec84720644582bcbb7bf52c301d0b..311bd18cb17fc782886dabbd6f2fcc921ee4c754 100644 (file)
@@ -315,6 +315,7 @@ extern "C" {
 #ifndef _di_fll_program_parameter_additional_rip_
   extern f_return_status fll_program_parameter_additional_rip(const f_string *argv, const f_string_lengths additional, f_string_dynamics *destination);
 #endif // _di_fll_program_parameter_additional_rip_
+
 /**
  * Mash together all additional arguments associated with a given console parameter.
  *
index acafe36f039fa0eaacfba9a0d7f71f1b4d201419..993b8316da4ea0fe7e4ca3d1f85c55890985b6b7 100644 (file)
@@ -256,14 +256,14 @@ extern "C" {
 
       if (data->parameters[byte_dump_parameter_first].result == f_console_result_additional && data->parameters[byte_dump_parameter_last].result == f_console_result_additional) {
         if (data->first > data->last) {
-            fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '");
-            fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, byte_dump_long_first);
-            fl_color_print(f_type_error, data->context.error, data->context.reset, "' value cannot be greater than the parameter '");
-            fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, byte_dump_long_last);
-            fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' value.");
+          fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '");
+          fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, byte_dump_long_first);
+          fl_color_print(f_type_error, data->context.error, data->context.reset, "' value cannot be greater than the parameter '");
+          fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, byte_dump_long_last);
+          fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' value.");
 
-            byte_dump_delete_data(data);
-            return F_status_set_error(status);
+          byte_dump_delete_data(data);
+          return F_status_set_error(status);
         }
 
         // store last position as a relative offset from first instead of an absolute position.
index 43ffc9af8d5ee272dd93a183ef7f94283ade2034..04ff9b80a5de6f29881622cf8264cf002f6b2215 100644 (file)
@@ -1538,6 +1538,9 @@ extern "C" {
       else if (operation_if == fake_make_operation_if_type_false_next) {
         operation_if = fake_make_operation_if_type_false;
       }
+      else if (operation_if == fake_make_operation_if_type_false_always_next) {
+        operation_if = fake_make_operation_if_type_false_always;
+      }
 
       fake_make_operate_validate(data, section->name, operation, *operation_name, arguments[i], &operation_if, data_make, section_stack, status);
 
@@ -1547,6 +1550,10 @@ extern "C" {
           operation_if = fake_make_operation_if_type_else_true_next;
           continue;
         }
+        else if (operation_if == fake_make_operation_if_type_false_always) {
+          operation_if = fake_make_operation_if_type_else_false_next_always;
+          continue;
+        }
         else if (operation_if == fake_make_operation_if_type_else_false) {
           operation_if = 0;
           continue;
@@ -1576,6 +1583,16 @@ extern "C" {
               break;
           }
         }
+
+        if (operation_if == fake_make_operation_if_type_false) {
+          operation_if = fake_make_operation_if_type_else_true_next;
+        }
+        else if (operation_if == fake_make_operation_if_type_false_always) {
+          operation_if = fake_make_operation_if_type_else_false_next_always;
+        }
+        else if (operation_if == fake_make_operation_if_type_else_false) {
+          operation_if = 0;
+        }
       }
 
       if (operation_if == fake_make_operation_if_type_else_true || operation_if == fake_make_operation_if_type_else_false) {
@@ -1587,8 +1604,8 @@ extern "C" {
       else if (operation_if == fake_make_operation_if_type_true) {
         operation_if = fake_make_operation_if_type_else_false_next;
       }
-      else if (operation_if == fake_make_operation_if_type_false) {
-        operation_if = fake_make_operation_if_type_else_true_next;
+      else if (operation_if == fake_make_operation_if_type_false_always) {
+        operation_if = fake_make_operation_if_type_else_false_next_always;
       }
 
       if (F_status_is_error(*status)) {
@@ -1666,8 +1683,8 @@ extern "C" {
       *status = F_status_set_error(F_failure);
     }
 
-    // ensure an error is returned during recursion if the last known section operation failed.
-    if (success == F_false && F_status_is_fine(*status)) {
+    // ensure an error is returned during recursion if the last known section operation failed, except for the main operation.
+    if (success == F_false && F_status_is_fine(*status) && section_stack->used > 1) {
       *status = F_status_set_error(F_failure);
     }
 
@@ -1830,7 +1847,7 @@ extern "C" {
     }
 
     if (operation == fake_make_operation_type_else) {
-      if (*operation_if == fake_make_operation_if_type_else_false_next) {
+      if (*operation_if == fake_make_operation_if_type_else_false_next || *operation_if == fake_make_operation_if_type_else_false_next_always) {
         *operation_if = fake_make_operation_if_type_else_false;
       }
       else if (*operation_if != fake_make_operation_if_type_else_true_next) {
@@ -1959,8 +1976,6 @@ extern "C" {
         return;
       }
 
-      // @todo: these conversions need to be UTF-8 friendly.
-
       if (*operation_if == fake_make_operation_if_type_if_success) {
         if (success) {
           *operation_if = fake_make_operation_if_type_true_next;
@@ -1985,7 +2000,49 @@ extern "C" {
 
       if (*operation_if == fake_make_operation_if_type_if_mode) {
         *operation_if = fake_make_operation_if_type_false_next;
-        // @todo: handle first mode parameter and then filepath parameters.
+
+        bool is = F_false;
+
+        if (fl_string_dynamic_compare_string(fake_make_operation_argument_is, arguments.array[1], fake_make_operation_argument_is_length) == F_equal_to) {
+          is = F_true;
+        }
+
+        f_file_mode mode_rule = 0;
+        mode_t mode_match = 0;
+        uint8_t replace = 0;
+
+        // @fixme: mode_rule needs to be converted to a mode_t.
+        *status = fake_make_get_id_mode(data, data_make->print, arguments.array[1], &mode_rule, &replace);
+        if (F_status_is_error(*status)) return;
+
+        mode_t mode_file = 0;
+
+        for (f_array_length i = 2; i < arguments.used; i++, mode_file = 0) {
+
+          *status = f_file_mode_read(arguments.array[i].string, &mode_file);
+          if (F_status_is_error(*status)) {
+            fake_print_message_file(data, F_status_set_fine(*status), "f_file_mode_read", arguments.array[i].string, "get mode of", F_true, F_true, data_make->print);
+            break;
+          }
+
+          if (is) {
+            if (mode_match == mode_file) {
+              // @todo success
+            }
+            else {
+              // @todo failure
+            }
+          }
+          else {
+            if (mode_match & mode_file) {
+              // @todo success
+            }
+            else {
+              // @todo failure
+            }
+          }
+        } // for
+
         return;
       }
 
@@ -2055,20 +2112,18 @@ extern "C" {
       if (F_status_is_error(*status)) return;
 
       mode_t mode = 0;
-
-      struct stat stat_file;
+      mode_t mode_file = 0;
 
       for (f_array_length i = 1; i < arguments.used; i++) {
         mode = 0;
-        memset(&stat_file, 0, sizeof(struct stat));
 
-        *status = f_file_stat(arguments.array[i].string, F_true, &stat_file);
+        *status = f_file_mode_read(arguments.array[i].string, &mode_file);
         if (F_status_is_error(*status)) {
-          fake_print_message_file(data, F_status_set_fine(*status), "f_file_stat", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
+          fake_print_message_file(data, F_status_set_fine(*status), "f_file_mode_read", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
           break;
         }
 
-        *status = f_file_mode_determine(stat_file.st_mode, mode_rule, replace, f_macro_file_type_is_directory(stat_file.st_mode), &mode);
+        *status = f_file_mode_determine(mode_file, mode_rule, replace, f_macro_file_type_is_directory(mode_file), &mode);
         if (F_status_is_error(*status)) {
           fake_print_message_file(data, F_status_set_fine(*status), "f_file_mode_determine", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
           break;
@@ -2100,21 +2155,19 @@ extern "C" {
       if (F_status_is_error(*status)) return;
 
       mode_t mode = 0;
-
-      struct stat stat_file;
+      mode_t mode_file = 0;
 
       for (f_array_length i = 1; i < arguments.used; i++) {
         // @todo recursive.
         mode = 0;
-        memset(&stat_file, 0, sizeof(struct stat));
 
-        *status = f_file_stat(arguments.array[i].string, F_true, &stat_file);
+        *status = f_file_mode_read(arguments.array[i].string, &mode_file);
         if (F_status_is_error(*status)) {
-          fake_print_message_file(data, F_status_set_fine(*status), "f_file_stat", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
+          fake_print_message_file(data, F_status_set_fine(*status), "f_file_mode_read", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
           break;
         }
 
-        *status = f_file_mode_determine(stat_file.st_mode, mode_rule, replace, f_macro_file_type_is_directory(stat_file.st_mode), &mode);
+        *status = f_file_mode_determine(mode_file, mode_rule, replace, f_macro_file_type_is_directory(mode_file), &mode);
         if (F_status_is_error(*status)) {
           fake_print_message_file(data, F_status_set_fine(*status), "f_file_mode_determine", arguments.array[i].string, "change mode of", F_true, F_true, data_make->print);
           break;
@@ -2695,7 +2748,6 @@ extern "C" {
             *status = F_status_set_error(status_file);
           }
           else if (F_status_is_error(status_file)) {
-            // @todo: print warning file.
             fake_print_message_file(data, *status, "f_file_is", data.file_data_build_fakefile.string, "find", F_true, F_true, data_make->print);
             *status = status_file;
           }
@@ -2850,7 +2902,7 @@ extern "C" {
         return;
       }
 
-      if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false) {
+      if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false || *operation_if == fake_make_operation_if_type_false_always) {
         if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
           printf("%c", f_string_eol[0]);
           fl_color_print(data_make->print.to, data_make->print.context, data.context.reset, "%s: Must not be used inside an ", data_make->print.prefix);
@@ -2864,7 +2916,7 @@ extern "C" {
         return;
       }
 
-      if (*operation_if != fake_make_operation_if_type_else_true_next && *operation_if != fake_make_operation_if_type_else_false_next) {
+      if (*operation_if != fake_make_operation_if_type_else_true_next && *operation_if != fake_make_operation_if_type_else_false_next && *operation_if != fake_make_operation_if_type_else_false_next_always) {
         if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
           printf("%c", f_string_eol[0]);
           fl_color_print_line(data_make->print.to, data_make->print.context, data.context.reset, "%s: Has no preceding if condition.", data_make->print.prefix);
@@ -2987,7 +3039,7 @@ extern "C" {
     }
 
     if (operation == fake_make_operation_type_if) {
-      if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false) {
+      if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false || *operation_if == fake_make_operation_if_type_false_always) {
         if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
           printf("%c", f_string_eol[0]);
           fl_color_print(data_make->print.to, data_make->print.context, data.context.reset, "%s: Must not be used after another '", data_make->print.prefix);
@@ -3065,7 +3117,7 @@ extern "C" {
           3,
           2,
           2,
-          3,
+          4,
           3,
           1,
         };
@@ -3088,7 +3140,7 @@ extern "C" {
           }
 
           *status = F_status_set_error(F_failure);
-          *operation_if = fake_make_operation_if_type_false_next; // @todo: there really needs to be a fail_always to not execute either block on these kinds of errors.
+          *operation_if = fake_make_operation_if_type_false_always_next;
 
           return;
         }
@@ -3102,7 +3154,7 @@ extern "C" {
               }
 
               *status = F_status_set_error(F_failure);
-              *operation_if = fake_make_operation_if_type_false_next; // @todo: there really needs to be a fail_always to not execute either block on these kinds of errors.
+              *operation_if = fake_make_operation_if_type_false_always_next;
             }
 
             return;
@@ -3110,13 +3162,28 @@ extern "C" {
 
           if (*operation_if == fake_make_operation_if_type_if_mode || *operation_if == fake_make_operation_if_type_if_owner || *operation_if == fake_make_operation_if_type_if_group || *operation_if == fake_make_operation_if_type_if_is || *operation_if == fake_make_operation_if_type_if_exists) {
             if (*operation_if == fake_make_operation_if_type_if_mode) {
+
+              if (fl_string_dynamic_compare_string(fake_make_operation_argument_is, arguments.array[1], fake_make_operation_argument_is_length) == F_equal_to_not) {
+                if (fl_string_dynamic_compare_string(fake_make_operation_argument_has, arguments.array[1], fake_make_operation_argument_has_length) == F_equal_to_not) {
+                  if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
+                    printf("%c", f_string_eol[0]);
+                    fl_color_print(data_make->print.to, data_make->print.context, data.context.reset, "%s: Unsupported mode type '", data_make->print.prefix);
+                    fl_color_print(data_make->print.to, data.context.notable, data.context.reset, "%s", arguments.array[1].string);
+                    fl_color_print_line(data_make->print.to, data_make->print.context, data.context.reset, "'.");
+                  }
+
+                  *status = F_status_set_error(F_failure);
+                  return;
+                }
+              }
+
               f_file_mode mode_rule = 0;
               uint8_t replace = 0;
 
-              *status = fake_make_get_id_mode(data, data_make->print, arguments.array[1], &mode_rule, &replace);
+              *status = fake_make_get_id_mode(data, data_make->print, arguments.array[2], &mode_rule, &replace);
               if (F_status_is_error(*status)) return;
 
-              i = 2;
+              i = 3;
             }
 
             if (*operation_if == fake_make_operation_if_type_if_owner) {
@@ -3138,14 +3205,10 @@ extern "C" {
             }
 
             if (*operation_if == fake_make_operation_if_type_if_is) {
-              // block     = 0x1  (0000 0001)
-              // character = 0x2  (0000 0010)
-              // directory = 0x4  (0000 0100)
-              // fifo      = 0x8  (0000 1000)
-              // link      = 0x10 (0001 0000)
-              // regular   = 0x20 (0010 0000)
-              // socket    = 0x40 (0100 0000)
-              // invalid   = 0x80 (1000 0000)
+              // block     = 0x1 (0000 0001) link    = 0x10 (0001 0000)
+              // character = 0x2 (0000 0010) regular = 0x20 (0010 0000)
+              // directory = 0x4 (0000 0100) socket  = 0x40 (0100 0000)
+              // fifo      = 0x8 (0000 1000) invalid = 0x80 (1000 0000)
               uint8_t type_file = 0;
 
               for (i = 1; i < arguments.used; i++) {
@@ -3189,7 +3252,7 @@ extern "C" {
 
               if (type_file & 0x80) {
                 *status = F_status_set_error(F_failure);
-                *operation_if = fake_make_operation_if_type_false_next; // @todo: there really needs to be a fail_always to not execute either block on these kinds of errors.
+                *operation_if = fake_make_operation_if_type_false_always_next;
 
                 return;
               }
@@ -3206,7 +3269,7 @@ extern "C" {
                 if (F_status_is_error(status_file)) {
                   fake_print_message_section_operation_path_outside(data, F_status_set_fine(status_file), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string, data_make->print);
 
-                  *operation_if = fake_make_operation_if_type_false_next; // @todo: there really needs to be a fail_always to not execute either block on these kinds of errors.
+                  *operation_if = fake_make_operation_if_type_false_always_next;
 
                   if (F_status_is_fine(*status)) {
                     if (F_status_set_fine(status_file) == F_false) {
@@ -3228,7 +3291,7 @@ extern "C" {
                   if (F_status_is_error(status_file)) {
                     fake_print_message_file(data, F_status_set_fine(status_file), "f_file_exists", arguments.array[i].string, "find", F_true, F_true, data_make->print);
 
-                    *operation_if = fake_make_operation_if_type_false_next; // @todo: there really needs to be a fail_always to not execute either block on these kinds of errors.
+                    *operation_if = fake_make_operation_if_type_false_always_next;
 
                     if (F_status_is_fine(*status)) {
                       *status = F_status_set_error(status_file);
@@ -3242,17 +3305,80 @@ extern "C" {
           }
 
           if (*operation_if == fake_make_operation_if_type_if_defined) {
-            // @todo: handle first parameter/environment parameter and then define name parameters.
+            if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment, arguments.array[1], fake_make_operation_argument_environment_length) == F_equal_to_not) {
+              if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter, arguments.array[1], fake_make_operation_argument_parameter_length) == F_equal_to_not) {
+                if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
+                  printf("%c", f_string_eol[0]);
+                  fl_color_print(data_make->print.to, data_make->print.context, data.context.reset, "%s: Unsupported define type '", data_make->print.prefix);
+                  fl_color_print(data_make->print.to, data.context.notable, data.context.reset, "%s", arguments.array[1].string);
+                  fl_color_print_line(data_make->print.to, data_make->print.context, data.context.reset, "'.");
+                }
+
+                *status = F_status_set_error(F_failure);
+              }
+            }
+
             return;
           }
 
-          // @todo: for each of these, handle converting all arguments to integers/numbers and then processing conditions in order.
-          //fake_make_operation_if_type_if_equal
-          //fake_make_operation_if_type_if_equal_not (needs to be applied to all, so use separate logic block.)
-          //fake_make_operation_if_type_if_greater
-          //fake_make_operation_if_type_if_greater_equal
-          //fake_make_operation_if_type_if_less
-          //fake_make_operation_if_type_if_less_equal
+          if (*operation_if == fake_make_operation_if_type_if_equal || *operation_if == fake_make_operation_if_type_if_equal_not) {
+            // nothing to validate.
+            return;
+          }
+
+          if (*operation_if == fake_make_operation_if_type_if_greater || *operation_if == fake_make_operation_if_type_if_greater_equal || *operation_if == fake_make_operation_if_type_if_less || *operation_if == fake_make_operation_if_type_if_less_equal) {
+            f_status status_number = F_none;
+            f_string_range range = f_string_range_initialize;
+            f_number_unsigned number = 0;
+            bool is_negative = F_false;
+
+            // @fixme there needs to handle converting numbers with decimals (like 1.01), perhaps operate on them as strings or provide a special processor.
+            for (i = 1; i < arguments.used; i++, status_number = F_none) {
+              if (arguments.array[i].used) {
+                range.start = 0;
+                range.stop = arguments.array[i].used - 1;
+
+                if (arguments.array[i].string[0] == '+') {
+                  range.start = 1;
+                }
+                else if (arguments.array[i].string[0] == '-') {
+                  range.start = 1;
+                  is_negative = F_true;
+                }
+
+                if (range.start > range.stop) {
+                  status_number = F_status_set_error(F_failure);
+                }
+                else {
+                  status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, &number, range);
+                }
+              }
+              else {
+                status_number = F_status_set_error(F_failure);
+              }
+
+              if (F_status_is_error(status_number)) {
+                *status = F_status_set_error(F_failure);
+
+                if (data.verbosity != fake_verbosity_quiet && data_make->print.to) {
+                  printf("%c", f_string_eol[0]);
+
+                  if (number > f_type_number_size_unsigned) {
+                    fl_color_print(data_make->print.to, data_make->print.context, data.context.reset, "%s: The number '", data_make->print.prefix);
+                    fl_color_print(data_make->print.to, data.context.notable, data.context.reset, "%c%s", arguments.array[i].string);
+                    fl_color_print_line(data_make->print.to, data_make->print.context, data.context.reset, "' may only be between the ranges -%llu to %llu.", f_type_number_size_unsigned, f_type_number_size_unsigned);
+                  }
+                  else {
+                    fl_color_print(data_make->print.to, data_make->print.context, data.context.reset, "%s: Invalid or unsupported number provided '", data_make->print.prefix);
+                    fl_color_print(data_make->print.to, data.context.notable, data.context.reset, "%s", arguments.array[i].string);
+                    fl_color_print_line(data_make->print.to, data_make->print.context, data.context.reset, "'.");
+                  }
+                }
+              }
+            } // for
+
+            return;
+          }
         }
       }
 
@@ -3262,7 +3388,7 @@ extern "C" {
       }
 
       *status = F_status_set_error(F_failure);
-      *operation_if = fake_make_operation_if_type_false_next;
+      *operation_if = fake_make_operation_if_type_false_always_next;
 
       return;
     }
index f39e5bab5e54d31d924e17d5e0a92c83823ca672..19f4367da90284a31ff4f1f949e39cf44fcc6f1e 100644 (file)
@@ -59,7 +59,6 @@ extern "C" {
   #define fake_make_setting_return_length      6
 #endif // _di_fake_make_setting_
 
-// @todo "operate" should use a call stack, but do not allow recursive calls (check to see if named operation is already on the call stack).
 #ifndef _di_fake_make_operation_
   #define fake_make_operation_archive  "archive"
   #define fake_make_operation_build    "build"
@@ -152,29 +151,37 @@ extern "C" {
 
   #define fake_make_operation_total 28
 
-  #define fake_make_operation_argument_failure   "failure"
-  #define fake_make_operation_argument_file      "file"
-  #define fake_make_operation_argument_directory "directory"
-  #define fake_make_operation_argument_error     "error"
-  #define fake_make_operation_argument_exit      "exit"
-  #define fake_make_operation_argument_ignore    "ignore"
-  #define fake_make_operation_argument_point     "point"
-  #define fake_make_operation_argument_recursive "recursive"
-  #define fake_make_operation_argument_success   "success"
-  #define fake_make_operation_argument_target    "target"
-  #define fake_make_operation_argument_warn      "warn"
-
-  #define fake_make_operation_argument_failure_length   7
-  #define fake_make_operation_argument_file_length      4
-  #define fake_make_operation_argument_directory_length 9
-  #define fake_make_operation_argument_error_length     5
-  #define fake_make_operation_argument_exit_length      4
-  #define fake_make_operation_argument_ignore_length    6
-  #define fake_make_operation_argument_point_length     5
-  #define fake_make_operation_argument_recursive_length 9
-  #define fake_make_operation_argument_success_length   7
-  #define fake_make_operation_argument_target_length    6
-  #define fake_make_operation_argument_warn_length      4
+  #define fake_make_operation_argument_environment "environment"
+  #define fake_make_operation_argument_failure     "failure"
+  #define fake_make_operation_argument_file        "file"
+  #define fake_make_operation_argument_directory   "directory"
+  #define fake_make_operation_argument_error       "error"
+  #define fake_make_operation_argument_exit        "exit"
+  #define fake_make_operation_argument_has         "has"
+  #define fake_make_operation_argument_ignore      "ignore"
+  #define fake_make_operation_argument_is          "is"
+  #define fake_make_operation_argument_parameter   "parameter"
+  #define fake_make_operation_argument_point       "point"
+  #define fake_make_operation_argument_recursive   "recursive"
+  #define fake_make_operation_argument_success     "success"
+  #define fake_make_operation_argument_target      "target"
+  #define fake_make_operation_argument_warn        "warn"
+
+  #define fake_make_operation_argument_environment_length 11
+  #define fake_make_operation_argument_failure_length     7
+  #define fake_make_operation_argument_file_length        4
+  #define fake_make_operation_argument_directory_length   9
+  #define fake_make_operation_argument_error_length       5
+  #define fake_make_operation_argument_exit_length        4
+  #define fake_make_operation_argument_has_length         3
+  #define fake_make_operation_argument_ignore_length      6
+  #define fake_make_operation_argument_is_length          2
+  #define fake_make_operation_argument_parameter_length   9
+  #define fake_make_operation_argument_point_length       5
+  #define fake_make_operation_argument_recursive_length   9
+  #define fake_make_operation_argument_success_length     7
+  #define fake_make_operation_argument_target_length      6
+  #define fake_make_operation_argument_warn_length        4
 
   #define fake_make_operation_argument_if_defined       "defined"
   #define fake_make_operation_argument_if_equal         "=="
@@ -211,9 +218,12 @@ extern "C" {
   enum {
     fake_make_operation_if_type_else_false = 1,
     fake_make_operation_if_type_else_false_next,
+    fake_make_operation_if_type_else_false_next_always,
     fake_make_operation_if_type_else_true,
     fake_make_operation_if_type_else_true_next,
     fake_make_operation_if_type_false,
+    fake_make_operation_if_type_false_always,
+    fake_make_operation_if_type_false_always_next,
     fake_make_operation_if_type_false_next,
     fake_make_operation_if_type_if_defined,
     fake_make_operation_if_type_if_equal,
index e2c69414d8829f8c7359bcd274be7cf5d1c9d511..7c0ccbff65f28916aa0a46ef0504c4601410953f 100644 (file)
@@ -153,31 +153,37 @@ Fakefile Documentation:
           compare all parameters to be equal.
           requires 2 or more after the "==".
           for example, "if == 'a' 'b' 'c' 'd'" would test: 'a' == 'b' && 'b' == 'c' && 'c' == 'd'.
+          this performs only string-based comparisons.
 
         > "left string" "right string"\:
           compare "left" to "right" for greater than.
           requires 2 or more after the ">".
           for example, "if > 0 1 2 3" would test: 0 > 1 && 1 > 2 && 2 > 3.
+          this performs only number-based comparisons.
 
         < "left string" "right string"\:
           compare "left" to "right" for less than.
           requires 2 or more after the ">".
           for example, "if < 0 1 2 3" would test: 0 < 1 && 1 < 2 && 2 < 3.
+          this performs only number-based comparisons.
 
         >= "left string" "right string"\:
           compare "left" to "right" for greater than or equal to.
           requires 2 or more after the ">=".
           for example, "if >= 0 1 2 3" would test: 0 >= 1 && 1 >= 2 && 2 >= 3.
+          this performs only number-based comparisons.
 
         <= "left string" "right string"\:
           compare "left" to "right" for less than or equal to.
           requires 2 or more after the ">=".
           for example, "if <= 0 1 2 3" would test: 0 <= 1 && 1 <= 2 && 2 <= 3.
+          this performs only number-based comparisons.
 
         <> "left" "right"\:
           compare all parameters to be not equal.
           requires 2 or more after the "==".
           for example, "if <> 'a' 'b' 'c'" would test: 'a' <> 'b' && 'b' <> 'c' && 'a' <> 'c'.
+          this performs only string-based comparisons.
 
         exists "file path"\:
           test if file exists.
index 4465a0d404ebfde608a89da738a3d1465b826287..92591d4cbb6cb55e8327c7397d229698fa38cc15 100644 (file)
@@ -77,7 +77,7 @@ Fakefile Specification:
   - ==: Two or more Content.
   - >: Two or more Content.
   - <: Two or more Content.
-  - <=: Two or more Content.
+  - >=: Two or more Content.
   - <=: Two or more Content.
   - <>: Two or more Content.
   - defined: First Content is either "parameter" or "environment". Second or more Content are valid names, such that for "parameter" it is a valid IKI name and for "environment" it is a valid environment variable name.
@@ -86,4 +86,22 @@ Fakefile Specification:
   - is: First Content is a list of "block", "character", "directory", "fifo", "link", "regular" , or "socket" followed by "for" and then the Remaining Content that are paths to files.
   - mode: First Content is either "is" or "has". Second Content is a valid file mode. Third or more Content are paths to files.
   - owner: First Content is the name of an owner. Second or more Content are paths to files.
-  - succeed: has no other Content.
+  - success: has no other Content.
+
+  The "if" Section Operation conditions and numbers\:
+    The numbers may be represented in any of the forms:
+    1) decimal: all numbers without a base-type prefix are of base-type 10, referred to as decimal.
+    2) binary: all numbers with the prefix "0b" (uppercase or lowercase 'b') are of base-type 2, referred to as binary.
+    3) octal: all numbers with the prefix "0o" (that is zero followed by the letter o, uppercase or lowercase 'o') are of base-type 8, referred to as octal.
+    4) duodecimal: all numbers with the prefix "0d" (uppercase or lowercase 'd') are of base-type 12, referred to as duodecimal.
+    5) hexadecimal: all numbers with the prefix "0x" (uppercase or lowercase 'x') are of base-type 16, referred to as hexadecimal.
+
+    (At this time) The numbers may be of a max value of 2^64, or 18446744073709551615, positive or negative.
+    (At this time) The numbers may only be whole numbers.
+    Note: there are plans to impose no limits on the number size or any decimal values, but this requires significant work is not to be implemented at this time.
+
+    Only the following "if" Section Operation conditions operate using these numbers:
+    - >
+    - <
+    - >=
+    - <=