From e36c35a44a35eb224bb2bd1bd4d476bf895f0e75 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 30 Oct 2020 20:01:49 -0500 Subject: [PATCH] Update: FSS Extended List should now support multiple depth parameters. Recursively parses the parameters determining what data should or should not be processed. For example, take the following file "example.fss": a { a.0 { a.0.0 { a's final content. } } } b { b.0 { b's first final content. } b.1 { b's second final content. } } TO only display "b's first final content.", the following is done: fss_extended_list_read example.fss -n 'b ' -d 1 -a 0 Which works by at depth 0, looks for the list name 'b ', then at depth 1, looks at position 0. The --at and --name parameters are using the wrong variable in their logic (using 'j' when it should be 'i'). This resulted in an incorrect parsing of the parameters. --- .../c/private-fss_extended_list_read.c | 165 ++++++++++++++------- .../c/private-fss_extended_list_read.h | 15 +- 2 files changed, 116 insertions(+), 64 deletions(-) diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index 9333198..65f2fa0 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -33,22 +33,24 @@ extern "C" { if (i) { for (j = 0; j < data.parameters[fss_extended_list_read_parameter_at].values.used; ++j) { - for (k = 0; k < j; ++k) { + for (k = 0; k < i; ++k) { if (values_order[k] > data.parameters[fss_extended_list_read_parameter_at].values.array[j]) { - for (l = j; l > k; --l) { + for (l = i; l > k; --l) { values_order[l] = values_order[l - 1]; + values_type[l] = values_type[l - 1]; } // for - values_order[i] = data.parameters[fss_extended_list_read_parameter_at].values.array[j]; - values_type[i++] = fss_extended_list_read_parameter_at; + values_order[k] = data.parameters[fss_extended_list_read_parameter_at].values.array[j]; + values_type[k] = fss_extended_list_read_parameter_at; + i++; break; } } // for - if (j == k) { - values_order[i] = data.parameters[fss_extended_list_read_parameter_at].values.array[j]; - values_type[i++] = fss_extended_list_read_parameter_at; + if (k == i) { + values_order[i] = data.parameters[fss_extended_list_read_parameter_at].values.array[j]; + values_type[i++] = fss_extended_list_read_parameter_at; } } // for } @@ -63,22 +65,24 @@ extern "C" { if (i) { for (j = 0; j < data.parameters[fss_extended_list_read_parameter_name].values.used; ++j) { - for (k = 0; k < j; ++k) { + for (k = 0; k < i; ++k) { if (values_order[k] > data.parameters[fss_extended_list_read_parameter_name].values.array[j]) { - for (l = j; l > k; --l) { + for (l = i; l > k; --l) { values_order[l] = values_order[l - 1]; + values_type[l] = values_type[l - 1]; } // for - values_order[i] = data.parameters[fss_extended_list_read_parameter_name].values.array[j]; - values_type[i++] = fss_extended_list_read_parameter_name; + values_order[k] = data.parameters[fss_extended_list_read_parameter_name].values.array[j]; + values_type[k] = fss_extended_list_read_parameter_name; + i++; break; } } // for - if (j == k) { - values_order[i] = data.parameters[fss_extended_list_read_parameter_name].values.array[j]; - values_type[i++] = fss_extended_list_read_parameter_name; + if (k == i) { + values_order[i] = data.parameters[fss_extended_list_read_parameter_name].values.array[j]; + values_type[i++] = fss_extended_list_read_parameter_name; } } // for } @@ -104,8 +108,6 @@ extern "C" { fll_error_print(data.error, F_status_set_fine(status), "fss_extended_list_read_main_preprocess_depth", F_true); return status; } - - depths->used = 0; } // provide default level-0 depth values. @@ -132,8 +134,9 @@ extern "C" { } if (values_type[i] == fss_extended_list_read_parameter_depth) { + if (first_depth) { - if (i) { + if (i && number) { depths->array[++depths->used].index_at = 0; depths->array[depths->used].index_name = 0; depths->array[depths->used].value_at = 0; @@ -173,20 +176,9 @@ extern "C" { return status; } } - - if (!depths->array[depths->used].value_name.used) { - fprintf(data.error.to.stream, "%c", f_string_eol[0]); - fl_color_print(data.error.to.stream, data.context.set.error, "%sThe '", fll_error_print_error); - fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); - fl_color_print(data.error.to.stream, data.context.set.error, "' must not be an empty string.%c", f_string_eol[0]); - - return F_status_set_error(F_parameter); - } } } // for - } - if (!depths->used) { depths->used++; } @@ -319,28 +311,22 @@ extern "C" { const fss_extended_list_read_skip_t parents = fss_extended_list_read_skip_t_initialize; - return fss_extended_list_read_main_process_for_depth(arguments, data, filename, depths.array[0], line, parents, objects_delimits, contents_delimits); + return fss_extended_list_read_main_process_for_depth(arguments, filename, depths, 0, line, parents, data, objects_delimits, contents_delimits); } #endif // _di_fss_extended_list_read_main_process_file_ #ifndef _di_fss_extended_list_read_main_process_for_depth_ - f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line, const fss_extended_list_read_skip_t parents, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { - f_status_t status = F_none; + f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, const f_string_t filename, const fss_extended_list_read_depths_t depths, const f_array_length_t depths_index, const f_array_length_t line, const fss_extended_list_read_skip_t parents, fss_extended_list_read_data_t *data, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { - f_fss_items_t *items = &data->nest.depth[depth_setting.depth]; + f_fss_items_t *items = &data->nest.depth[depths.array[depths_index].depth]; bool skip[items->used]; - f_array_length_t i = 0; - f_array_length_t j = 0; - - const f_string_lengths_t except_none = f_string_lengths_t_initialize; - // setup defaults to be not skipped unless any given parent is skipped. memset(skip, F_false, sizeof(skip) * items->used); if (parents.used) { - for (i = 0; i < items->used; ++i) { + for (f_array_length_t i = 0; i < items->used; ++i) { if (items->array[i].parent >= parents.used || parents.skip[items->array[i].parent]) { skip[i] = F_true; @@ -348,30 +334,38 @@ extern "C" { } // for } - if (depth_setting.index_name || depth_setting.index_at) { + if (depths.array[depths_index].index_name || depths.array[depths_index].index_at) { + const f_string_lengths_t except_none = f_string_lengths_t_initialize; + + f_array_length_t i = 0; + f_array_length_t j = 0; - if (!depth_setting.index_name || (depth_setting.index_at && depth_setting.index_at < depth_setting.index_name)) { + if (!depths.array[depths_index].index_name || (depths.array[depths_index].index_at && depths.array[depths_index].index_at < depths.array[depths_index].index_name)) { // all other non-"at" parameters must be FALSE. - for (i = 0; i < items->used; ++i) { + for (; i < items->used; ++i) { + + if (skip[i]) continue; - if (i != depth_setting.value_at) { + if (j != depths.array[depths_index].value_at) { skip[i] = F_true; } + + ++j; } // for - if (depth_setting.value_at < items->used && !skip[depth_setting.value_at]) { - if (depth_setting.index_name) { + if (depths.array[depths_index].value_at < items->used && !skip[depths.array[depths_index].value_at]) { + if (depths.array[depths_index].index_name) { if (data->parameters[fss_extended_list_read_parameter_trim].result == f_console_result_found) { - if (fl_string_dynamic_partial_compare_except_trim_dynamic(depth_setting.value_name, data->buffer, items->array[depth_setting.value_at].object, except_none, *objects_delimits) != F_equal_to) { - skip[depth_setting.value_at] = F_true; + if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[depths_index].value_name, data->buffer, items->array[depths.array[depths_index].value_at].object, except_none, *objects_delimits) != F_equal_to) { + skip[depths.array[depths_index].value_at] = F_true; } } else { - if (fl_string_dynamic_partial_compare_except_dynamic(depth_setting.value_name, data->buffer, items->array[depth_setting.value_at].object, except_none, *objects_delimits) != F_equal_to) { - skip[depth_setting.value_at] = F_true; + if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[depths_index].value_name, data->buffer, items->array[depths.array[depths_index].value_at].object, except_none, *objects_delimits) != F_equal_to) { + skip[depths.array[depths_index].value_at] = F_true; } } } @@ -385,7 +379,7 @@ extern "C" { if (skip[i]) continue; - if (fl_string_dynamic_partial_compare_except_trim_dynamic(depth_setting.value_name, data->buffer, items->array[i].object, except_none, *objects_delimits) != F_equal_to) { + if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[depths_index].value_name, data->buffer, items->array[i].object, except_none, *objects_delimits) != F_equal_to) { skip[i] = F_true; } } // for @@ -396,26 +390,83 @@ extern "C" { if (skip[i]) continue; - if (fl_string_dynamic_partial_compare_except_dynamic(depth_setting.value_name, data->buffer, items->array[i].object, except_none, *objects_delimits) != F_equal_to) { + if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[depths_index].value_name, data->buffer, items->array[i].object, except_none, *objects_delimits) != F_equal_to) { skip[i] = F_true; } } // for } - if (depth_setting.index_at) { + if (depths.array[depths_index].index_at) { - for (i = 0, j = 0; i < items->used; ++i) { + // all other non-"at" parameters must be FALSE. + for (i = 0, j = 0; i < items->used; ++i) { - if (!skip[i] && j != depth_setting.value_at) { - skip[i] = F_true; - ++j; - } - } // for + if (skip[i]) continue; + + if (j != depths.array[depths_index].value_at) { + skip[i] = F_true; + } + + ++j; + } // for } } } + // if the current depth is not the final depth, then recurse into the next depth. + if (depths_index + 1 < depths.used) { + bool skip_next[data->nest.depth[depths.array[depths_index + 1].depth - 1].used]; + + fss_extended_list_read_skip_t parents_next = fss_extended_list_read_skip_t_initialize; + + if (depths.array[depths_index].depth + 1 == depths.array[depths_index + 1].depth) { + parents_next.skip = skip; + parents_next.used = items->used; + } + else { + const f_array_length_t parents_depth = depths.array[depths_index + 1].depth - 1; + const f_array_length_t depth_next = depths.array[depths_index + 1].depth; + + parents_next.skip = skip_next; + parents_next.used = data->nest.depth[parents_depth].used; + + memset(skip_next, F_true, sizeof(skip_next) * parents_next.used); + + f_fss_items_t *items_next = &data->nest.depth[depth_next]; + f_fss_items_t *items_previous = 0; + f_fss_item_t *item_previous = 0; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + for (; i < items_next->used; ++i) { + + j = depth_next; + + item_previous = &items_next->array[i]; + items_previous = &data->nest.depth[--j]; + + while (j > depths.array[depths_index].depth) { + + item_previous = &items_previous->array[item_previous->parent]; + items_previous = &data->nest.depth[--j]; + } // while + + if (skip[item_previous->parent]) { + skip_next[items_next->array[i].parent] = F_true; + } + else { + skip_next[items_next->array[i].parent] = F_false; + } + } // for + } + + return fss_extended_list_read_main_process_for_depth(arguments, filename, depths, depths_index + 1, line, parents_next, data, objects_delimits, contents_delimits); + } + // process objects. + f_array_length_t i = 0; + f_array_length_t j = 0; if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_found) { if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h index 179f4a9..965606f 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h @@ -237,22 +237,23 @@ extern "C" { /** * Process the items for a given depth. * - * This is intended to be used as a way to process the final specified depth. - * (for --depth 1 --depth 2 --depth 3, this would be called after navigating to depth 3.) + * This will recursively continue down the depth chain until the final depth is reached. * * @param arguments * The console arguments passed to the program. - * @param data - * The program specific data. * @param file_name * The name of the file being processed. - * @param depth_setting - * The depth settings specific to the desired depth. + * @param depths + * The array of all depth related parameter settings. + * @param depths_index + * The array location within depth being worked on. * @param line * The line number parameter value, used for printing a specific line number for content. * @param parents * The skip status of any parent lists. * Set parents.length to 0 for depth 0. + * @param data + * The program specific data. * @param objects_delimits * An array of delimits detected during processing, for top-level objects. * @param contents_delimits @@ -266,7 +267,7 @@ extern "C" { * @see fss_extended_list_read_main_process_file() */ #ifndef _di_fss_extended_list_read_main_process_for_depth_ - extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line, const fss_extended_list_read_skip_t parents, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, const f_string_t filename, const fss_extended_list_read_depths_t depths, const f_array_length_t depths_index, const f_array_length_t line, const fss_extended_list_read_skip_t parents, fss_extended_list_read_data_t *data, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_process_for_depth_ /** -- 1.8.3.1