From: Kevin Day Date: Wed, 10 May 2023 03:34:28 +0000 (-0500) Subject: Progress: Continue work on refactoring fss_*_read into fss_read. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=aa2d7d7a02a851da4683005a1d970fefb3e5745e;p=fll Progress: Continue work on refactoring fss_*_read into fss_read. Some small progress on refactoring the settings loader, focusing on the depth processing function. --- diff --git a/level_3/fss_read/c/main/common.c b/level_3/fss_read/c/main/common.c index 4108faa..db21a15 100644 --- a/level_3/fss_read/c/main/common.c +++ b/level_3/fss_read/c/main/common.c @@ -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" diff --git a/level_3/fss_read/c/main/common.h b/level_3/fss_read/c/main/common.h index d2188fe..0b8d077 100644 --- a/level_3/fss_read/c/main/common.h +++ b/level_3/fss_read/c/main/common.h @@ -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 diff --git a/level_3/fss_read/c/main/common/print.c b/level_3/fss_read/c/main/common/print.c index 5b0dc16..d611b9a 100644 --- a/level_3/fss_read/c/main/common/print.c +++ b/level_3/fss_read/c/main/common/print.c @@ -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_ diff --git a/level_3/fss_read/c/main/common/print.h b/level_3/fss_read/c/main/common/print.h index 7c63948..0d97880 100644 --- a/level_3/fss_read/c/main/common/print.h +++ b/level_3/fss_read/c/main/common/print.h @@ -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_ diff --git a/level_3/fss_read/c/main/print/error.c b/level_3/fss_read/c/main/print/error.c index 024bf13..0faa7f3 100644 --- a/level_3/fss_read/c/main/print/error.c +++ b/level_3/fss_read/c/main/print/error.c @@ -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) { diff --git a/level_3/fss_read/c/main/print/error.h b/level_3/fss_read/c/main/print/error.h index 1d1e115..2a1d617 100644 --- a/level_3/fss_read/c/main/print/error.h +++ b/level_3/fss_read/c/main/print/error.h @@ -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