From 93a8385e696ee646ee0a179c51097632da8459c0 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 15 Dec 2024 22:00:04 -0600 Subject: [PATCH] Progress: Continue fixing iki_read (and eki_read). I am using the 0.6.x iki_read runtime tests files to help identify problems. This will also help identify problems with the 0.6.x iki_read. (Of which I believe that there are some.) This has a huge focus on addressing the `--line` and `--total`. There are still known problems to solve, such as: ``` iki_read tests/runtime/iki/source/test-0000-basic.iki -L -a 1 -n hello iki_read tests/runtime/iki/source/test-0000-basic.iki -L -a 1 -n hello -t ``` The EKI code is being partially updated while I am working on the IKI code. However, big parts of it that are outdated are being left alone until I have IKI working correctly. I will then update EKI accordingly and write the appropriate runtime tests. --- level_3/iki_read/c/eki/print.c | 65 +++--- level_3/iki_read/c/eki/print.h | 2 +- level_3/iki_read/c/eki/process.c | 412 +++++++++++++++++++++++++++------ level_3/iki_read/c/eki/process.h | 29 +++ level_3/iki_read/c/iki/print.c | 20 +- level_3/iki_read/c/iki/print.h | 2 +- level_3/iki_read/c/iki/process.c | 355 ++++++++++++++++++++++------ level_3/iki_read/c/iki/process.h | 44 ++++ level_3/iki_read/c/main/common/print.c | 6 + level_3/iki_read/c/main/common/print.h | 4 + level_3/iki_read/c/main/common/type.c | 1 + level_3/iki_read/c/main/common/type.h | 7 +- level_3/iki_read/c/main/print/data.c | 85 +++++++ level_3/iki_read/c/main/print/data.h | 52 +++++ level_3/iki_read/c/main/process.c | 109 ++++++--- level_3/iki_read/c/main/process.h | 76 ++++-- level_3/iki_read/data/build/testfile | 2 + 17 files changed, 1045 insertions(+), 226 deletions(-) diff --git a/level_3/iki_read/c/eki/print.c b/level_3/iki_read/c/eki/print.c index 743ede7..35bada7 100644 --- a/level_3/iki_read/c/eki/print.c +++ b/level_3/iki_read/c/eki/print.c @@ -17,16 +17,24 @@ extern "C" { if (index >= data->vocabularys.used) return; - f_number_unsigned_t at = main->setting.reassign.used; + // @todo This needs to handle order of operations such that it does not return immediately after say a reassign or a substitution. + // When a substitution or a re-assign is matched, then all things to the right can be ignored. + + f_number_unsigned_t i = 0; + f_number_unsigned_t j = main->setting.reassign.used; f_range_t range = f_range_t_initialize; - if (main->setting.reassign.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { - at = iki_read_identify_substitution(main, data->vocabularys.array[index].array[0], data->content.array[index], &main->setting.reassign); - } + for (; i < data->vocabularys.array[index].used; ++i) { + + if (main->setting.reassign.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { + j = iki_read_identify_substitution(main, data->vocabularys.array[index].array[i], data->content.array[index], &main->setting.reassign); + if (j < main->setting.reassign.used) break; + } + } // for - if (at < main->setting.reassign.used) { + if (j < main->setting.reassign.used) { if (main->setting.flag & iki_read_main_flag_content_d) { - f_print_dynamic(main->setting.reassign.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.reassign.array[j].c, main->program.output.to); } else { range.start = data->variable.array[index].start; @@ -34,7 +42,7 @@ extern "C" { f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to); - f_print_dynamic(main->setting.reassign.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.reassign.array[j].c, main->program.output.to); range.start = data->content.array[index].stop + 1; range.stop = data->variable.array[index].stop; @@ -45,17 +53,21 @@ extern "C" { return; } - at = main->setting.substitute.used; + j = main->setting.substitute.used; - if (main->setting.substitute.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { - at = iki_read_identify_substitution(main, data->vocabularys.array[index].array[0], data->content.array[index], &main->setting.substitute); - } + for (i = 0; i < data->vocabularys.array[index].used; ++i) { + + if (main->setting.substitute.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { + j = iki_read_identify_substitution(main, data->vocabularys.array[index].array[i], data->content.array[index], &main->setting.substitute); + if (j < main->setting.substitute.used) break; + } + } // for - if (at < main->setting.substitute.used) { + if (j < main->setting.substitute.used) { if (main->setting.flag & iki_read_main_flag_content_d) { iki_read_print_data_wrap_prepend(&main->program.output, index); - f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.substitute.array[j].c, main->program.output.to); iki_read_print_data_wrap_append(&main->program.output, index); } @@ -67,7 +79,7 @@ extern "C" { iki_read_print_data_wrap_prepend(&main->program.output, index); - f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.substitute.array[j].c, main->program.output.to); iki_read_print_data_wrap_append(&main->program.output, index); @@ -81,10 +93,10 @@ extern "C" { if (main->setting.flag & iki_read_main_flag_content_d) { iki_read_print_data_wrap_prepend(&main->program.output, index); - for (at = 0; at < main->setting.map_replacess.array[index].used; ++at) { + for (j = 0; j < main->setting.map_replacess.array[index].used; ++j) { - if (main->setting.map_replacess.array[index].array[at] < main->setting.replace.used) { - f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[at]].value, main->program.output.to); + if (main->setting.map_replacess.array[index].array[j] < main->setting.replace.used) { + f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[j]].value, main->program.output.to); } } // for @@ -97,10 +109,10 @@ extern "C" { } } else { - for (at = 0; at < main->setting.map_replacess.array[index].used; ++at) { + for (j = 0; j < main->setting.map_replacess.array[index].used; ++j) { - if (main->setting.map_replacess.array[index].array[at] < main->setting.replace.used) { - f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[at]].key, main->program.output.to); + if (main->setting.map_replacess.array[index].array[j] < main->setting.replace.used) { + f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[j]].key, main->program.output.to); } } // for } @@ -113,14 +125,13 @@ extern "C" { iki_read_print_data_wrap_prepend(&main->program.output, index); - for (at = 0; at < main->setting.map_replacess.array[index].used; ++at) { + for (j = 0; j < main->setting.map_replacess.array[index].used; ++j) { - if (main->setting.map_replacess.array[index].array[at] < main->setting.replace.used) { - f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[at]].value, main->program.output.to); + if (main->setting.map_replacess.array[index].array[j] < main->setting.replace.used) { + f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[j]].value, main->program.output.to); } } // for - iki_read_print_data_wrap_append(&main->program.output, index); range.start = data->content.array[index].stop + 1; @@ -143,11 +154,11 @@ extern "C" { } } else { - for (at = 0; at < data->vocabularys.array[index].used; ) { + for (j = 0; j < data->vocabularys.array[index].used; ) { - f_print_dynamic_partial(main->cache.buffer, data->vocabularys.array[index].array[at], main->program.output.to); + f_print_dynamic_partial(main->cache.buffer, data->vocabularys.array[index].array[j], main->program.output.to); - if (++at < data->vocabularys.array[index].used) { + if (++j < data->vocabularys.array[index].used) { f_print_dynamic_raw(f_string_space_s, print->to); } } // for diff --git a/level_3/iki_read/c/eki/print.h b/level_3/iki_read/c/eki/print.h index cef4cd9..3eeb09b 100644 --- a/level_3/iki_read/c/eki/print.h +++ b/level_3/iki_read/c/eki/print.h @@ -38,8 +38,8 @@ extern "C" { * @see f_print_dynamic_partial() * * @see iki_read_identify_substitution() - * @see iki_read_print_data_wrap_prepend() * @see iki_read_print_data_wrap_append() + * @see iki_read_print_data_wrap_prepend() */ #ifndef _di_iki_read_eki_print_data_ extern void iki_read_eki_print_data(fl_print_t * const print, const f_number_unsigned_t index); diff --git a/level_3/iki_read/c/eki/process.c b/level_3/iki_read/c/eki/process.c index 8791166..006a7c2 100644 --- a/level_3/iki_read/c/eki/process.c +++ b/level_3/iki_read/c/eki/process.c @@ -4,6 +4,211 @@ extern "C" { #endif +#ifndef _di_iki_read_eki_process_buffer_line_ + void iki_read_eki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index) { + + if (!main || F_status_is_error(main->setting.state.status)) return; + + // @todo replace all of this with what is in iki_read_eki_print_data() once that is updated/fixed appropriately. + + if (!main->data) { + main->setting.state.status = F_status_set_error(F_parameter); + } + else { + f_iki_eki_t * const data = (f_iki_eki_t *) main->data; + + if (index >= data->vocabularys.used) { + main->setting.state.status = F_data_not; + + return; + } + + f_number_unsigned_t i = main->setting.reassign.used; + f_number_unsigned_t j = 0; + f_range_t range = f_range_t_initialize; + + // @todo this needs to handle all j where .array[0]. + if (main->setting.reassign.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { + i = iki_read_identify_substitution(main, data->vocabularys.array[index].array[0], data->content.array[index], &main->setting.reassign); + } + + if (i < main->setting.reassign.used) { + if (main->setting.flag & iki_read_main_flag_content_d) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.reassign.array[i].c, &main->cache.expand); + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.reassign.array[i].c, &main->cache.expand); + } + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + else { + i = main->setting.substitute.used; + + if (main->setting.substitute.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { + i = iki_read_identify_substitution(main, data->vocabularys.array[index].array[0], data->content.array[index], &main->setting.substitute); + } + + if (i < main->setting.substitute.used) { + if (main->setting.flag & iki_read_main_flag_content_d) { + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.substitute.array[i].c, &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.substitute.array[i].c, &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + else if (main->setting.replace.used && main->setting.map_replacess.array[index].used) { + if (main->setting.flag & iki_read_main_flag_content_d) { + iki_read_process_wrap_prepend(main, index); + + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < main->setting.map_replacess.array[index].used; ++i) { + + if (main->setting.map_replacess.array[index].array[i] < main->setting.replace.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[i]].value, &main->cache.expand); + } + } // for + + iki_read_process_wrap_append(main, index); + } + else if (main->setting.flag & iki_read_main_flag_object_d) { + if (main->setting.flag & iki_read_main_flag_select_d) { + if (main->setting.select < main->setting.map_replacess.array[index].used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[main->setting.select]].key, &main->cache.expand); + } + } + else { + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < main->setting.map_replacess.array[index].used; ++i) { + + if (main->setting.map_replacess.array[index].array[i] < main->setting.replace.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[i]].key, &main->cache.expand); + } + } // for + } + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + iki_read_process_wrap_prepend(main, index); + + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < main->setting.map_replacess.array[index].used; ++i) { + + if (main->setting.map_replacess.array[index].array[i] < main->setting.replace.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[i]].value, &main->cache.expand); + } + } // for + + + iki_read_process_wrap_append(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + else if (main->setting.flag & iki_read_main_flag_content_d) { + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->content.array[index], &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + } + else if (main->setting.flag & iki_read_main_flag_object_d) { + if (main->setting.flag & iki_read_main_flag_select_d) { + if (main->setting.select < data->vocabularys.array[index].used) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->vocabularys.array[index].array[main->setting.select], &main->cache.expand); + } + } + else { + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->vocabularys.array[index].used; ) { + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->vocabularys.array[index].array[i], &main->cache.expand); + + if (F_status_is_error_not(main->setting.state.status)) { + if (++i < data->vocabularys.array[index].used) { + main->setting.state.status = f_string_dynamic_append_nulless(f_string_space_s, &main->cache.expand); + } + } + } // for + } + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->content.array[index], &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + } + + if (F_status_is_error(main->setting.state.status)) { + iki_read_print_error(&main->program.error, macro_iki_read_f(iki_read_callback_process_buffer_line)); + + return; + } + + main->setting.state.status = main->cache.expand.used ? F_okay : F_data_not; + } +#endif // _di_iki_read_eki_process_buffer_line_ + #ifndef _di_iki_read_eki_process_buffer_ranges_ void iki_read_eki_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const range_buffer) { @@ -14,100 +219,106 @@ extern "C" { iki_read_eki_process_buffer_ranges_prepare(main, range_buffer, data); if (F_status_is_error(main->setting.state.status)) return; - if ((main->setting.flag & iki_read_main_flag_total_d) && !(main->setting.flag & iki_read_main_flag_name_d)) { - fll_print_format( - "%ul%r", - main->program.output.to, - (main->setting.flag & iki_read_main_flag_at_d) - ? main->setting.at < data->variable.used ? 1 : 0 - : data->variable.used, - f_string_eol_s - ); - - main->setting.state.status = F_okay; - - return; - } - // When --at and --line are specified, the only value for --line that will print anything is 0 when using --object. if ((main->setting.flag & iki_read_main_flag_at_d) && (main->setting.flag & iki_read_main_flag_line_d)) { if ((main->setting.flag & iki_read_main_flag_object_d) && main->setting.line) { + if (main->setting.flag & iki_read_main_flag_total_d) { + fll_print_format("0%r", main->program.output.to, f_string_eol_s); + } + main->setting.state.status = F_data_not; return; } } + main->cache.expand.used = 0; + f_number_unsigned_t i = 0; + f_number_unsigned_t j = 0; if (main->setting.flag & iki_read_main_flag_name_d) { - f_number_unsigned_t j = 0; + f_number_unsigned_t k = 0; f_number_unsigned_t matches = 0; - uint8_t unmatched = 0x1; // 0x1 = unmatched, 0x2 = line break. - - if (!(main->setting.flag & iki_read_main_flag_total_d)) { - f_file_stream_lock(main->program.output.to); - } + uint8_t matched = 0x0; // 0x0 = unmatched, 0x1 = matched. for (i = 0; i < data->vocabularys.used; ++i) { - if (iki_read_signal_check(main)) { - if (!(main->setting.flag & iki_read_main_flag_total_d)) { - f_file_stream_unlock(main->program.output.to); - } + if (iki_read_signal_check(main)) return; - return; - } + for (j = 0; j < data->vocabularys.array[i].used; ++j) { - for (j = 0; j < main->setting.names.used; ++j) { + if (iki_read_signal_check(main)) return; - if (iki_read_signal_check(main)) { - if (!(main->setting.flag & iki_read_main_flag_total_d)) { - f_file_stream_unlock(main->program.output.to); - } + for (k = 0; k < main->setting.names.used; ++k) { - return; - } + if (iki_read_signal_check(main)) return; + + if (f_compare_dynamic_partial_string(main->setting.names.array[k].string, main->cache.buffer, main->setting.names.array[k].used, data->vocabularys.array[i].array[j]) == F_equal_to) { + matched |= 0x1; - if (f_compare_dynamic_partial_string(main->setting.names.array[j].string, main->cache.buffer, main->setting.names.array[j].used, data->vocabularys.array[i].array[0]) == F_equal_to) { - unmatched &= ~0x1; + if (main->setting.flag & iki_read_main_flag_at_d) { + if (matches < main->setting.at) { + matches++; - if (main->setting.flag & iki_read_main_flag_at_d) { - if (matches < main->setting.at) { - matches++; + continue; + } - continue; + if (matches++ > main->setting.at) break; } - if (matches++ > main->setting.at) break; - } + if (main->setting.flag & iki_read_main_flag_total_d) { + if (!(main->setting.flag & iki_read_main_flag_at_d)) { + ++matches; + } + + if (main->setting.flag & iki_read_main_flag_line_d) { // @todo handle --at. + iki_read_eki_process_buffer_line(main, i); - if (main->setting.flag & iki_read_main_flag_total_d) { - if (!(main->setting.flag & iki_read_main_flag_at_d)) { - ++matches; + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + } } - } - else { - if (main->callback.print_data) { - main->callback.print_data(&main->program.output, i); + else if (main->setting.flag & iki_read_main_flag_line_d) { + iki_read_eki_process_buffer_line(main, i); + + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } } + else { + f_file_stream_lock(main->program.output.to); - f_print_dynamic_raw(f_string_eol_s, main->program.output.to); + if (main->callback.print_data) { + main->callback.print_data(&main->program.output, i); + } + + f_print_dynamic_raw(f_string_eol_s, main->program.output.to); + + f_file_stream_unlock(main->program.output.to); + } } - } + } // for } // for - - if (unmatched & 0x2) break; } // for - if ((main->setting.flag & iki_read_main_flag_total_d)) { - fll_print_format( - "%ul%r", - main->program.output.to, - (main->setting.flag & iki_read_main_flag_at_d) + if (main->setting.flag & iki_read_main_flag_line_d) { + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_line_total(&main->program.output); + } + else { + iki_read_print_data_line(&main->program.output); + } + } + else if ((main->setting.flag & iki_read_main_flag_total_d)) { + iki_read_print_data_total( + &main->program.output, + (main->setting.flag & iki_read_main_flag_line_d) ? main->setting.at < matches ? 1 : 0 - : matches, - f_string_eol_s + : matches ); main->setting.state.status = F_okay; @@ -118,28 +329,69 @@ extern "C" { f_file_stream_unlock(main->program.output.to); } - main->setting.state.status = (unmatched & 0x1) ? F_data_not : F_okay; + main->setting.state.status = matched ? F_okay : F_data_not; } else { if (data->variable.used) { if (main->setting.flag & iki_read_main_flag_at_d) { if (main->setting.at < data->variable.used) { - f_file_stream_lock(main->program.output.to); + if (main->setting.flag & iki_read_main_flag_line_d) { + iki_read_eki_process_buffer_line(main, main->setting.at); - if (main->callback.print_data) { - main->callback.print_data(&main->program.output, main->setting.at); + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_line_total(&main->program.output); + } + else { + iki_read_print_data_line(&main->program.output); + } } + else { + f_file_stream_lock(main->program.output.to); - f_print_dynamic_raw(f_string_eol_s, main->program.output.to); + if (main->callback.print_data) { + main->callback.print_data(&main->program.output, main->setting.at); + } + + f_print_dynamic_raw(f_string_eol_s, main->program.output.to); + + f_file_stream_unlock(main->program.output.to); - f_file_stream_unlock(main->program.output.to); + main->setting.state.status = F_okay; + } - main->setting.state.status = F_okay; + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = F_okay; + } } else { main->setting.state.status = F_data_not; } } + else if (main->setting.flag & iki_read_main_flag_line_d) { + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->variable.used; ++i) { + + if (iki_read_signal_check(main)) return; + + iki_read_eki_process_buffer_line(main, i); + + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + } // for + + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_line_total(&main->program.output); + } + else { + iki_read_print_data_line(&main->program.output); + } + } else { f_file_stream_lock(main->program.output.to); @@ -147,12 +399,6 @@ extern "C" { if (iki_read_signal_check(main)) return; - // The variable parts, when not using --wrap, each is represented on its own line. - if (main->setting.flag & iki_read_main_flag_line_d) { - if (i < main->setting.line) continue; - if (i > main->setting.line) break; - } - if (main->callback.print_data) { main->callback.print_data(&main->program.output, i); } @@ -166,6 +412,10 @@ extern "C" { } } else { + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_total(&main->program.output, 0); + } + main->setting.state.status = F_data_not; } } @@ -345,7 +595,7 @@ extern "C" { f_range_t range = macro_f_range_t_initialize_2(main->cache.buffer.used); - iki_read_process_line(main, &range); + iki_read_process_line(main, &range); // @fixme is this valid here anymore? if (main->setting.state.status == F_true || main->setting.state.status == F_data_not) { if (main->setting.state.status == F_data_not || range.start > main->cache.buffer.used) { @@ -380,6 +630,7 @@ extern "C" { f_number_unsigned_t index = 0; f_number_unsigned_t j = 0; + f_number_unsigned_t k = 0; range.start = 0; @@ -404,9 +655,16 @@ extern "C" { for (j = 0; j < data->vocabularys.used; ++j) { - main->setting.state.status = f_compare_dynamic_partial(name, main->cache.buffer, range, data->vocabularys.array[j].array[0]); + if (iki_read_signal_check(main)) return; + + for (k = 0; k < data->vocabularys.array[j].used; ++k) { + + if (iki_read_signal_check(main)) return; + + main->setting.state.status = f_compare_dynamic_partial(name, main->cache.buffer, range, data->vocabularys.array[j].array[k]); - if (main->setting.state.status == F_equal_to) ++total; + if (main->setting.state.status == F_equal_to) ++total; + } // for } // for } // for @@ -423,7 +681,7 @@ extern "C" { } } - fll_print_format("%ul%r", main->program.output.to, total, f_string_eol_s); + iki_read_print_data_total(&main->program.output, total); main->setting.state.status = F_okay; } diff --git a/level_3/iki_read/c/eki/process.h b/level_3/iki_read/c/eki/process.h index b306449..492c837 100644 --- a/level_3/iki_read/c/eki/process.h +++ b/level_3/iki_read/c/eki/process.h @@ -17,6 +17,35 @@ extern "C" { #endif /** + * Print the given range at the given index for EKI read, for when printing a single Line in Content and Literal modes. + * + * This expects the caller to have the output locked appropriately. + * + * This detects and prints any applicable substitution matching the vocabulary at the given index. + * If there is no substitution, then this prints the given range at the given index. + * + * @param print + * The output structure to print to. + * + * The setting.map_wrapss is expected to be defined as a valid pointer to an array. + * The setting.map_replacess is expected to be defined as a valid pointer to an array. + * + * This does not alter print.custom.setting.state.status. + * @param index + * The index used to identify the desired range in variable, content, and ranges. + * + * @see f_print_dynamic() + * @see f_print_dynamic_partial() + * + * @see iki_read_identify_substitution() + * @see iki_read_print_data_wrap_append() + * @see iki_read_print_data_wrap_prepend() + */ +#ifndef _di_iki_read_eki_process_buffer_line_ + extern void iki_read_eki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index); +#endif // _di_iki_read_eki_process_buffer_line_ + +/** * Process a given buffer, printing the given range for EKI read. * * @param main diff --git a/level_3/iki_read/c/iki/print.c b/level_3/iki_read/c/iki/print.c index 01916ad..a948f0f 100644 --- a/level_3/iki_read/c/iki/print.c +++ b/level_3/iki_read/c/iki/print.c @@ -17,16 +17,16 @@ extern "C" { if (index >= data->vocabulary.used) return; - f_number_unsigned_t at = main->setting.reassign.used; + f_number_unsigned_t i = main->setting.reassign.used; f_range_t range = f_range_t_initialize; if (main->setting.reassign.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { - at = iki_read_identify_substitution(main, data->vocabulary.array[index], data->content.array[index], &main->setting.reassign); + i = iki_read_identify_substitution(main, data->vocabulary.array[index], data->content.array[index], &main->setting.reassign); } - if (at < main->setting.reassign.used) { + if (i < main->setting.reassign.used) { if (main->setting.flag & iki_read_main_flag_content_d) { - f_print_dynamic(main->setting.reassign.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.reassign.array[i].c, main->program.output.to); } else { range.start = data->variable.array[index].start; @@ -34,7 +34,7 @@ extern "C" { f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to); - f_print_dynamic(main->setting.reassign.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.reassign.array[i].c, main->program.output.to); range.start = data->content.array[index].stop + 1; range.stop = data->variable.array[index].stop; @@ -45,17 +45,17 @@ extern "C" { return; } - at = main->setting.substitute.used; + i = main->setting.substitute.used; if (main->setting.substitute.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { - at = iki_read_identify_substitution(main, data->vocabulary.array[index], data->content.array[index], &main->setting.substitute); + i = iki_read_identify_substitution(main, data->vocabulary.array[index], data->content.array[index], &main->setting.substitute); } - if (at < main->setting.substitute.used) { + if (i < main->setting.substitute.used) { if (main->setting.flag & iki_read_main_flag_content_d) { iki_read_print_data_wrap_prepend(&main->program.output, index); - f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.substitute.array[i].c, main->program.output.to); iki_read_print_data_wrap_append(&main->program.output, index); } @@ -67,7 +67,7 @@ extern "C" { iki_read_print_data_wrap_prepend(&main->program.output, index); - f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to); + f_print_dynamic(main->setting.substitute.array[i].c, main->program.output.to); iki_read_print_data_wrap_append(&main->program.output, index); diff --git a/level_3/iki_read/c/iki/print.h b/level_3/iki_read/c/iki/print.h index 371e2a9..2b32584 100644 --- a/level_3/iki_read/c/iki/print.h +++ b/level_3/iki_read/c/iki/print.h @@ -38,8 +38,8 @@ extern "C" { * @see f_print_dynamic_partial() * * @see iki_read_identify_substitution() - * @see iki_read_print_data_wrap_prepend() * @see iki_read_print_data_wrap_append() + * @see iki_read_print_data_wrap_prepend() */ #ifndef _di_iki_read_iki_print_data_ extern void iki_read_iki_print_data(fl_print_t * const print, const f_number_unsigned_t index); diff --git a/level_3/iki_read/c/iki/process.c b/level_3/iki_read/c/iki/process.c index d0fdecb..6d0b0a7 100644 --- a/level_3/iki_read/c/iki/process.c +++ b/level_3/iki_read/c/iki/process.c @@ -4,6 +4,183 @@ extern "C" { #endif +#ifndef _di_iki_read_iki_process_buffer_line_ + void iki_read_iki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index) { + + if (!main || F_status_is_error(main->setting.state.status)) return; + + const f_number_unsigned_t original = main->cache.expand.used; + + if (!main->data) { + main->setting.state.status = F_status_set_error(F_parameter); + } + else { + f_iki_data_t * const data = (f_iki_data_t *) main->data; + + if (index >= data->vocabulary.used) { + main->setting.state.status = F_data_not; + + return; + } + + f_number_unsigned_t i = main->setting.reassign.used; + f_range_t range = f_range_t_initialize; + + if (main->setting.reassign.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { + i = iki_read_identify_substitution(main, data->vocabulary.array[index], data->content.array[index], &main->setting.reassign); + } + + if (i < main->setting.reassign.used) { + if (main->setting.flag & iki_read_main_flag_content_d) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.reassign.array[i].c, &main->cache.expand); + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.reassign.array[i].c, &main->cache.expand); + } + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + else { + i = main->setting.substitute.used; + + if (main->setting.substitute.used && (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) { + i = iki_read_identify_substitution(main, data->vocabulary.array[index], data->content.array[index], &main->setting.substitute); + } + + if (i < main->setting.substitute.used) { + if (main->setting.flag & iki_read_main_flag_content_d) { + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.substitute.array[i].c, &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.substitute.array[i].c, &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + else if (main->setting.replace.used && main->setting.map_replacess.array[index].used) { + if (main->setting.flag & iki_read_main_flag_content_d) { + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status) && main->setting.map_replacess.array[index].array[0] < main->setting.replace.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[0]].value, &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + } + else if (main->setting.flag & iki_read_main_flag_object_d) { + if (!(main->setting.flag & iki_read_main_flag_select_d) || !main->setting.select) { + if (main->setting.map_replacess.array[index].array[0] < main->setting.replace.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[0]].key, &main->cache.expand); + } + } + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status) && main->setting.map_replacess.array[index].array[0] < main->setting.replace.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.replace.array[main->setting.map_replacess.array[index].array[0]].value, &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + else if (main->setting.flag & iki_read_main_flag_content_d) { + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->content.array[index], &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + } + else if (main->setting.flag & iki_read_main_flag_object_d) { + if (!(main->setting.flag & iki_read_main_flag_select_d) || !main->setting.select) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->vocabulary.array[index], &main->cache.expand); + } + else if ((main->setting.flag & iki_read_main_flag_select_d) && main->setting.select) { + main->setting.state.status = F_data_not; + } + } + else { + range.start = data->variable.array[index].start; + range.stop = data->content.array[index].start - 1; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + + iki_read_process_wrap_prepend(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, data->content.array[index], &main->cache.expand); + } + + iki_read_process_wrap_append(main, index); + + if (F_status_is_error_not(main->setting.state.status)) { + range.start = data->content.array[index].stop + 1; + range.stop = data->variable.array[index].stop; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.expand); + } + } + } + } + + if (F_status_is_error(main->setting.state.status)) { + iki_read_print_error(&main->program.error, macro_iki_read_f(iki_read_callback_process_buffer_line)); + + return; + } + + main->setting.state.status = main->cache.expand.used == original ? F_data_not : F_okay; + } +#endif // _di_iki_read_iki_process_buffer_line_ + #ifndef _di_iki_read_iki_process_buffer_ranges_ void iki_read_iki_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const range_buffer) { @@ -14,63 +191,38 @@ extern "C" { iki_read_iki_process_buffer_ranges_prepare(main, range_buffer, data); if (F_status_is_error(main->setting.state.status)) return; - if ((main->setting.flag & iki_read_main_flag_total_d) && !(main->setting.flag & iki_read_main_flag_name_d)) { - fll_print_format( - "%ul%r", - main->program.output.to, - (main->setting.flag & iki_read_main_flag_at_d) - ? main->setting.at < data->variable.used ? 1 : 0 - : data->variable.used, - f_string_eol_s - ); - - main->setting.state.status = F_okay; - - return; - } - // When --at and --line are specified, the only value for --line that will print anything is 0 when using --object. if ((main->setting.flag & iki_read_main_flag_at_d) && (main->setting.flag & iki_read_main_flag_line_d)) { if ((main->setting.flag & iki_read_main_flag_object_d) && main->setting.line) { + if (main->setting.flag & iki_read_main_flag_total_d) { + fll_print_format("0%r", main->program.output.to, f_string_eol_s); + } + main->setting.state.status = F_data_not; return; } } + main->cache.expand.used = 0; + f_number_unsigned_t i = 0; if (main->setting.flag & iki_read_main_flag_name_d) { f_number_unsigned_t j = 0; f_number_unsigned_t matches = 0; - uint8_t unmatched = 0x1; // 0x1 = unmatched, 0x2 = line break. - - if (!(main->setting.flag & iki_read_main_flag_total_d)) { - f_file_stream_lock(main->program.output.to); - } + uint8_t matched = 0x0; // 0x0 = unmatched, 0x1 = matched. for (i = 0; i < data->vocabulary.used; ++i) { - if (iki_read_signal_check(main)) { - if (!(main->setting.flag & iki_read_main_flag_total_d)) { - f_file_stream_unlock(main->program.output.to); - } - - return; - } + if (iki_read_signal_check(main)) return; for (j = 0; j < main->setting.names.used; ++j) { - if (iki_read_signal_check(main)) { - if (!(main->setting.flag & iki_read_main_flag_total_d)) { - f_file_stream_unlock(main->program.output.to); - } - - return; - } + if (iki_read_signal_check(main)) return; if (f_compare_dynamic_partial_string(main->setting.names.array[j].string, main->cache.buffer, main->setting.names.array[j].used, data->vocabulary.array[i]) == F_equal_to) { - unmatched &= ~0x1; + matched |= 0x1; if (main->setting.flag & iki_read_main_flag_at_d) { if (matches < main->setting.at) { @@ -86,60 +238,131 @@ extern "C" { if (!(main->setting.flag & iki_read_main_flag_at_d)) { ++matches; } + + if (main->setting.flag & iki_read_main_flag_line_d) { // @todo handle --at. + iki_read_iki_process_buffer_line(main, i); + + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + } + } + else if (main->setting.flag & iki_read_main_flag_line_d) { + iki_read_iki_process_buffer_line(main, i); + + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } } else { + f_file_stream_lock(main->program.output.to); + if (main->callback.print_data) { main->callback.print_data(&main->program.output, i); } f_print_dynamic_raw(f_string_eol_s, main->program.output.to); + + f_file_stream_unlock(main->program.output.to); } } } // for - - if (unmatched & 0x2) break; } // for - if (main->setting.flag & iki_read_main_flag_total_d) { - fll_print_format( - "%ul%r", - main->program.output.to, - (main->setting.flag & iki_read_main_flag_at_d) - ? main->setting.at < matches ? 1 : 0 - : matches, - f_string_eol_s - ); + if (main->setting.flag & iki_read_main_flag_line_d) { + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_line_total(&main->program.output); + } + else { + iki_read_print_data_line(&main->program.output); + } + } + else if (main->setting.flag & iki_read_main_flag_total_d) { + if (main->setting.flag & iki_read_main_flag_line_d) { + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->variable.used; ++i) { + + if (iki_read_signal_check(main)) return; - main->setting.state.status = F_okay; + iki_read_iki_process_buffer_line(main, i); + + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + } // for + } + else { + iki_read_print_data_total(&main->program.output, matches); + } + + main->setting.state.status = matched ? F_okay : F_data_not; return; } - else { - f_file_stream_unlock(main->program.output.to); - } - main->setting.state.status = (unmatched & 0x1) ? F_data_not : F_okay; + main->setting.state.status = matched ? F_okay : F_data_not; } else { if (data->variable.used) { if (main->setting.flag & iki_read_main_flag_at_d) { - if ((main->setting.flag & iki_read_main_flag_line_d) && main->setting.line < data->variable.used && !main->setting.at || main->setting.at < data->variable.used) { - f_file_stream_lock(main->program.output.to); + if (main->setting.at < data->variable.used) { + if (main->setting.flag & iki_read_main_flag_line_d) { + iki_read_iki_process_buffer_line(main, main->setting.at); - if (main->callback.print_data) { - main->callback.print_data(&main->program.output, (main->setting.flag & iki_read_main_flag_line_d) ? main->setting.line : main->setting.at); + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_line_total(&main->program.output); + } + else { + iki_read_print_data_line(&main->program.output); + } } + else { + f_file_stream_lock(main->program.output.to); - f_print_dynamic_raw(f_string_eol_s, main->program.output.to); + if (main->callback.print_data) { + main->callback.print_data(&main->program.output, main->setting.at); + } - f_file_stream_unlock(main->program.output.to); + f_print_dynamic_raw(f_string_eol_s, main->program.output.to); - main->setting.state.status = F_okay; + f_file_stream_unlock(main->program.output.to); + } + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = F_okay; + } } else { main->setting.state.status = F_data_not; } } + else if (main->setting.flag & iki_read_main_flag_line_d) { + for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->variable.used; ++i) { + + if (iki_read_signal_check(main)) return; + + iki_read_iki_process_buffer_line(main, i); + + // Ensure that a newline is always at the end. + if (main->setting.state.status == F_okay) { + main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand); + } + } // for + + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_line_total(&main->program.output); + } + else { + iki_read_print_data_line(&main->program.output); + } + } else { f_file_stream_lock(main->program.output.to); @@ -147,12 +370,6 @@ extern "C" { if (iki_read_signal_check(main)) return; - // The variable parts, when not using --wrap, each is represented on its own line. - if (main->setting.flag & iki_read_main_flag_line_d) { - if (i < main->setting.line) continue; - if (i > main->setting.line) break; - } - if (main->callback.print_data) { main->callback.print_data(&main->program.output, i); } @@ -166,6 +383,10 @@ extern "C" { } } else { + if (main->setting.flag & iki_read_main_flag_total_d) { + iki_read_print_data_total(&main->program.output, 0); + } + main->setting.state.status = F_data_not; } } @@ -339,7 +560,7 @@ extern "C" { f_range_t range = macro_f_range_t_initialize_2(main->cache.buffer.used); - iki_read_process_line(main, &range); + iki_read_process_line(main, &range); // @fixme is this valid here anymore? if (main->setting.state.status == F_true || main->setting.state.status == F_data_not) { if (main->setting.state.status == F_data_not || range.start > main->cache.buffer.used) { @@ -398,6 +619,8 @@ extern "C" { for (j = 0; j < data->vocabulary.used; ++j) { + if (iki_read_signal_check(main)) return; + main->setting.state.status = f_compare_dynamic_partial(name, main->cache.buffer, range, data->vocabulary.array[j]); if (main->setting.state.status == F_equal_to) ++total; @@ -417,7 +640,7 @@ extern "C" { } } - fll_print_format("%ul%r", main->program.output.to, total, f_string_eol_s); + iki_read_print_data_total(&main->program.output, total); main->setting.state.status = F_okay; } diff --git a/level_3/iki_read/c/iki/process.h b/level_3/iki_read/c/iki/process.h index 44173a2..d84896b 100644 --- a/level_3/iki_read/c/iki/process.h +++ b/level_3/iki_read/c/iki/process.h @@ -17,8 +17,51 @@ extern "C" { #endif /** + * Process and print the given range at the given index for IKI read, for when printing a single Line in Content and Literal modes. + * + * This expects the caller to have the output locked appropriately.???? + * + * This detects and prints any applicable substitution matching the vocabulary at the given index. + * If there is no substitution, then this prints the given range at the given index. + * + * @param main + * The main program data. + * + * Must not be NULL. + * + * The setting.map_wrapss is expected to be defined as a valid pointer to an array. + * The setting.map_replacess is expected to be defined as a valid pointer to an array. + * + * This alters setting.state.status: + * F_okay on success. + * F_data_not on success, but nothing done. + * + * F_interrupt (with error bit) on (exit) signal received. + * + * Errors (with error bit) from: f_string_dynamic_append_nulless(). + * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). + * + * Errors (with error bit) from: iki_read_process_wrap_append(). + * Errors (with error bit) from: iki_read_process_wrap_prepend(). + * @param index + * The index used to identify the desired range in variable, content, and ranges. + * + * @see f_string_dynamic_append_nulless() + * @see f_string_dynamic_partial_append_nulless() + * + * @see iki_read_identify_substitution() + * @see iki_read_process_wrap_append() + * @see iki_read_process_wrap_prepend() + */ +#ifndef _di_iki_read_iki_process_buffer_line_ + extern void iki_read_iki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index); +#endif // _di_iki_read_iki_process_buffer_line_ + +/** * Process a given buffer, printing the given range for IKI read. * + * This prints error messages. + * * @param main * The main program data. * @@ -28,6 +71,7 @@ extern "C" { * F_okay on success. * F_data_not on success, but nothing done. * + * F_parameter (with error bit) if a parameter is invalid. * F_interrupt (with error bit) on (exit) signal received. * * Errors (with error bit) from: iki_read_iki_process_buffer_ranges_prepare(). diff --git a/level_3/iki_read/c/main/common/print.c b/level_3/iki_read/c/main/common/print.c index 0a47f48..1154680 100644 --- a/level_3/iki_read/c/main/common/print.c +++ b/level_3/iki_read/c/main/common/print.c @@ -18,12 +18,18 @@ extern "C" { "f_memory_array_resize", "f_memory_arrays_resize", "f_string_dynamic_append_nulless", + "f_string_dynamic_partial_append_nulless", "f_string_dynamics_append", + "f_string_dynamics_increase_by", + "f_string_dynamics_resize", "f_thread_create", "fl_iki_eki_read", "fl_iki_read", "fll_program_parameter_process_context_standard", "fll_program_parameter_process_verbosity_standard", + "iki_read_callback_process_buffer_line", + "iki_read_process_wrap_append", + "iki_read_process_wrap_prepend", }; #endif // _di_iki_read_f_a_ diff --git a/level_3/iki_read/c/main/common/print.h b/level_3/iki_read/c/main/common/print.h index deb3f06..1f5f7e7 100644 --- a/level_3/iki_read/c/main/common/print.h +++ b/level_3/iki_read/c/main/common/print.h @@ -51,6 +51,7 @@ extern "C" { iki_read_f_f_memory_array_resize_e, iki_read_f_f_memory_arrays_resize_e, iki_read_f_f_string_dynamic_append_nulless_e, + iki_read_f_f_string_dynamic_partial_append_nulless_e, iki_read_f_f_string_dynamics_append_e, iki_read_f_f_string_dynamics_increase_by_e, iki_read_f_f_string_dynamics_resize_e, @@ -59,6 +60,9 @@ extern "C" { iki_read_f_fl_iki_read_e, iki_read_f_fll_program_parameter_process_context_standard_e, iki_read_f_fll_program_parameter_process_verbosity_standard_e, + iki_read_f_iki_read_callback_process_buffer_line_e, + iki_read_f_iki_read_process_wrap_append_e, + iki_read_f_iki_read_process_wrap_prepend_e, }; // enum #endif // _di_iki_read_f_e_ diff --git a/level_3/iki_read/c/main/common/type.c b/level_3/iki_read/c/main/common/type.c index 8c432d9..a2612bf 100644 --- a/level_3/iki_read/c/main/common/type.c +++ b/level_3/iki_read/c/main/common/type.c @@ -10,6 +10,7 @@ extern "C" { if (!cache) return; f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->buffer.string, &cache->buffer.used, &cache->buffer.size); + f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->expand.string, &cache->expand.used, &cache->expand.size); } #endif // _di_iki_read_cache_delete_ diff --git a/level_3/iki_read/c/main/common/type.h b/level_3/iki_read/c/main/common/type.h index 513557a..16cfa86 100644 --- a/level_3/iki_read/c/main/common/type.h +++ b/level_3/iki_read/c/main/common/type.h @@ -28,15 +28,18 @@ extern "C" { * * Properties: * - buffer: A buffer used for loading the files and other miscellaneous tasks. + * - expand: A buffer used in certain cases for the expanded output that is to be printed. */ #ifndef _di_iki_read_setting_t_ typedef struct { f_string_dynamic_t buffer; + f_string_dynamic_t expand; } iki_read_cache_t; #define iki_read_cache_t_initialize \ { \ f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ } #endif // _di_iki_read_cache_t_ @@ -49,9 +52,9 @@ extern "C" { * - print_data: Print IKI/EKI data at the given index. * - print_help: Print the main help message. * - * - process_buffer_ranges: Process and print the given reange. + * - process_buffer_ranges: Process and print the given range. * - process_buffer_ranges_whole: Process and print the given ranges in whole mode. - * - process_buffer_total: Process and print the total. + * - process_buffer_total: Process and print the total. * * - delete_data: Delete the IKI/EKI data. */ diff --git a/level_3/iki_read/c/main/print/data.c b/level_3/iki_read/c/main/print/data.c index 5733337..08e68b4 100644 --- a/level_3/iki_read/c/main/print/data.c +++ b/level_3/iki_read/c/main/print/data.c @@ -4,6 +4,91 @@ extern "C" { #endif +#ifndef _di_iki_read_print_data_line_ + void iki_read_print_data_line(fl_print_t * const print) { + + if (!print || !print->custom) return; + + iki_read_main_t * const main = (iki_read_main_t *) print->custom; + + if (F_status_is_error(main->setting.state.status) || !main->cache.expand.used) return; + + f_number_unsigned_t i = 0; + f_range_t range = macro_f_range_t_initialize_2(main->cache.expand.used); + f_status_t status; + + for (f_number_unsigned_t first = 0; range.start <= range.stop && range.start < main->cache.expand.used; ) { + + status = f_string_dynamic_seek_line(main->cache.expand, &range); + if (F_status_is_error(status)) return; + + if (status == F_okay) { + if (i == main->setting.line) { + range.stop = range.start; + range.start = first; + + f_print_dynamic_partial(main->cache.expand, range, main->program.output.to); + + break; + } + else { + first = ++range.start; + ++i; + } + } + else { + if (i == main->setting.line) { + range.stop = range.start; + range.start = first; + + f_print_dynamic_partial(main->cache.expand, range, main->program.output.to); + f_print_dynamic(f_string_eol_s, main->program.output.to); + } + + break; + } + } // for + } +#endif // _di_iki_read_print_data_line_ + +#ifndef _di_iki_read_print_data_line_total_ + void iki_read_print_data_line_total(fl_print_t * const print) { + + if (!print || !print->custom) return; + + iki_read_main_t * const main = (iki_read_main_t *) print->custom; + + if (F_status_is_error(main->setting.state.status)) return; + + f_number_unsigned_t total = 0; + + { + f_range_t range = macro_f_range_t_initialize_2(main->cache.expand.used); + + for (; range.start <= range.stop && range.start < main->cache.expand.used; ++total, ++range.start) { + + if (iki_read_signal_check(main)) return; + + main->setting.state.status = f_string_dynamic_seek_line(main->cache.expand, &range); + if (F_status_is_error(main->setting.state.status)) return; + } // for + } + + iki_read_print_data_total(print, main->setting.line < total ? 1 : 0); + + main->setting.state.status = main->setting.line < total ? F_okay : F_data_not; + } +#endif // _di_iki_read_print_data_line_total_ + +#ifndef _di_iki_read_print_data_total_ + void iki_read_print_data_total(fl_print_t * const print, const f_number_unsigned_t total) { + + if (!print) return; + + fll_print_format("%ul%r", print->to, total, f_string_eol_s); + } +#endif // _di_iki_read_print_data_total_ + #ifndef _di_iki_read_print_data_wrap_append_ void iki_read_print_data_wrap_append(fl_print_t * const print, const f_number_unsigned_t index) { diff --git a/level_3/iki_read/c/main/print/data.h b/level_3/iki_read/c/main/print/data.h index 2f02a47..d2fd0b9 100644 --- a/level_3/iki_read/c/main/print/data.h +++ b/level_3/iki_read/c/main/print/data.h @@ -17,6 +17,58 @@ extern "C" { #endif /** + * Print the data from the expand cache at the line. + * + * This requires that the expand cache is properly populated. + * The expand cache may be empty. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_read_print_data_line_ + extern void iki_read_print_data_line(fl_print_t * const print); +#endif // _di_iki_read_print_data_line_ + +/** + * Print the total from the data in the expand cache at the line. + * + * This requires that the expand cache is properly populated. + * The expand cache may be empty. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_read_print_data_line_total_ + extern void iki_read_print_data_line_total(fl_print_t * const print); +#endif // _di_iki_read_print_data_line_total_ + +/** + * Print the number that represents the total. + * + * @param print + * The output structure to print to. + * + * This alters print.custom.setting.state.status: + * F_okay on success and data was processed. + * F_data_not on success, but there was no data to process (0 is printed). + * + * Signal from iki_read_signal_check(). + * + * Error (with error bit set) from f_string_dynamic_seek_line() + * + * @see f_string_dynamic_seek_line() + * + * @see iki_read_signal_check() + */ +#ifndef _di_iki_read_print_data_total_ + extern void iki_read_print_data_total(fl_print_t * const print, const f_number_unsigned_t); +#endif // _di_iki_read_print_data_total_ + +/** * Print the append part of the wrap at the given index, if valid. * * This expects the caller to have the output locked appropriately. diff --git a/level_3/iki_read/c/main/process.c b/level_3/iki_read/c/main/process.c index 72d6106..f793cb0 100644 --- a/level_3/iki_read/c/main/process.c +++ b/level_3/iki_read/c/main/process.c @@ -4,6 +4,50 @@ extern "C" { #endif +#ifndef _di_iki_read_process_buffer_ + void iki_read_process_buffer(iki_read_main_t * const main) { + + if (F_status_is_error(main->setting.state.status)) return; + + f_range_t buffer_range = macro_f_range_t_initialize_2(main->cache.buffer.used); + + if (main->setting.flag & iki_read_main_flag_whole_d) { + iki_read_process_line(main, &buffer_range); + + if (main->setting.state.status == F_data_not || main->setting.state.status == F_true && buffer_range.start > main->cache.buffer.used) { + main->setting.state.status = F_data_not; + + return; + } + + if (main->setting.flag & iki_read_main_flag_total_d) { + if (main->callback.process_buffer_total) { + main->callback.process_buffer_total(main); + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = F_okay; + } + } + + return; + } + + if (main->callback.process_buffer_ranges_whole) { + main->callback.process_buffer_ranges_whole(main, &buffer_range); + } + } + else { + if (main->callback.process_buffer_ranges) { + main->callback.process_buffer_ranges(main, &buffer_range); + } + } + + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = F_okay; + } + } +#endif // _di_iki_read_process_buffer_ + #ifndef _di_iki_read_process_line_ void iki_read_process_line(iki_read_main_t * const main, f_range_t * const range) { @@ -16,6 +60,7 @@ extern "C" { f_number_unsigned_t line = 0; range->start = 0; + if (main->setting.line) { for (; line < main->setting.line && range->start < main->cache.buffer.used; ++range->start) { if (main->cache.buffer.string[range->start] == f_string_eol_s.string[0]) ++line; @@ -37,47 +82,55 @@ extern "C" { } #endif // _di_iki_read_process_line_ -#ifndef _di_iki_read_process_buffer_ - void iki_read_process_buffer(iki_read_main_t * const main) { +#ifndef _di_iki_read_process_wrap_append_ + void iki_read_process_wrap_append(iki_read_main_t * const main, const f_number_unsigned_t index) { - f_range_t buffer_range = macro_f_range_t_initialize_2(main->cache.buffer.used); + if (!main || F_status_is_error(main->setting.state.status)) return; - if (main->setting.flag & iki_read_main_flag_whole_d) { - iki_read_process_line(main, &buffer_range); + if (index >= main->setting.map_wrapss.used) { + main->setting.state.status = F_data_not; - if (main->setting.state.status == F_data_not || main->setting.state.status == F_true && buffer_range.start > main->cache.buffer.used) { - main->setting.state.status = F_data_not; + return; + } - return; + f_number_unsigned_t * const array = main->setting.map_wrapss.array[index].array; + + for (f_number_unsigned_t i = 0; i < main->setting.map_wrapss.array[index].used; ++i) { + + if (array[i] < main->setting.wrap.used && main->setting.wrap.array[array[i]].c.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.wrap.array[array[i]].c, &main->cache.expand); + if (F_status_is_error(main->setting.state.status)) return; } + } // for - if (main->setting.flag & iki_read_main_flag_total_d) { - if (main->callback.process_buffer_total) { - main->callback.process_buffer_total(main); + main->setting.state.status = F_okay; + } +#endif // _di_iki_read_process_wrap_append_ - if (F_status_is_error_not(main->setting.state.status)) { - main->setting.state.status = F_okay; - } - } +#ifndef _di_iki_read_process_wrap_prepend_ + void iki_read_process_wrap_prepend(iki_read_main_t * const main, const f_number_unsigned_t index) { - return; - } + if (!main || F_status_is_error(main->setting.state.status)) return; - if (main->callback.process_buffer_ranges_whole) { - main->callback.process_buffer_ranges_whole(main, &buffer_range); - } + if (index >= main->setting.map_wrapss.used) { + main->setting.state.status = F_data_not; + + return; } - else { - if (main->callback.process_buffer_ranges) { - main->callback.process_buffer_ranges(main, &buffer_range); + + f_number_unsigned_t * const array = main->setting.map_wrapss.array[index].array; + + for (f_number_unsigned_t i = 0; i < main->setting.map_wrapss.array[index].used; ++i) { + + if (array[i] < main->setting.wrap.used && main->setting.wrap.array[array[i]].b.used) { + main->setting.state.status = f_string_dynamic_append_nulless(main->setting.wrap.array[array[i]].b, &main->cache.expand); + if (F_status_is_error(main->setting.state.status)) return; } - } + } // for - if (F_status_is_error_not(main->setting.state.status)) { - main->setting.state.status = F_okay; - } + main->setting.state.status = F_okay; } -#endif // _di_iki_read_process_buffer_ +#endif // _di_iki_read_process_wrap_prepend_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/iki_read/c/main/process.h b/level_3/iki_read/c/main/process.h index ba92685..0306446 100644 --- a/level_3/iki_read/c/main/process.h +++ b/level_3/iki_read/c/main/process.h @@ -17,6 +17,35 @@ extern "C" { #endif /** + * Process a given buffer. + * + * This will print error messages, except for errors in callbacks. + * The callbacks should handle their own error printing. + * + * @param main + * The main program data. + * + * Must not be NULL. + * + * This alters setting.state.status: + * F_okay on success. + * F_data_not on success, but nothing done. + * + * F_interrupt (with error bit) on (exit) signal received. + * + * Errors (with error bit) from: main.callback.process_buffer_ranges(). + * Errors (with error bit) from: main.callback.process_buffer_ranges_whole(). + * Errors (with error bit) from: main.callback.process_buffer_total(). + * + * @see main.callback.process_buffer_ranges() + * @see main.callback.process_buffer_ranges_whole() + * @see main.callback.process_buffer_total() + */ +#ifndef _di_iki_read_process_buffer_ + extern void iki_read_process_buffer(iki_read_main_t * const main); +#endif // _di_iki_read_process_buffer_ + +/** * Determine the range based on the --line parameter. * * If the --line parameter is not specified in the console arguments, then range is untouched. @@ -39,10 +68,31 @@ extern "C" { #endif // _di_iki_read_process_line_ /** - * Process a given buffer. + * Process the append part of the wrap at the given index adding it to the expand cache, if valid. * - * This will print error messages, except for errors in callbacks. - * The callbacks should handle their own error printing. + * @param main + * The main program data. + * + * Must not be NULL. + * + * This alters setting.state.status: + * F_okay on success. + * F_data_not on success, but nothing added to the expand cache. + * + * Errors (with error bit) from: f_string_dynamic_append_nulless() + * + * F_failure (with error bit) for any other failure. + * @param index + * The index within the setting->map_wrapss array to print. + * + * @see f_string_dynamic_append_nulless() + */ +#ifndef _di_iki_read_process_wrap_append_ + extern void iki_read_process_wrap_append(iki_read_main_t * const main, const f_number_unsigned_t index); +#endif // _di_iki_read_process_wrap_append_ + +/** + * Print the prepend part of the wrap at the given index adding it to the expand cache, if valid. * * @param main * The main program data. @@ -51,21 +101,19 @@ extern "C" { * * This alters setting.state.status: * F_okay on success. - * F_data_not on success, but nothing done. + * F_data_not on success, but nothing added to the expand cache. * - * F_interrupt (with error bit) on (exit) signal received. + * Errors (with error bit) from: f_string_dynamic_append_nulless() * - * Errors (with error bit) from: main.callback.process_buffer_ranges(). - * Errors (with error bit) from: main.callback.process_buffer_ranges_whole(). - * Errors (with error bit) from: main.callback.process_buffer_total(). + * F_failure (with error bit) for any other failure. + * @param index + * The index within the setting->map_wrapss array to print. * - * @see main.callback.process_buffer_ranges() - * @see main.callback.process_buffer_ranges_whole() - * @see main.callback.process_buffer_total() + * @see f_string_dynamic_append_nulless() */ -#ifndef _di_iki_read_process_buffer_ - extern void iki_read_process_buffer(iki_read_main_t * const main); -#endif // _di_iki_read_process_buffer_ +#ifndef _di_iki_read_process_wrap_prepend_ + extern void iki_read_process_wrap_prepend(iki_read_main_t * const main, const f_number_unsigned_t index); +#endif // _di_iki_read_process_wrap_prepend_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/iki_read/data/build/testfile b/level_3/iki_read/data/build/testfile index 69f5961..d067395 100644 --- a/level_3/iki_read/data/build/testfile +++ b/level_3/iki_read/data/build/testfile @@ -18,6 +18,8 @@ settings: main: build settings + build settings.eki_read + build settings.iki_read operate build_path operate ld_library_path -- 1.8.3.1