Some small progress on refactoring the settings loader, focusing on the depth processing function.
}
}
- 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) { ...
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"
* 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().
* 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.
* @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
"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",
"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",
"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_
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,
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,
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_
}
#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) {
#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