]> Kevux Git Server - fll/commitdiff
Progress: Continue work on refactoring fss_*_read into fss_read.
authorKevin Day <kevin@kevux.org>
Wed, 10 May 2023 03:34:28 +0000 (22:34 -0500)
committerKevin Day <kevin@kevux.org>
Wed, 10 May 2023 03:34:28 +0000 (22:34 -0500)
Some small progress on refactoring the settings loader, focusing on the depth processing function.

level_3/fss_read/c/main/common.c
level_3/fss_read/c/main/common.h
level_3/fss_read/c/main/common/print.c
level_3/fss_read/c/main/common/print.h
level_3/fss_read/c/main/print/error.c
level_3/fss_read/c/main/print/error.h

index 4108faa72e615c3c6bde60c05418e29d75e0990d..db21a159920117255f21f765e906ddb5549e7d5e 100644 (file)
@@ -388,17 +388,9 @@ extern "C" {
       }
     }
 
-    main->setting.state.status = fss_read_depth_process(main, &data);
-
-    if (F_status_is_error(main->setting.state.status) {
-      if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
-        fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
-      }
-
-      fss_read_print_error(&main->program.error, macro_fss_read_f(fss_read_depth_process));
-
-      return;
-    }
+    // The standards providing the setting load callback must call this rather than calling this here because they need to perfom tests after this is called based on the results.
+    main->setting.state.status = fss_read_setting_load_depth(arguments, main);
+    if (F_status_is_error(main->setting.state.status)) return;
 
     // @todo: Some standards do not support nesting, so any depth greater than 0 can be predicted without processing the file, this check needs to happen in the program specific settings processing function.
     // if (data.depths.array[0].depth) { ...
@@ -418,13 +410,188 @@ extern "C" {
     if (main->program.parameters.array[fss_read_parameter_trim_e].result & f_console_result_found_e) {
       main->setting.flag |= fss_read_main_flag_trim_e;
     }
+  }
+#endif // _di_fss_read_setting_load_
+
+#ifndef _di_fss_read_setting_load_depth_
+  void fss_read_setting_load_depth(const f_console_arguments_t arguments, fss_read_main_t * const main) {
+
+    if (!main) return;
+
+    f_array_length_t i = 1;
 
-    // @fixme this is from fss_write, but doing some sort of file check, such as no pipe and no files may be a good idea here. Replace this with such logic if deemed desirable.
-    if (!(main->setting.flag & (fll_program_data_pipe_input_e | fss_read_main_flag_content_e | fss_read_parameter_object_e))) {
-      main->setting.state.status = F_data_not;
+    if (main->parameters.array[fss_read_parameter_depth_e].result & f_console_result_value_e) {
+      i = main->parameters.array[fss_read_parameter_depth_e].values.used;
     }
+
+    if (i > data->depths.size) {
+      main->setting.state.status = fss_read_depths_resize(i, &data->depths);
+
+      if (F_status_is_error(main->setting.state.status)) {
+        if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+          fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+        }
+
+        fss_read_print_error(&main->program.error, macro_fss_read_f(fss_read_depths_resize));
+
+        return;
+      }
+    }
+
+    data->depths.used = depth_size;
+
+    f_array_length_t position_depth = 0;
+    f_array_length_t position_at = 0;
+    f_array_length_t position_name = 0;
+
+    for (i = 0; i < data->depths.used; ++i) {
+
+      if (!((++main->signal_check) % fss_read_signal_check_d)) {
+        if (fll_program_standard_signal_received(&main->program)) {
+          fll_program_print_signal_received(main->warning, main->signal_received);
+
+          main->setting.state.status = F_status_set_error(F_interrupt);
+
+          return;
+        }
+
+        main->signal_check = 0;
+      }
+
+      data->depths.array[i].depth = 0;
+      data->depths.array[i].index_at = 0;
+      data->depths.array[i].index_name = 0;
+      data->depths.array[i].value_at = 0;
+
+      // This dynamic string is actually a static string, so clear it between loops.
+      macro_f_string_dynamic_t_clear(data->depths.array[i].value_name);
+
+      if (!main->parameters.array[fss_read_parameter_depth_e].values.used) {
+        position_depth = 0;
+      }
+      else {
+        position_depth = main->parameters.array[fss_read_parameter_depth_e].values.array[i];
+
+        main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, data->argv[position_depth], &data->depths.array[i].depth);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+            fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+          }
+
+          fll_error_parameter_integer_print(&main->program.error, F_status_set_fine(main->setting.state.status), macro_fss_read_f(fl_conversion_dynamic_to_unsigned_detect), F_true, fss_read_long_depth_s, data->argv[position_depth]);
+
+          return;
+        }
+      }
+
+      if (main->parameters.array[fss_read_parameter_at_e].result & f_console_result_value_e) {
+        for (; position_at < main->parameters.array[fss_read_parameter_at_e].values.used; ++position_at) {
+
+          if (main->parameters.array[fss_read_parameter_at_e].values.array[position_at] < position_depth) {
+            continue;
+          }
+
+          if (i + 1 < data->depths.used && main->parameters.array[fss_read_parameter_at_e].values.array[position_at] > main->parameters.array[fss_read_parameter_depth_e].values.array[i + 1]) {
+            break;
+          }
+
+          data->depths.array[i].index_at = main->parameters.array[fss_read_parameter_at_e].values.array[position_at];
+
+          main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, data->argv[data->depths.array[i].index_at], &data->depths.array[i].value_at);
+
+          if (F_status_is_error(main->setting.state.status)) {
+            if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+              fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+            }
+
+            fll_error_parameter_integer_print(&main->program.error, F_status_set_fine(main->setting.state.status), macro_fss_read_f(fl_conversion_dynamic_to_unsigned_detect), F_true, fss_read_long_at_s, data->argv[data->depths.array[i].index_at]);
+
+            return;
+          }
+        } // for
+      }
+
+      if (main->parameters.array[fss_read_parameter_name_e].result & f_console_result_value_e) {
+        for (; position_name < main->parameters.array[fss_read_parameter_name_e].values.used; ++position_name) {
+
+          if (main->parameters.array[fss_read_parameter_name_e].values.array[position_name] < position_depth) {
+            continue;
+          }
+
+          if (i + 1 < data->depths.used && main->parameters.array[fss_read_parameter_name_e].values.array[position_name] > main->parameters.array[fss_read_parameter_depth_e].values.array[i + 1]) {
+            break;
+          }
+
+          data->depths.array[i].index_name = main->parameters.array[fss_read_parameter_name_e].values.array[position_name];
+
+          if (main->parameters.array[fss_read_parameter_trim_e].result & f_console_result_found_e) {
+            main->setting.state.status = f_rip_dynamic(data->argv[data->depths.array[i].index_name], &data->depths.array[i].value_name);
+          }
+          else {
+            main->setting.state.status = f_string_dynamic_append(data->argv[data->depths.array[i].index_name], &data->depths.array[i].value_name);
+          }
+
+          if (F_status_is_error(main->setting.state.status)) {
+            if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+              fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+            }
+
+            fss_read_print_error(&main->program.error, (main->parameters.array[fss_read_parameter_trim_e].result & f_console_result_found_e) ? macro_fss_read_f(f_rip_dynamic) : macro_fss_read_f(f_string_dynamic_append));
+
+            return;
+          }
+        } // for
+      }
+    } // for
+
+    f_array_length_t j = 0;
+
+    for (i = 0; i < data->depths.used; ++i) {
+
+      for (j = i + 1; j < data->depths.used; ++j) {
+
+        if (!((++main->signal_check) % fss_read_signal_check_d)) {
+          if (fll_program_standard_signal_received(&main->program)) {
+            fll_program_print_signal_received(main->warning, main->signal_received);
+
+            main->setting.state.status = F_status_set_error(F_interrupt);
+
+            return;
+          }
+
+          main->signal_check = 0;
+        }
+
+        if (data->depths.array[i].depth == data->depths.array[j].depth) {
+          main->setting.state.status = F_status_set_error(F_parameter);
+
+          if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+            fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+          }
+
+          fss_read_print_error_parameter_value_once_only_number(&main->program.error, f_console_symbol_long_normal_s, fss_read_long_depth_s, data->depths.array[i].depth);
+
+          return;
+        }
+
+        if (data->depths.array[i].depth > data->depths.array[j].depth) {
+          main->setting.state.status = F_status_set_error(F_parameter);
+
+          if ((main->setting.flag & fss_read_main_flag_print_first_e) && main->program.message.verbosity > f_console_verbosity_error_e) {
+            fll_print_dynamic_raw(f_string_eol_s, main->program.message.to);
+          }
+
+          fss_read_print_error_parameter_value_before_value_number(&main->program.error, f_console_symbol_long_normal_s, fss_read_long_depth_s, data->depths.array[i].depth, data->depths.array[j].depth);
+
+          return;
+        }
+      } // for
+    } // for
+
+    main->setting.state.status = F_none;
   }
-#endif // _di_fss_read_setting_load_
+#endif // _di_fss_read_setting_load_depth_
 
 #ifdef __cplusplus
 } // extern "C"
index d2188fe6a1c0c1176b0b233d628a57eaa90c1fe5..0b8d077dafaaa4f30305d54a1cc2fbdde5815269 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
  *     F_none on success.
  *     F_data_not on success but nothing was provided to operate with.
  *
+ *     F_interrupt (with error bit) on interrupt signal received.
  *     F_parameter (with error bit) on parameter error.
  *
  *     Errors (with error bit) from: f_console_parameter_process().
@@ -41,6 +42,8 @@ extern "C" {
  *     Errors (with error bit) from: f_string_dynamics_resize().
  *     Errors (with error bit) from: fll_program_parameter_process_context().
  *     Errors (with error bit) from: fll_program_parameter_process_verbosity().
+ *
+ *     Errors (with error bit) from: fss_read_setting_load_depth(). @todo fss_read_depths_resize() is to be relocated to "callback".
  * @param callback
  *   (optional) Designate a function to call after performing the initial processing, but before printing help.
  *   If the function returns F_done, then this function immediately returns, resetting status to F_none.
@@ -51,11 +54,51 @@ extern "C" {
  * @see f_string_dynamics_resize()
  * @see fll_program_parameter_process_context()
  * @see fll_program_parameter_process_verbosity()
+ *
+ * @see fss_read_setting_load_depth() @todo fss_read_depths_resize() is to be relocated to "callback".
  */
 #ifndef _di_fss_read_setting_load_
   extern void fss_read_setting_load(const f_console_arguments_t arguments, fss_read_main_t * const main, void (*callback)(const f_console_arguments_t arguments, fss_read_main_t * const main));
 #endif // _di_fss_read_setting_load_
 
+/**
+ * Process the depth and depth related parameters.
+ *
+ * Will handle depth-sensitive parameter conflicts, such as --name being used with --at (which is not allowed).
+ *
+ * This should only be called by standards that support this behavior.
+ *
+ * This is intended to be called within the scope of a setting load callback in fss_read_setting_load().
+ *
+ * @param arguments
+ *   The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ *   The main program data.
+ *
+ *   This alters main.setting.state.status:
+ *     F_none on success.
+ *
+ *     F_interrupt (with error bit) on interrupt signal received.
+ *     F_parameter (with error bit) on parameter error.
+ *
+ *     Errors (with error bit) from: f_rip_dynamic().
+ *     Errors (with error bit) from: f_string_dynamic_append().
+ *     Errors (with error bit) from: fl_conversion_dynamic_partial_to_unsigned_detect().
+ *
+ *     Errors (with error bit) from: fss_read_depths_resize().
+ *
+ * @see f_rip_dynamic()
+ * @see f_string_dynamic_append()
+ * @see fl_conversion_dynamic_partial_to_unsigned_detect()
+ * @see fll_program_print_signal_received()
+ *
+ * @see fss_read_depths_resize()
+ * @see fss_read_setting_load()
+ */
+#ifndef _di_fss_read_setting_load_depth_
+  extern void fss_read_setting_load_depth(const f_console_arguments_t arguments, fss_read_main_t * const main);
+#endif // _di_fss_read_setting_load_depth_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 5b0dc166a1b78371f6122d99355b5b001b0c9f01..d611b9a2ec03f94d2098aa20e60cb6bd09125756 100644 (file)
@@ -10,6 +10,7 @@ extern "C" {
     "f_file_read_block",
     "f_file_stream_open",
     "f_fss_is_space",
+    "f_rip_dynamic",
     "f_string_dynamic_append",
     "f_string_dynamic_append_nulless",
     "f_string_dynamic_increase_by",
@@ -25,6 +26,7 @@ extern "C" {
     "f_string_read_block_increase",
     "f_thread_create",
     "fl_conversion_dynamic_partial_to_unsigned_detect",
+    "fl_conversion_dynamic_to_unsigned_detect",
     "fl_fss_basic_content_read",
     "fl_fss_basic_list_content_read",
     "fl_fss_basic_list_object_read",
@@ -39,7 +41,8 @@ extern "C" {
     "fll_program_parameter_process_context",
     "fll_program_parameter_process_verbosity",
     "fll_fss_payload_read",
-    "fss_read_depth_process",
+    "fss_read_depths_resize",
+    "fss_read_setting_load_depth",
   };
 #endif // _di_fss_read_f_a_
 
index 7c63948101843afd48241851595255418224f979..0d9788051c4ed5a7ea31a941a013055db1fe26db 100644 (file)
@@ -43,6 +43,7 @@ extern "C" {
     fss_read_f_f_file_read_block_e,
     fss_read_f_f_file_stream_open_e,
     fss_read_f_f_fss_is_space_e,
+    fss_read_f_f_rip_dynamic_e,
     fss_read_f_f_string_dynamic_append_e,
     fss_read_f_f_string_dynamic_append_nulless_e,
     fss_read_f_f_string_dynamic_increase_by_e,
@@ -58,6 +59,7 @@ extern "C" {
     fss_read_f_f_string_read_block_increase_e,
     fss_read_f_f_thread_create_e,
     fss_read_f_fl_conversion_dynamic_partial_to_unsigned_detect_e,
+    fss_read_f_fl_conversion_dynamic_to_unsigned_detect_e,
     fss_read_f_fl_fss_basic_content_read_e,
     fss_read_f_fl_fss_basic_list_content_read_e,
     fss_read_f_fl_fss_basic_list_object_read_e,
@@ -72,7 +74,8 @@ extern "C" {
     fss_read_f_fll_program_parameter_process_context_e,
     fss_read_f_fll_program_parameter_process_verbosity_e,
     fss_read_f_fll_fss_payload_read_e,
-    fss_rerad_f_fss_read_depth_process_e,
+    fss_read_f_fss_read_depths_resize_e,
+    fss_read_f_fss_read_setting_load_depth_e,
   }; // enum
 #endif // _di_fss_read_f_e_
 
index 024bf133fae4de843cbfe640f7bae6617d7be50d..0faa7f328cd375615c0a21a80089483f6a207113 100644 (file)
@@ -68,6 +68,48 @@ extern "C" {
   }
 #endif // _di_fss_read_print_error_parameter_requires_message_
 
+#ifndef _di_fss_read_print_error_parameter_value_before_value_number_
+  f_status_t fss_read_print_error_parameter_value_before_value_number(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t name, const f_array_length_t value, const f_array_length_t before) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity == f_console_verbosity_quiet_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QThe parameter '%]", print->to, print->context, print->prefix, print->context);
+    fl_print_format("%[%r%r%]", print->to, print->notable, symbol, name, print->notable);
+    fl_print_format("%[' may not have the value '%]", print->to, print->context, print->context);
+    fl_print_format("%[%ul%]", print->to, print->notable, value, print->notable);
+    fl_print_format("%[' before the value '%]", print->to, print->context, print->context);
+    fl_print_format("%[%ul%]", print->to, print->notable, before, print->notable);
+    fl_print_format("%['.%]%r", print->to, print->context, print->context, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_none;
+  }
+#endif // _di_fss_read_print_error_parameter_value_before_value_number_
+
+#ifndef _di_fss_read_print_error_parameter_value_once_only_number_
+  f_status_t fss_read_print_error_parameter_value_once_only_number(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t name, const f_array_length_t value) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity == f_console_verbosity_quiet_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QThe value '%]", print->to, print->context, print->prefix, print->context);
+    fl_print_format("%[%ul%]", print->to, print->notable, value, print->notable);
+    fl_print_format("%[' may only be specified once for the parameter '%]", print->to, print->context, print->context);
+    fl_print_format("%[%r%r%]", print->to, print->notable, symbol, name, print->notable);
+    fl_print_format("%['.%]%r", print->to, print->context, print->context, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_none;
+  }
+#endif // _di_fss_read_print_error_parameter_value_once_only_number_
+
 #ifndef _di_fss_read_print_error_one_content_only_
   f_status_t fss_read_print_error_one_content_only(fl_print_t * const print) {
 
index 1d1e115545657976d2763121849736f74bf4e72d..2a1d6179bb375e66408ba2f49a09b5b5fca79f70 100644 (file)
@@ -105,6 +105,46 @@ extern "C" {
 #endif // _di_fss_read_print_error_parameter_requires_message_
 
 /**
+ * Print an error message about the parameter not allowing a value before another value.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param symbol
+ *   The symbol string prepended to the first parameter.
+ *   This is usually f_console_symbol_long_normal_s.
+ * @param name
+ *   The parameter name.
+ * @param value
+ *   The parameter value that cannot be specified before the "before" function parameter.
+ * @param before
+ *   The parameter value that is before the "value" function parameter.
+ */
+#ifndef _di_fss_read_print_error_parameter_value_before_value_number_
+  extern f_status_t fss_read_print_error_parameter_value_before_value_number(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t name, const f_array_length_t value, const f_array_length_t before);
+#endif // _di_fss_read_print_error_parameter_value_before_value_number_
+
+/**
+ * Print an error message about the parameter only allowing the given value to be specified one time.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param symbol
+ *   The symbol string prepended to the first parameter.
+ *   This is usually f_console_symbol_long_normal_s.
+ * @param name
+ *   The parameter name.
+ * @param value
+ *   The parameter value that is already specified.
+ */
+#ifndef _di_fss_read_print_error_parameter_value_once_only_number_
+  extern f_status_t fss_read_print_error_parameter_value_once_only_number(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t name, const f_array_length_t value);
+#endif // _di_fss_read_print_error_parameter_value_once_only_number_
+
+/**
  * Print an message about a multiple Content being unsupported for a particular standard.
  *
  * @param print