This refactors iki_read in regards to the wraps and replaces.
I have not done any testing of the wraps and the replaces yet.
I also need to consider exactly how I want the multiple parameters to be handled.
I need to think about how I want to handle printing Objects (`--object`) with EKI when there is more than one Object for a single Variable.
extern "C" {
#endif
+#ifndef _di_iki_read_eki_delete_data_
+ void iki_read_eki_delete_data(iki_read_main_t * const main) {
+
+ if (!main || !main->data) return;
+
+ f_iki_eki_delete(main->data);
+ }
+#endif // _di_iki_read_eki_delete_data_
+
#ifdef __cplusplus
} // extern "C"
#endif
#ifndef _iki_read_eki_eki_read_h
#define _iki_read_eki_eki_read_h
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Libc includes.
#include <dirent.h>
#include <stdio.h>
#include <program/iki_read/main/signal.h>
#include <program/iki_read/main/thread.h>
#include <program/iki_read/eki/common.h>
+#include <program/iki_read/eki/identify.h>
#include <program/iki_read/eki/print.h>
#include <program/iki_read/eki/process.h>
#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * This does not alter main.setting.state.status.
+ *
+ * @see f_iki_data_delete()
+ * @see f_memory_array_resize()
+ * @see f_memory_arrays_resize()
+ */
+#ifndef _di_iki_read_eki_delete_data_
+ extern void iki_read_eki_delete_data(iki_read_main_t * const main);
+#endif // _di_iki_read_eki_delete_data_
+
+#ifdef __cplusplus
} // extern "C"
#endif
--- /dev/null
+#include "eki_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_read_eki_identify_alteration_
+ void iki_read_eki_identify_alteration(iki_read_main_t * const main) {
+
+ if (!main || !main->data || !(main->setting.replace.used || main->setting.wrap.used)) return;
+
+ if (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d)) {
+ f_iki_eki_t * const data = (f_iki_eki_t *) main->data;
+
+ f_number_unsigned_t i = 0;
+ f_number_unsigned_t j = 0;
+ f_number_unsigned_t k = 0;
+
+ for (i = 0; i < data->vocabularys.used; ++i) {
+
+ for (j = 0; j < data->vocabularys.array[i].used; ++j) {
+
+ if (iki_read_signal_check(main)) return;
+
+ if (main->setting.replace.used) {
+ main->setting.map_replacess.array[i].used = 0;
+
+ k = main->setting.replace.used - 1;
+
+ do {
+ if (f_compare_dynamic_partial_string(main->setting.replace.array[k].key.string, main->cache.buffer, main->setting.replace.array[k].key.used, data->vocabularys.array[i].array[j]) == F_equal_to) {
+ main->setting.state.status = f_memory_array_increase(main->setting.state.step_small, sizeof(f_number_unsigned_t), (void **) &main->setting.map_replacess.array[i].array, &main->setting.map_replacess.array[i].used, &main->setting.map_replacess.array[i].size);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_memory_array_increase));
+
+ return;
+ }
+
+ main->setting.map_replacess.array[i].array[main->setting.map_replacess.array[i].used++] = k;
+ }
+
+ } while (k--);
+ }
+
+ if (main->setting.wrap.used) {
+ main->setting.map_wrapss.array[i].used = 0;
+
+ k = main->setting.wrap.used - 1;
+
+ do {
+ if (f_compare_dynamic_partial_string(main->setting.wrap.array[k].a.string, main->cache.buffer, main->setting.wrap.array[k].a.used, data->vocabularys.array[i].array[j]) == F_equal_to) {
+ main->setting.state.status = f_memory_array_increase(main->setting.state.step_small, sizeof(f_number_unsigned_t), (void **) &main->setting.map_wrapss.array[i].array, &main->setting.map_wrapss.array[i].used, &main->setting.map_wrapss.array[i].size);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_memory_array_increase));
+
+ return;
+ }
+
+ main->setting.map_wrapss.array[i].array[main->setting.map_wrapss.array[i].used++] = k;
+ }
+
+ } while (k--);
+ }
+ } // for
+ } // for
+ }
+ }
+#endif // _di_iki_read_eki_identify_alteration_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: IKI Read
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the identify functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _iki_read_eki_identify_h
+#define _iki_read_eki_identify_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Process the arguments, associating replacements and wraps with a given vocabulary.
+ *
+ * This does not handle substitutions because substitutions must match both name and value (Object and Content).
+ * This function does not know the value (Content).
+ *
+ * @param main
+ * The program and settings data.
+ * @param replaces
+ * A map to the last matching replacment or a value of setting->data.vocabulary.used if there is no matching replacement.
+ * Must be an array of length setting->data.vocabulary.used.
+ * @param wraps
+ * A map to the last matching wrap or a value of setting->data.vocabulary.used if there is no matching wrap.
+ * Must be an array of length setting->data.vocabulary.used.
+ *
+ * @return
+ * The matching setting->data.vocabulary index or if no match then setting->data.vocabulary.used.
+ */
+#ifndef _di_iki_read_eki_identify_alteration_
+ extern void iki_read_eki_identify_alteration(iki_read_main_t * const main);
+#endif // _di_iki_read_eki_identify_alteration_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _iki_read_eki_identify_h
+
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
iki_read_main_t data = iki_read_main_t_initialize;
+ f_iki_eki_t data_eki = f_iki_eki_t_initialize;
+
+ data.data = (void *) &data_eki;
data.program.debug.flag |= iki_read_print_flag_debug_d | iki_read_print_flag_out_d;
data.program.error.flag |= iki_read_print_flag_error_d | iki_read_print_flag_out_d;
data.setting.state.custom = (void *) &data;
data.setting.state.handle = &fll_program_standard_signal_handle;
+ data.callback.identify_alteration = &iki_read_eki_identify_alteration;
+ data.callback.print_data = &iki_read_eki_print_data;
data.callback.print_help = &iki_read_eki_print_message_help;
- //data.callback.process_objects_content = &iki_read_eki_process_objects_content;
+ data.callback.process_buffer_ranges = &iki_read_eki_process_buffer_ranges;
+ data.callback.process_buffer_ranges_whole = &iki_read_eki_process_buffer_ranges_whole;
+ data.callback.process_buffer_total = &iki_read_eki_process_buffer_total;
+ data.callback.delete_data = &iki_read_eki_delete_data;
f_console_parameter_t parameters[] = iki_read_console_parameter_t_initialize;
data.program.parameters.array = parameters;
extern "C" {
#endif
+#ifndef _di_iki_read_eki_print_data_
+ void iki_read_eki_print_data(fl_print_t * const print, const f_number_unsigned_t index) {
+
+ if (!print || !print->custom) return;
+
+ iki_read_main_t * const main = (iki_read_main_t *) print->custom;
+
+ if (!main->data) return;
+
+ f_iki_eki_t * const data = (f_iki_eki_t *) main->data;
+
+ if (index >= data->vocabularys.used) return;
+
+ f_number_unsigned_t at = 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);
+ }
+
+ if (at < 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);
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ 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);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+
+ return;
+ }
+
+ at = 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);
+ }
+
+ if (at < 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);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+ }
+ 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_print_data_wrap_prepend(&main->program.output, index);
+
+ for (at = 0; at < main->setting.map_replacess.array[index].used; ++at) {
+
+ 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);
+ }
+ } // for
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+ }
+ else if (main->setting.flag & iki_read_main_flag_object_d) {
+ for (at = 0; at < main->setting.map_replacess.array[index].used; ++at) {
+
+ 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);
+ }
+ } // for
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ for (at = 0; at < main->setting.map_replacess.array[index].used; ++at) {
+
+ 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);
+ }
+ } // for
+
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+ }
+ else if (main->setting.flag & iki_read_main_flag_content_d) {
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ f_print_dynamic_partial(main->cache.buffer, data->content.array[index], main->program.output.to);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+ }
+ else if (main->setting.flag & iki_read_main_flag_object_d) {
+ f_print_dynamic_partial(main->cache.buffer, data->vocabularys.array[index].array[0], main->program.output.to);
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ f_print_dynamic_partial(main->cache.buffer, data->content.array[index], main->program.output.to);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+ }
+#endif // _di_iki_read_eki_print_data_
+
#ifndef _di_iki_read_eki_print_message_help_
void iki_read_eki_print_message_help(fl_print_t * const print) {
#endif
/**
+ * Print the given range at the given index for EKI read.
+ *
+ * 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_prepend()
+ * @see iki_read_print_data_wrap_append()
+ */
+#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);
+#endif // _di_iki_read_eki_print_data_
+
+/**
* Print help for EKI read.
*
* @param print
extern "C" {
#endif
+#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) {
+
+ if (!main || !main->data || !range_buffer) return;
+
+ f_iki_eki_t * const data = (f_iki_eki_t *) main->data;
+
+ iki_read_eki_process_buffer_ranges_prepare(main, range_buffer, data);
+ if (F_status_is_error(main->setting.state.status)) return;
+
+ 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 = F_true;
+
+ f_file_stream_lock(main->program.output.to);
+
+ for (i = 0; i < data->vocabularys.used; ++i) {
+
+ for (j = 0; j < main->setting.names.used; ++j) {
+
+ 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->vocabularys.array[i].array[0]) == F_equal_to) {
+ unmatched = F_false;
+
+ if (main->setting.flag & iki_read_main_flag_at_d) {
+ if (matches < main->setting.at) {
+ matches++;
+
+ continue;
+ }
+
+ if (matches++ > main->setting.at) break;
+ }
+
+ 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);
+ }
+ } // for
+ } // for
+
+ f_file_stream_unlock(main->program.output.to);
+
+ if (unmatched) {
+ main->setting.state.status = F_data_not;
+ }
+ else {
+ main->setting.state.status = F_okay;
+ }
+ }
+ 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->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);
+
+ main->setting.state.status = F_okay;
+ }
+ else {
+ main->setting.state.status = F_data_not;
+ }
+ }
+ else {
+ f_file_stream_lock(main->program.output.to);
+
+ for (i = 0; i < data->variable.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ 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);
+ } // for
+
+ f_file_stream_unlock(main->program.output.to);
+
+ main->setting.state.status = F_okay;
+ }
+ }
+ else {
+ main->setting.state.status = F_data_not;
+ }
+ }
+ }
+#endif // _di_iki_read_eki_process_buffer_ranges_
+
+#ifndef _di_iki_read_eki_process_buffer_ranges_prepare_
+ void iki_read_eki_process_buffer_ranges_prepare(iki_read_main_t * const main, f_range_t * const range_buffer, f_iki_eki_t * const data) {
+
+ if (!main || !range_buffer || !data) return;
+
+ fl_iki_eki_read(&main->cache.buffer, range_buffer, data, &main->setting.state);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_read));
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+
+ for (; i < main->setting.map_replacess.used; ++i) {
+ main->setting.map_replacess.array[i].used = 0;
+ } // for
+
+ for (i = 0; i < main->setting.map_wrapss.used; ++i) {
+ main->setting.map_wrapss.array[i].used = 0;
+ } // for
+
+ main->setting.map_replacess.used = 0;
+ main->setting.map_wrapss.used = 0;
+
+ main->setting.state.status = f_memory_arrays_resize(data->vocabularys.used, sizeof(f_number_unsigneds_t), (void **) &main->setting.map_replacess.array, &main->setting.map_replacess.used, &main->setting.map_replacess.size, &f_number_unsignedss_delete_callback);
+
+ if (F_status_is_error_not(main->setting.state.status)) {
+ main->setting.state.status = f_memory_arrays_resize(data->vocabularys.used, sizeof(f_number_unsigneds_t), (void **) &main->setting.map_wrapss.array, &main->setting.map_wrapss.used, &main->setting.map_wrapss.size, &f_number_unsignedss_delete_callback);
+ }
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_memory_arrays_resize));
+
+ return;
+ }
+
+ for (i = 0; i < data->delimits.used; ++i) {
+ main->cache.buffer.string[data->delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
+ } // for
+
+ if (main->callback.identify_alteration) {
+ main->callback.identify_alteration(main);
+ }
+ }
+#endif // _di_iki_read_eki_process_buffer_ranges_prepare_
+
+#ifndef _di_iki_read_eki_process_buffer_ranges_whole_
+ void iki_read_eki_process_buffer_ranges_whole(iki_read_main_t * const main, f_range_t * const range_buffer) {
+
+ if (!main || !main->data || !range_buffer) return;
+
+ f_iki_eki_t * const data = (f_iki_eki_t *) main->data;
+
+ const f_range_t range_original = *range_buffer;
+
+ iki_read_eki_process_buffer_ranges_prepare(main, range_buffer, data);
+ if (F_status_is_error(main->setting.state.status)) return;
+
+ if (!data->variable.used) {
+ fll_print_dynamic_partial(main->cache.buffer, range_original, main->program.output.to);
+
+ main->setting.state.status = F_okay;
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+
+ {
+ f_number_unsigned_t j = 0;
+ f_number_unsigned_t k = 0;
+ f_number_unsigned_t stop = data->variable.used;
+
+ i = range_original.start;
+ *range_buffer = range_original;
+
+ f_file_stream_lock(main->program.output.to);
+
+ while (i <= range_buffer->stop && j < stop) {
+
+ if (iki_read_signal_check(main)) return;
+
+ if (i < data->variable.array[j].start) {
+ range_buffer->start = i;
+ range_buffer->stop = data->variable.array[j].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, *range_buffer, main->program.output.to);
+
+ range_buffer->start = data->variable.array[j].stop + 1;
+ range_buffer->stop = range_original.stop;
+
+ i = data->variable.array[j].start;
+ }
+
+ if (main->setting.names.used) {
+ for (k = 0; k < main->setting.names.used; ++k) {
+ if (f_compare_dynamic_partial_string(main->setting.names.array[k].string, main->cache.buffer, main->setting.names.array[k].used, data->vocabularys.array[j].array[0]) == F_equal_to) break;
+ } // for
+
+ if (k < main->setting.names.used) {
+ if (main->callback.print_data) {
+ main->callback.print_data(&main->program.output, j);
+ }
+ }
+ }
+ else {
+ if (main->callback.print_data) {
+ main->callback.print_data(&main->program.output, j);
+ }
+ }
+
+ i = data->variable.array[j].stop + 1;
+ ++j;
+ } // while
+
+ if (i <= range_original.stop) {
+ range_buffer->start = i;
+ f_print_dynamic_partial(main->cache.buffer, *range_buffer, main->program.output.to);
+ }
+
+ f_file_stream_unlock(main->program.output.to);
+ }
+
+ main->setting.state.status = F_okay;
+ }
+#endif // _di_iki_read_eki_process_buffer_ranges_whole_
+
+#ifndef _di_iki_read_eki_process_buffer_total_
+ void iki_read_eki_process_buffer_total(iki_read_main_t * const main) {
+
+ if (!main || !main->data) return;
+
+ f_iki_eki_t * const data = (f_iki_eki_t *) main->data;
+
+ f_range_t range = macro_f_range_t_initialize_2(main->cache.buffer.used);
+
+ iki_read_process_line(main, &range);
+
+ if (main->setting.state.status == F_true) {
+ if (range.start > main->cache.buffer.used) {
+ fll_print_format("%r%r", main->program.output.to, f_string_ascii_0_s, f_string_eol_s);
+
+ main->setting.state.status = F_okay;
+
+ return;
+ }
+ }
+ else if (main->setting.state.status == F_data_not) {
+ fll_print_format("%r%r", main->program.output.to, f_string_ascii_0_s, f_string_eol_s);
+
+ main->setting.state.status = F_okay;
+
+ return;
+ }
+
+ fl_iki_eki_read(&main->cache.buffer, &range, data, &main->setting.state);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_eki_read));
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+ f_number_unsigned_t total = 0;
+
+ for (; i < data->delimits.used; ++i) {
+ main->cache.buffer.string[data->delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
+ } // for
+
+ if (main->program.parameters.array[iki_read_parameter_name_e].result & f_console_result_value_e) {
+ f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+ f_number_unsigned_t index = 0;
+ f_number_unsigned_t j = 0;
+
+ range.start = 0;
+
+ for (i = 0; i < main->program.parameters.array[iki_read_parameter_name_e].values.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ index = main->program.parameters.array[iki_read_parameter_name_e].values.array[i];
+ name.used = 0;
+
+ main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &name);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_string_dynamic_append_nulless));
+
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &name.string, &name.used, &name.size);
+
+ return;
+ }
+
+ range.stop = name.used - 1;
+
+ 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 (main->setting.state.status == F_equal_to) ++total;
+ } // for
+ } // for
+
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &name.string, &name.used, &name.size);
+ }
+ else {
+ total = data->variable.used;
+ }
+
+ // If the "at" position is within the actual total, then the total at the given position is 1, otherwise is 0.
+ if (main->program.parameters.array[iki_read_parameter_at_e].result & f_console_result_value_e) {
+ if (main->setting.at < total) {
+ total = 1;
+ }
+ else {
+ total = 0;
+ }
+ }
+
+ fll_print_format("%ul%r", main->program.output.to, total, f_string_eol_s);
+
+ main->setting.state.status = F_okay;
+ }
+#endif // _di_iki_read_eki_process_buffer_total_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
+/**
+ * Process a given buffer, printing the given range for EKI read.
+ *
+ * @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: iki_read_eki_process_buffer_ranges_prepare().
+ * @param range_buffer
+ * The range within the buffer to process.
+ *
+ * Must not be NULL.
+ *
+ * @see iki_read_eki_process_buffer_ranges_prepare()
+ */
+#ifndef _di_iki_read_eki_process_buffer_ranges_
+ extern void iki_read_eki_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const range_buffer);
+#endif // _di_iki_read_eki_process_buffer_ranges_
+
+/**
+ * Helper function for preparing the processing of the buffer ranges.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * This alters setting.state.status:
+ * Not directly changed on success.
+ *
+ * Errors (with error bit) from: f_memory_arrays_resize().
+ * Errors (with error bit) from: fl_iki_eki_read().
+ * @param range_buffer
+ * The range within the buffer to process.
+ *
+ * Must not be NULL.
+ * @param data
+ * The IKI data structure.
+ *
+ * Must not be NULL.
+ *
+ * @see f_memory_arrays_resize()
+ * @see fl_iki_eki_read()
+ */
+#ifndef _di_iki_read_eki_process_buffer_ranges_prepare_
+ extern void iki_read_eki_process_buffer_ranges_prepare(iki_read_main_t * const main, f_range_t * const range_buffer, f_iki_eki_t * const data);
+#endif // _di_iki_read_eki_process_buffer_ranges_prepare_
+
+/**
+ * Process a given buffer, printing the given buffer in whole mode based on the given ranges for EKI read.
+ *
+ * The entire variable is replaced with the value from the associated ranges.
+ *
+ * @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: f_memory_arrays_resize().
+ * @param range_buffer
+ * The range within the buffer to process.
+ *
+ * Must not be NULL.
+ *
+ * @see f_memory_arrays_resize()
+ */
+#ifndef _di_iki_read_eki_process_buffer_ranges_whole_
+ extern void iki_read_eki_process_buffer_ranges_whole(iki_read_main_t * const main, f_range_t * const range_buffer);
+#endif // _di_iki_read_eki_process_buffer_ranges_whole_
+
+/**
+ * Process a given buffer, printing the total for EKI read.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * @return
+ * F_okay on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_iki_read_eki_process_buffer_total_
+ extern void iki_read_eki_process_buffer_total(iki_read_main_t * const main);
+#endif // _di_iki_read_eki_process_buffer_total_
+
#ifdef __cplusplus
} // extern "C"
#endif
--- /dev/null
+#include "iki_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_read_iki_identify_alteration_
+ void iki_read_iki_identify_alteration(iki_read_main_t * const main) {
+
+ if (!main || !main->data || !(main->setting.replace.used || main->setting.wrap.used)) return;
+ if (!(main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d))) return;
+
+ f_iki_data_t * const data = (f_iki_data_t *) main->data;
+
+ f_number_unsigned_t i = 0;
+ f_number_unsigned_t j = 0;
+
+ for (i = 0; i < data->vocabulary.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ if (main->setting.replace.used) {
+ main->setting.map_replacess.array[i].used = 0;
+
+ j = main->setting.replace.used - 1;
+
+ do {
+ if (f_compare_dynamic_partial_string(main->setting.replace.array[j].key.string, main->cache.buffer, main->setting.replace.array[j].key.used, data->vocabulary.array[i]) == F_equal_to) {
+ main->setting.map_replacess.array[i].used = 0;
+
+ main->setting.state.status = f_memory_array_increase_by(1, sizeof(f_number_unsigned_t), (void **) &main->setting.map_replacess.array[i].array, &main->setting.map_replacess.array[i].used, &main->setting.map_replacess.array[i].size);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_memory_array_increase_by));
+
+ return;
+ }
+
+ main->setting.map_replacess.array[i].array[main->setting.map_replacess.array[i].used++] = j;
+
+ break;
+ }
+
+ } while (j--);
+ }
+
+ if (main->setting.wrap.used) {
+ main->setting.map_wrapss.array[i].used = 0;
+
+ j = main->setting.wrap.used - 1;
+
+ do {
+ if (f_compare_dynamic_partial_string(main->setting.wrap.array[j].a.string, main->cache.buffer, main->setting.wrap.array[j].a.used, data->vocabulary.array[i]) == F_equal_to) {
+ main->setting.map_wrapss.array[i].used = 0;
+
+ main->setting.state.status = f_memory_array_increase_by(1, sizeof(f_number_unsigned_t), (void **) &main->setting.map_wrapss.array[i].array, &main->setting.map_wrapss.array[i].used, &main->setting.map_wrapss.array[i].size);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_memory_array_increase_by));
+
+ return;
+ }
+
+ main->setting.map_wrapss.array[i].array[main->setting.map_wrapss.array[i].used++] = j;
+
+ break;
+ }
+
+ } while (j--);
+ }
+ } // for
+ }
+#endif // _di_iki_read_iki_identify_alteration_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: IKI Read
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the identify functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _iki_read_iki_identify_h
+#define _iki_read_iki_identify_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Process the arguments, associating replacements and wraps with a given vocabulary.
+ *
+ * This does not handle substitutions because substitutions must match both name and value (Object and Content).
+ * This function does not know the value (Content).
+ *
+ * @param main
+ * The program and settings data.
+ * @param replaces
+ * A map to the last matching replacment or a value of setting->data.vocabulary.used if there is no matching replacement.
+ * Must be an array of length setting->data.vocabulary.used.
+ * @param wraps
+ * A map to the last matching wrap or a value of setting->data.vocabulary.used if there is no matching wrap.
+ * Must be an array of length setting->data.vocabulary.used.
+ *
+ * @return
+ * The matching setting->data.vocabulary index or if no match then setting->data.vocabulary.used.
+ */
+#ifndef _di_iki_read_iki_identify_alteration_
+ extern void iki_read_iki_identify_alteration(iki_read_main_t * const main);
+#endif // _di_iki_read_iki_identify_alteration_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _iki_read_iki_identify_h
extern "C" {
#endif
+#ifndef _di_iki_read_iki_delete_data_
+ void iki_read_iki_delete_data(iki_read_main_t * const main) {
+
+ if (!main || !main->data) return;
+
+ f_iki_data_delete(main->data);
+ }
+#endif // _di_iki_read_iki_delete_data_
+
#ifdef __cplusplus
} // extern "C"
#endif
#ifndef _iki_read_iki_iki_read_h
#define _iki_read_iki_iki_read_h
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Libc includes.
#include <dirent.h>
#include <stdio.h>
#include <program/iki_read/main/signal.h>
#include <program/iki_read/main/thread.h>
#include <program/iki_read/iki/common.h>
+#include <program/iki_read/iki/identify.h>
#include <program/iki_read/iki/print.h>
#include <program/iki_read/iki/process.h>
#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * This does not alter main.setting.state.status.
+ *
+ * @see f_iki_data_delete()
+ * @see f_memory_array_resize()
+ * @see f_memory_arrays_resize()
+ */
+#ifndef _di_iki_read_iki_delete_data_
+ extern void iki_read_iki_delete_data(iki_read_main_t * const main);
+#endif // _di_iki_read_iki_delete_data_
+
+#ifdef __cplusplus
} // extern "C"
#endif
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
iki_read_main_t data = iki_read_main_t_initialize;
+ f_iki_data_t data_iki = f_iki_data_t_initialize;
+
+ data.data = (void *) &data_iki;
data.program.debug.flag |= iki_read_print_flag_debug_d | iki_read_print_flag_out_d;
data.program.error.flag |= iki_read_print_flag_error_d | iki_read_print_flag_out_d;
data.setting.state.custom = (void *) &data;
data.setting.state.handle = &fll_program_standard_signal_handle;
+ data.callback.identify_alteration = &iki_read_iki_identify_alteration;
+ data.callback.print_data = &iki_read_iki_print_data;
data.callback.print_help = &iki_read_iki_print_message_help;
- //data.callback.process_objects_content = &iki_read_iki_process_objects_content;
+ data.callback.process_buffer_ranges = &iki_read_iki_process_buffer_ranges;
+ data.callback.process_buffer_ranges_whole = &iki_read_iki_process_buffer_ranges_whole;
+ data.callback.process_buffer_total = &iki_read_iki_process_buffer_total;
+ data.callback.delete_data = &iki_read_iki_delete_data;
f_console_parameter_t parameters[] = iki_read_console_parameter_t_initialize;
data.program.parameters.array = parameters;
extern "C" {
#endif
+#ifndef _di_iki_read_iki_print_data_
+ void iki_read_iki_print_data(fl_print_t * const print, const f_number_unsigned_t index) {
+
+ if (!print || !print->custom) return;
+
+ iki_read_main_t * const main = (iki_read_main_t *) print->custom;
+
+ if (!main->data) return;
+
+ f_iki_data_t * const data = (f_iki_data_t *) main->data;
+
+ if (index >= data->vocabulary.used) return;
+
+ f_number_unsigned_t at = 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);
+ }
+
+ if (at < 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);
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ 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);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+
+ return;
+ }
+
+ at = 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);
+ }
+
+ if (at < 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);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+ }
+ 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_print_data_wrap_prepend(&main->program.output, index);
+
+ if (main->setting.map_replacess.array[index].array[0] < main->setting.replace.used) {
+ f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[0]].value, main->program.output.to);
+ }
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+ }
+ else if (main->setting.flag & iki_read_main_flag_object_d) {
+ if (main->setting.map_replacess.array[index].array[0] < main->setting.replace.used) {
+ f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[0]].key, main->program.output.to);
+ }
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ if (main->setting.map_replacess.array[index].array[0] < main->setting.replace.used) {
+ f_print_dynamic(main->setting.replace.array[main->setting.map_replacess.array[index].array[0]].value, main->program.output.to);
+ }
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+ }
+ else if (main->setting.flag & iki_read_main_flag_content_d) {
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ f_print_dynamic_partial(main->cache.buffer, data->content.array[index], main->program.output.to);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+ }
+ else if (main->setting.flag & iki_read_main_flag_object_d) {
+ f_print_dynamic_partial(main->cache.buffer, data->vocabulary.array[index], main->program.output.to);
+ }
+ else {
+ range.start = data->variable.array[index].start;
+ range.stop = data->content.array[index].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+
+ iki_read_print_data_wrap_prepend(&main->program.output, index);
+
+ f_print_dynamic_partial(main->cache.buffer, data->content.array[index], main->program.output.to);
+
+ iki_read_print_data_wrap_append(&main->program.output, index);
+
+ range.start = data->content.array[index].stop + 1;
+ range.stop = data->variable.array[index].stop;
+
+ f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ }
+ }
+#endif // _di_iki_read_iki_print_data_
+
#ifndef _di_iki_read_iki_print_message_help_
void iki_read_iki_print_message_help(fl_print_t * const print) {
#endif
/**
+ * Print the given range at the given index for IKI read.
+ *
+ * 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_prepend()
+ * @see iki_read_print_data_wrap_append()
+ */
+#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);
+#endif // _di_iki_read_iki_print_data_
+
+/**
* Print help for IKI read.
*
* @param print
extern "C" {
#endif
+#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) {
+
+ if (!main || !main->data || !range_buffer) return;
+
+ f_iki_data_t * const data = (f_iki_data_t *) main->data;
+
+ iki_read_iki_process_buffer_ranges_prepare(main, range_buffer, data);
+ if (F_status_is_error(main->setting.state.status)) return;
+
+ 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 = F_true;
+
+ f_file_stream_lock(main->program.output.to);
+
+ for (i = 0; i < data->vocabulary.used; ++i) {
+
+ for (j = 0; j < main->setting.names.used; ++j) {
+
+ 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 = F_false;
+
+ if (main->setting.flag & iki_read_main_flag_at_d) {
+ if (matches < main->setting.at) {
+ matches++;
+
+ continue;
+ }
+
+ if (matches++ > main->setting.at) break;
+ }
+
+ 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);
+ }
+ } // for
+ } // for
+
+ f_file_stream_unlock(main->program.output.to);
+
+ if (unmatched) {
+ main->setting.state.status = F_data_not;
+ }
+ else {
+ main->setting.state.status = F_okay;
+ }
+ }
+ 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->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);
+
+ main->setting.state.status = F_okay;
+ }
+ else {
+ main->setting.state.status = F_data_not;
+ }
+ }
+ else {
+ f_file_stream_lock(main->program.output.to);
+
+ for (i = 0; i < data->variable.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ 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);
+ } // for
+
+ f_file_stream_unlock(main->program.output.to);
+
+ main->setting.state.status = F_okay;
+ }
+ }
+ else {
+ main->setting.state.status = F_data_not;
+ }
+ }
+ }
+#endif // _di_iki_read_iki_process_buffer_ranges_
+
+#ifndef _di_iki_read_iki_process_buffer_ranges_prepare_
+ void iki_read_iki_process_buffer_ranges_prepare(iki_read_main_t * const main, f_range_t * const range_buffer, f_iki_data_t * const data) {
+
+ if (!main || !range_buffer || !data) return;
+
+ fl_iki_read(&main->cache.buffer, range_buffer, data, &main->setting.state);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_read));
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+
+ for (; i < main->setting.map_replacess.used; ++i) {
+ main->setting.map_replacess.array[i].used = 0;
+ } // for
+
+ for (i = 0; i < main->setting.map_wrapss.used; ++i) {
+ main->setting.map_wrapss.array[i].used = 0;
+ } // for
+
+ main->setting.map_replacess.used = 0;
+ main->setting.map_wrapss.used = 0;
+
+ main->setting.state.status = f_memory_arrays_resize(data->vocabulary.used, sizeof(f_number_unsigneds_t), (void **) &main->setting.map_replacess.array, &main->setting.map_replacess.used, &main->setting.map_replacess.size, &f_number_unsignedss_delete_callback);
+
+ if (F_status_is_error_not(main->setting.state.status)) {
+ main->setting.state.status = f_memory_arrays_resize(data->vocabulary.used, sizeof(f_number_unsigneds_t), (void **) &main->setting.map_wrapss.array, &main->setting.map_wrapss.used, &main->setting.map_wrapss.size, &f_number_unsignedss_delete_callback);
+ }
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_memory_arrays_resize));
+
+ return;
+ }
+
+ for (i = 0; i < data->delimits.used; ++i) {
+ main->cache.buffer.string[data->delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
+ } // for
+
+ if (main->callback.identify_alteration) {
+ main->callback.identify_alteration(main);
+ }
+ }
+#endif // _di_iki_read_iki_process_buffer_ranges_prepare_
+
+#ifndef _di_iki_read_iki_process_buffer_ranges_whole_
+ void iki_read_iki_process_buffer_ranges_whole(iki_read_main_t * const main, f_range_t * const range_buffer) {
+
+ if (!main || !main->data || !range_buffer) return;
+
+ f_iki_data_t * const data = (f_iki_data_t *) main->data;
+
+ const f_range_t range_original = *range_buffer;
+
+ iki_read_iki_process_buffer_ranges_prepare(main, range_buffer, data);
+ if (F_status_is_error(main->setting.state.status)) return;
+
+ if (!data->variable.used) {
+ fll_print_dynamic_partial(main->cache.buffer, range_original, main->program.output.to);
+
+ main->setting.state.status = F_okay;
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+
+ {
+ f_number_unsigned_t j = 0;
+ f_number_unsigned_t k = 0;
+ f_number_unsigned_t stop = data->variable.used;
+
+ i = range_original.start;
+ *range_buffer = range_original;
+
+ f_file_stream_lock(main->program.output.to);
+
+ while (i <= range_buffer->stop && j < stop) {
+
+ if (iki_read_signal_check(main)) return;
+
+ if (i < data->variable.array[j].start) {
+ range_buffer->start = i;
+ range_buffer->stop = data->variable.array[j].start - 1;
+
+ f_print_dynamic_partial(main->cache.buffer, *range_buffer, main->program.output.to);
+
+ range_buffer->start = data->variable.array[j].stop + 1;
+ range_buffer->stop = range_original.stop;
+
+ i = data->variable.array[j].start;
+ }
+
+ if (main->setting.names.used) {
+ for (k = 0; k < main->setting.names.used; ++k) {
+ if (f_compare_dynamic_partial_string(main->setting.names.array[k].string, main->cache.buffer, main->setting.names.array[k].used, data->vocabulary.array[j]) == F_equal_to) break;
+ } // for
+
+ if (k < main->setting.names.used) {
+ if (main->callback.print_data) {
+ main->callback.print_data(&main->program.output, j);
+ }
+ }
+ }
+ else {
+ if (main->callback.print_data) {
+ main->callback.print_data(&main->program.output, j);
+ }
+ }
+
+ i = data->variable.array[j].stop + 1;
+ ++j;
+ } // while
+
+ if (i <= range_original.stop) {
+ range_buffer->start = i;
+ f_print_dynamic_partial(main->cache.buffer, *range_buffer, main->program.output.to);
+ }
+
+ f_file_stream_unlock(main->program.output.to);
+ }
+
+ main->setting.state.status = F_okay;
+ }
+#endif // _di_iki_read_iki_process_buffer_ranges_whole_
+
+#ifndef _di_iki_read_iki_process_buffer_total_
+ void iki_read_iki_process_buffer_total(iki_read_main_t * const main) {
+
+ if (!main || !main->data) return;
+
+ f_iki_data_t * const data = (f_iki_data_t *) main->data;
+
+ f_range_t range = macro_f_range_t_initialize_2(main->cache.buffer.used);
+
+ iki_read_process_line(main, &range);
+
+ if (main->setting.state.status == F_true) {
+ if (range.start > main->cache.buffer.used) {
+ fll_print_format("%r%r", main->program.output.to, f_string_ascii_0_s, f_string_eol_s);
+
+ main->setting.state.status = F_okay;
+
+ return;
+ }
+ }
+ else if (main->setting.state.status == F_data_not) {
+ fll_print_format("%r%r", main->program.output.to, f_string_ascii_0_s, f_string_eol_s);
+
+ main->setting.state.status = F_okay;
+
+ return;
+ }
+
+ fl_iki_read(&main->cache.buffer, &range, data, &main->setting.state);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_read));
+
+ return;
+ }
+
+ f_number_unsigned_t i = 0;
+ f_number_unsigned_t total = 0;
+
+ for (; i < data->delimits.used; ++i) {
+ main->cache.buffer.string[data->delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
+ } // for
+
+ if (main->program.parameters.array[iki_read_parameter_name_e].result & f_console_result_value_e) {
+ f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+ f_number_unsigned_t index = 0;
+ f_number_unsigned_t j = 0;
+
+ range.start = 0;
+
+ for (i = 0; i < main->program.parameters.array[iki_read_parameter_name_e].values.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ index = main->program.parameters.array[iki_read_parameter_name_e].values.array[i];
+ name.used = 0;
+
+ main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &name);
+
+ if (F_status_is_error(main->setting.state.status)) {
+ iki_read_print_error(&main->program.error, macro_iki_read_f(f_string_dynamic_append_nulless));
+
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &name.string, &name.used, &name.size);
+
+ return;
+ }
+
+ range.stop = name.used - 1;
+
+ for (j = 0; j < data->vocabulary.used; ++j) {
+
+ 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;
+ } // for
+ } // for
+
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &name.string, &name.used, &name.size);
+ }
+ else {
+ total = data->variable.used;
+ }
+
+ // If the "at" position is within the actual total, then the total at the given position is 1, otherwise is 0.
+ if (main->program.parameters.array[iki_read_parameter_at_e].result & f_console_result_value_e) {
+ if (main->setting.at < total) {
+ total = 1;
+ }
+ else {
+ total = 0;
+ }
+ }
+
+ fll_print_format("%ul%r", main->program.output.to, total, f_string_eol_s);
+
+ main->setting.state.status = F_okay;
+ }
+#endif // _di_iki_read_iki_process_buffer_total_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
+/**
+ * Process a given buffer, printing the given range for IKI read.
+ *
+ * @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: iki_read_iki_process_buffer_ranges_prepare().
+ * @param range_buffer
+ * The range within the buffer to process.
+ *
+ * Must not be NULL.
+ *
+ * @see iki_read_iki_process_buffer_ranges_prepare()
+ */
+#ifndef _di_iki_read_iki_process_buffer_ranges_
+ extern void iki_read_iki_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const range_buffer);
+#endif // _di_iki_read_iki_process_buffer_ranges_
+
+/**
+ * Helper function for preparing the processing of the buffer ranges.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * This alters setting.state.status:
+ * Not directly changed on success.
+ *
+ * Errors (with error bit) from: f_memory_arrays_resize().
+ * Errors (with error bit) from: fl_iki_read().
+ * @param range_buffer
+ * The range within the buffer to process.
+ *
+ * Must not be NULL.
+ * @param data
+ * The IKI data structure.
+ *
+ * Must not be NULL.
+ *
+ * @see f_memory_arrays_resize()
+ * @see fl_iki_read()
+ */
+#ifndef _di_iki_read_iki_process_buffer_ranges_prepare_
+ extern void iki_read_iki_process_buffer_ranges_prepare(iki_read_main_t * const main, f_range_t * const range_buffer, f_iki_data_t * const data);
+#endif // _di_iki_read_iki_process_buffer_ranges_prepare_
+
+/**
+ * Process a given buffer, printing the given buffer in whole mode based on the given ranges for IKI read.
+ *
+ * The entire variable is replaced with the value from the associated ranges.
+ *
+ * @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: f_memory_arrays_resize().
+ * @param range_buffer
+ * The range within the buffer to process.
+ *
+ * Must not be NULL.
+ *
+ * @see f_memory_arrays_resize()
+ */
+#ifndef _di_iki_read_iki_process_buffer_ranges_whole_
+ extern void iki_read_iki_process_buffer_ranges_whole(iki_read_main_t * const main, f_range_t * const range_buffer);
+#endif // _di_iki_read_iki_process_buffer_ranges_whole_
+
+/**
+ * Process a given buffer, printing the total for IKI read.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * @return
+ * F_okay on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_iki_read_iki_process_buffer_total_
+ extern void iki_read_iki_process_buffer_total(iki_read_main_t * const main);
+#endif // _di_iki_read_iki_process_buffer_total_
+
#ifdef __cplusplus
} // extern "C"
#endif
"f_file_size_by_id",
"f_file_stream_open",
"f_file_stream_read_until",
+ "f_memory_array_increase",
"f_memory_array_increase_by",
"f_memory_array_resize",
"f_memory_arrays_resize",
"f_string_dynamic_append_nulless",
"f_string_dynamics_append",
"f_thread_create",
+ "fl_iki_eki_read",
"fl_iki_read",
"fll_program_parameter_process_context_standard",
"fll_program_parameter_process_verbosity_standard",
iki_read_f_f_file_size_by_id_e,
iki_read_f_f_file_stream_open_e,
iki_read_f_f_file_stream_read_until_e,
+ iki_read_f_f_memory_array_increase_e,
iki_read_f_f_memory_array_increase_by_e,
iki_read_f_f_memory_array_resize_e,
iki_read_f_f_memory_arrays_resize_e,
iki_read_f_f_string_dynamics_increase_by_e,
iki_read_f_f_string_dynamics_resize_e,
iki_read_f_f_thread_create_e,
+ iki_read_f_fl_iki_eki_read_e,
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_cache_delete(&main->cache);
fll_program_data_delete(&main->program);
iki_read_setting_delete(&main->setting);
+
+ if (main->callback.delete_data) {
+ main->callback.delete_data(main);
+ }
}
#endif // _di_iki_read_main_delete_
f_memory_arrays_resize(0, sizeof(f_string_triple_t), (void **) &setting->substitute.array, &setting->substitute.used, &setting->substitute.size, &f_string_triples_delete_callback);
f_memory_arrays_resize(0, sizeof(f_string_triple_t), (void **) &setting->wrap.array, &setting->wrap.used, &setting->wrap.size, &f_string_triples_delete_callback);
- f_iki_data_delete(&setting->data);
+ f_memory_arrays_resize(0, sizeof(f_number_unsigneds_t), (void **) &setting->map_replacess.array, &setting->map_replacess.used, &setting->map_replacess.size, &f_number_unsignedss_delete_callback);
+ f_memory_arrays_resize(0, sizeof(f_number_unsigneds_t), (void **) &setting->map_wrapss.array, &setting->map_wrapss.used, &setting->map_wrapss.size, &f_number_unsignedss_delete_callback);
}
#endif // _di_iki_read_setting_delete_
#endif
/**
+ * Make the typedef for iki_read_main_t available to child structures.
+ */
+#ifndef _di_iki_read_main_t__
+ typedef struct iki_read_main_t_ iki_read_main_t;
+#endif // _di_iki_read_main_t__
+
+/**
* The IKI read main program cache.
*
* Properties:
* The IKI write callbacks.
*
* Properties:
+ * - identify_alteration: Identify the location of an alteration.
+ *
+ * - print_data: Print IKI/EKI data at the given index.
* - print_help: Print the main help message.
*
- * - process_objects_content: Process an Objects and Content set.
+ * - process_buffer_ranges: Process and print the given reange.
+ * - process_buffer_ranges_whole: Process and print the given ranges in whole mode.
+ * - process_buffer_total: Process and print the total.
+ *
+ * - delete_data: Delete the IKI/EKI data.
*/
#ifndef _di_iki_read_callback_t_
typedef struct {
+ void (*identify_alteration)(iki_read_main_t * const main);
+
+ void (*print_data)(fl_print_t * const print, const f_number_unsigned_t index);
void (*print_help)(fl_print_t * const print);
- void (*process_objects_content)(void * const main, const f_string_statics_t objects, const f_string_static_t content);
+ void (*process_buffer_ranges)(iki_read_main_t * const main, f_range_t * const range_buffer);
+ void (*process_buffer_ranges_whole)(iki_read_main_t * const main, f_range_t * const range_buffer);
+ void (*process_buffer_total)(iki_read_main_t * const main);
+
+ void (*delete_data)(iki_read_main_t * const main);
} iki_read_callback_t;
#define iki_read_callback_t_initialize \
{ \
0, \
0, \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
}
#endif // _di_iki_read_callback_t_
* - substitute: A triple containing the Vocabulary name (a), Content to match (b), and the string used as the substitute (c).
* - wrap: A triple containing the Vocabulary name (a), the string to prepend (b), and the string to append (c).
*
- * - map_replaces: A pointer representing an array with length of setting->data.vocabulary.used mapping the vocabulary location to a replace array location.
- * - map_wraps: A pointer representing an array with length of setting->data.vocabulary.used mapping the vocabulary location to a wrap array location.
- *
- * - data: The loaded IKI data.
+ * - map_replacess: Map the vocabulary location to a location containing the replace parameter value.
+ * - map_wrapss: Map the vocabulary location to a location containing the wrap parameter value.
*/
#ifndef _di_iki_read_setting_t_
typedef struct {
f_string_triples_t substitute;
f_string_triples_t wrap;
- f_number_unsigned_t *map_replaces;
- f_number_unsigned_t *map_wraps;
-
- f_iki_data_t data;
+ f_number_unsignedss_t map_replacess;
+ f_number_unsignedss_t map_wrapss;
} iki_read_setting_t;
#define iki_read_setting_t_initialize \
f_string_triples_t_initialize, \
f_string_triples_t_initialize, \
f_string_triples_t_initialize, \
- 0, \
- 0, \
- f_iki_data_t_initialize, \
+ f_number_unsignedss_t_initialize, \
+ f_number_unsignedss_t_initialize, \
}
#endif // _di_iki_read_setting_t_
* The main program data as a single structure.
*
* Properties:
- * - program: The main program data.
- * - setting: The settings data.
+ * - cache: The cache data.
+ * - callback: The callbacks.
+ * - data: A pointer for the structure representing IKI data (or EKI data).
+ * - program: The main program data.
+ * - setting: The settings data.
*/
#ifndef _di_iki_read_main_t_
- typedef struct {
+ struct iki_read_main_t_ {
iki_read_cache_t cache;
iki_read_callback_t callback;
+ void * data;
fll_program_data_t program;
iki_read_setting_t setting;
- } iki_read_main_t;
-
- #define iki_read_main_t_initialize \
- { \
- iki_read_cache_t_initialize, \
- iki_read_callback_t_initialize, \
- fll_program_data_t_initialize, \
- iki_read_setting_t_initialize, \
- }
+ };
+
+ #ifndef iki_read_main_t_initialize
+ #define iki_read_main_t_initialize \
+ { \
+ iki_read_cache_t_initialize, \
+ iki_read_callback_t_initialize, \
+ 0, \
+ fll_program_data_t_initialize, \
+ iki_read_setting_t_initialize, \
+ }
+ #endif // iki_read_main_t_initialize
#endif // _di_iki_read_main_t_
/**
extern "C" {
#endif
-#ifndef _di_iki_read_identify_alteration_
- void iki_read_identify_alteration(iki_read_main_t * const main) {
-
- if (!main || !(main->setting.replace.used || main->setting.wrap.used)) return;
-
- f_number_unsigned_t i = 0;
-
- if (main->setting.flag & (iki_read_main_flag_content_d | iki_read_main_flag_literal_d)) {
- f_number_unsigned_t j = 0;
-
- for (i = 0; i < main->setting.data.vocabulary.used; ++i) {
-
- if (main->setting.replace.used) {
- main->setting.map_replaces[i] = main->setting.replace.used;
-
- j = main->setting.replace.used - 1;
-
- do {
- if (f_compare_dynamic_partial_string(main->setting.replace.array[j].key.string, main->cache.buffer, main->setting.replace.array[j].key.used, main->setting.data.vocabulary.array[i]) == F_equal_to) {
- main->setting.map_replaces[i] = j;
-
- break;
- }
-
- } while (j--);
- }
-
- if (main->setting.wrap.used) {
- main->setting.map_wraps[i] = main->setting.wrap.used;
-
- j = main->setting.wrap.used - 1;
-
- do {
- if (f_compare_dynamic_partial_string(main->setting.wrap.array[j].a.string, main->cache.buffer, main->setting.wrap.array[j].a.used, main->setting.data.vocabulary.array[i]) == F_equal_to) {
- main->setting.map_wraps[i] = j;
-
- break;
- }
-
- } while (j--);
- }
- } // for
- }
- else {
- for (i = 0; i < main->setting.data.vocabulary.used; ++i) {
-
- if (main->setting.replace.used) {
- main->setting.map_replaces[i] = main->setting.replace.used;
- }
-
- if (main->setting.wrap.used) {
- main->setting.map_wraps[i] = main->setting.wrap.used;
- }
- } // for
- }
- }
-#endif // _di_iki_read_identify_alteration_
-
#ifndef _di_iki_read_identify_substitution_
- f_number_unsigned_t iki_read_identify_substitution(iki_read_main_t * const main, const f_range_t name, const f_range_t value, f_string_triples_t *triple) {
+ f_number_unsigned_t iki_read_identify_substitution(iki_read_main_t * const main, const f_range_t name, const f_range_t value, f_string_triples_t * const triple) {
f_number_unsigned_t i = triple->used - 1;
#endif
/**
- * Process the arguments, associating replacements and wraps with a given vocabulary.
- *
- * This does not handle substitutions because substitutions must match both name and value (Object and Content).
- * This function does not know the value (Content).
- *
- * @param main
- * The program and settings data.
- * @param replaces
- * A map to the last matching replacment or a value of setting->data.vocabulary.used if there is no matching replacement.
- * Must be an array of length setting->data.vocabulary.used.
- * @param wraps
- * A map to the last matching wrap or a value of setting->data.vocabulary.used if there is no matching wrap.
- * Must be an array of length setting->data.vocabulary.used.
- *
- * @return
- * The matching setting->data.vocabulary index or if no match then setting->data.vocabulary.used.
- */
-#ifndef _di_iki_read_identify_alteration_
- extern void iki_read_identify_alteration(iki_read_main_t * const main);
-#endif // _di_iki_read_identify_alteration_
-
-/**
* Process the arguments, associating the last matching reassignment or substitution with a given vocabulary name and value (Object and Content).
*
* This function expects appropriate sanity checks are performed on the reassignments or substitutions array before calling.
* The value of the triple.used is returned on no match.
*/
#ifndef _di_iki_read_identify_substitution_
- extern f_number_unsigned_t iki_read_identify_substitution(iki_read_main_t * const main, const f_range_t name, const f_range_t value, f_string_triples_t *triple);
+ extern f_number_unsigned_t iki_read_identify_substitution(iki_read_main_t * const main, const f_range_t name, const f_range_t value, f_string_triples_t * const triple);
#endif // _di_iki_read_identify_substitution_
#ifdef __cplusplus
for (size_read = 0; size_read < size_file; size_read += size_block) {
- // The signal check is always performed on each pass.
- if (size_file > iki_read_block_max_d && fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- break;
- }
+ if (size_file > iki_read_block_max_d && iki_read_signal_check(main)) break;
main->setting.state.status = f_file_stream_read_until(file, size_block, &main->cache.buffer);
if (F_status_is_error(main->setting.state.status)) break;
+++ /dev/null
-#include "iki_read.h"
-
-int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
-
- iki_read_main_t data = iki_read_main_t_initialize;
-
- data.program.debug.flag |= iki_read_print_flag_debug_d | iki_read_print_flag_out_d;
- data.program.error.flag |= iki_read_print_flag_error_d | iki_read_print_flag_out_d;
- data.program.output.flag |= iki_read_print_flag_out_d;
- data.program.message.flag |= iki_read_print_flag_message_d | iki_read_print_flag_out_d;
- data.program.warning.flag |= iki_read_print_flag_warning_d | iki_read_print_flag_out_d;
- data.program.error.custom = (void *) &data;
- data.program.debug.custom = (void *) &data;
- data.program.message.custom = (void *) &data;
- data.program.output.custom = (void *) &data;
- data.program.warning.custom = (void *) &data;
-
- data.setting.state.custom = (void *) &data;
- data.setting.state.handle = &fll_program_standard_signal_handle;
-
- f_console_parameter_t parameters[] = iki_read_console_parameter_t_initialize;
- data.program.parameters.array = parameters;
- data.program.parameters.used = iki_read_parameter_total_d;
- data.program.environment = envp;
-
- if (f_pipe_input_exists()) {
- data.program.pipe = fll_program_data_pipe_input_e;
- }
-
- fll_program_standard_set_up(&data.program);
-
- f_file_umask_get(&data.program.umask);
-
- #ifdef _di_thread_support_
- {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
-
- iki_read_setting_load(arguments, &data);
- }
-
- iki_read_main(&data);
- #else
- {
- f_thread_id_t id_signal;
-
- memset(&id_signal, 0, sizeof(f_thread_id_t));
-
- data.setting.state.status = f_thread_create(0, &id_signal, &iki_read_thread_signal, (void *) &data);
-
- if (F_status_is_error(data.setting.state.status)) {
- iki_read_print_error(&data.program.error, macro_iki_read_f(f_thread_create));
- }
- else {
- {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
-
- iki_read_setting_load(arguments, &data);
- }
-
- if (!iki_read_signal_check(&data)) {
- iki_read_main(&data);
- }
-
- f_thread_cancel(id_signal);
- f_thread_join(id_signal, 0);
- }
- }
- #endif // _di_thread_support_
-
- iki_read_main_delete(&data);
-
- fll_program_standard_set_down(&data.program);
-
- return F_status_is_error(data.setting.state.status) ? 1 : 0;
-}
+++ /dev/null
-/**
- * FLL - Level 3
- *
- * Project: IKI Read
- * API Version: 0.7
- * Licenses: lgpl-2.1-or-later
- *
- * This file is only ever included by main/main.c and should not normally be included anywhere else.
- * Anything that wants to include this should be providing the "iki_read" program functionality in some manner.
- */
-#ifndef _iki_read_main_h
-#define _iki_read_main_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Standard program entry point.
- *
- * @param argc
- * The number of arguments.
- * @param argv
- * The array of arguments.
- * @param envp
- * The array of all environment variables on program start.
- *
- * @return
- * 0 on success.
- * 1 on error.
- */
-extern int main(const int argc, const f_string_t *argv, const f_string_t *envp);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // _iki_read_main_h
extern "C" {
#endif
-#ifndef _di_iki_read_print_data_
- void iki_read_print_data(fl_print_t * const print, const f_number_unsigned_t index) {
+#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) {
if (!print || !print->custom) return;
iki_read_main_t * const main = (iki_read_main_t *) print->custom;
- f_number_unsigned_t at = main->setting.reassign.used;
-
- 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, main->setting.data.vocabulary.array[index], main->setting.data.content.array[index], &main->setting.reassign);
- }
-
- if (at < 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);
- }
- else {
- f_range_t range = macro_f_range_t_initialize_1(main->setting.data.variable.array[index].start, main->setting.data.content.array[index].start - 1);
-
- 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);
-
- range.start = main->setting.data.content.array[index].stop + 1;
- range.stop = main->setting.data.variable.array[index].stop;
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
- }
-
- return;
- }
-
- at = 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, main->setting.data.vocabulary.array[index], main->setting.data.content.array[index], &main->setting.substitute);
- }
-
- if (at < 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);
-
- iki_read_print_data_wrap_append(&main->program.output, index);
- }
- else {
- f_range_t range = macro_f_range_t_initialize_1(main->setting.data.variable.array[index].start, main->setting.data.content.array[index].start - 1);
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
-
- iki_read_print_data_wrap_prepend(&main->program.output, index);
-
- f_print_dynamic(main->setting.substitute.array[at].c, main->program.output.to);
-
- iki_read_print_data_wrap_append(&main->program.output, index);
-
- range.start = main->setting.data.content.array[index].stop + 1;
- range.stop = main->setting.data.variable.array[index].stop;
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
- }
- }
- else if (main->setting.replace.used && main->setting.map_replaces[index] < main->setting.replace.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.replace.array[main->setting.map_replaces[index]].value, main->program.output.to);
-
- iki_read_print_data_wrap_append(&main->program.output, index);
- }
- else if (main->setting.flag & iki_read_main_flag_object_d) {
- f_print_dynamic(main->setting.replace.array[main->setting.map_replaces[index]].key, main->program.output.to);
- }
- else {
- f_range_t range = macro_f_range_t_initialize_1(main->setting.data.variable.array[index].start, main->setting.data.content.array[index].start - 1);
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
-
- iki_read_print_data_wrap_prepend(&main->program.output, index);
+ if (index >= main->setting.map_wrapss.used) return;
- f_print_dynamic(main->setting.replace.array[main->setting.map_replaces[index]].value, main->program.output.to);
+ f_number_unsigned_t * const array = main->setting.map_wrapss.array[index].array;
- iki_read_print_data_wrap_append(&main->program.output, index);
+ for (f_number_unsigned_t i = 0; i < main->setting.map_wrapss.array[index].used; ++i) {
- range.start = main->setting.data.content.array[index].stop + 1;
- range.stop = main->setting.data.variable.array[index].stop;
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
+ if (array[i] < main->setting.wrap.used && main->setting.wrap.array[array[i]].c.used) {
+ f_print_dynamic(main->setting.wrap.array[array[i]].c, main->program.output.to);
}
- }
- else if (main->setting.flag & iki_read_main_flag_content_d) {
- iki_read_print_data_wrap_prepend(&main->program.output, index);
-
- f_print_dynamic_partial(main->cache.buffer, main->setting.data.content.array[index], main->program.output.to);
-
- iki_read_print_data_wrap_append(&main->program.output, index);
- }
- else if (main->setting.flag & iki_read_main_flag_object_d) {
- f_print_dynamic_partial(main->cache.buffer, main->setting.data.vocabulary.array[index], main->program.output.to);
- }
- else {
- f_range_t range = macro_f_range_t_initialize_1(main->setting.data.variable.array[index].start, main->setting.data.content.array[index].start - 1);
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
-
- iki_read_print_data_wrap_prepend(&main->program.output, index);
-
- f_print_dynamic_partial(main->cache.buffer, main->setting.data.content.array[index], main->program.output.to);
-
- iki_read_print_data_wrap_append(&main->program.output, index);
-
- range.start = main->setting.data.content.array[index].stop + 1;
- range.stop = main->setting.data.variable.array[index].stop;
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
- }
- }
-#endif // _di_iki_read_print_data_
-
-#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) {
-
- if (!print || !print->custom) return;
-
- iki_read_main_t * const main = (iki_read_main_t *) print->custom;
-
- if (index < main->setting.data.vocabulary.used && main->setting.map_wraps[index] < main->setting.wrap.used) {
- if (!main->setting.wrap.array[main->setting.map_wraps[index]].c.used) return;
- }
- else {
- return;
- }
-
- f_print_dynamic(main->setting.wrap.array[main->setting.map_wraps[index]].c, main->program.output.to);
+ } // for
}
#endif // _di_iki_read_print_data_wrap_append_
iki_read_main_t * const main = (iki_read_main_t *) print->custom;
- if (index < main->setting.data.vocabulary.used && main->setting.map_wraps[index] < main->setting.wrap.used) {
- if (!main->setting.wrap.array[main->setting.map_wraps[index]].b.used) return;
- }
- else {
- return;
- }
+ if (index >= main->setting.map_wrapss.used) return;
- f_print_dynamic(main->setting.wrap.array[main->setting.map_wraps[index]].b, main->program.output.to);
+ 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) {
+ f_print_dynamic(main->setting.wrap.array[array[i]].b, main->program.output.to);
+ }
+ } // for
}
#endif // _di_iki_read_print_data_wrap_prepend_
#endif
/**
- * Print the given range at the given index.
- *
- * 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_wraps is expected to be defined as a valid pointer to an array.
- * The setting.map_replaces 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_prepend()
- * @see iki_read_print_data_wrap_append()
- */
-#ifndef _di_iki_read_print_data_
- extern void iki_read_print_data(fl_print_t * const print, const f_number_unsigned_t index) F_attribute_visibility_internal_d;
-#endif // _di_iki_read_print_data_
-
-/**
* Print the append part of the wrap at the given index, if valid.
*
* This expects the caller to have the output locked appropriately.
*
* This does not alter print.custom.setting.state.status.
* @param index
- * The index within the setting->map_wraps array to print.
- *
- * @see f_print_dynamic()
+ * The index within the setting->map_wrapss array to print.
*/
#ifndef _di_iki_read_print_data_wrap_append_
- extern void iki_read_print_data_wrap_append(fl_print_t * const print, const f_number_unsigned_t index) F_attribute_visibility_internal_d;
+ extern void iki_read_print_data_wrap_append(fl_print_t * const print, const f_number_unsigned_t index);
#endif // _di_iki_read_print_data_wrap_append_
/**
*
* This does not alter print.custom.setting.state.status.
* @param index
- * The index within the setting->map_wraps array to print.
- *
- * @see f_print_dynamic()
+ * The index within the setting->map_wrapss array to print.
*/
#ifndef _di_iki_read_print_data_wrap_prepend_
- extern void iki_read_print_data_wrap_prepend(fl_print_t * const print, const f_number_unsigned_t index) F_attribute_visibility_internal_d;
+ extern void iki_read_print_data_wrap_prepend(fl_print_t * const print, const f_number_unsigned_t index);
#endif // _di_iki_read_print_data_wrap_prepend_
#ifdef __cplusplus
void iki_read_process_buffer(iki_read_main_t * const main) {
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_process_buffer_total(main);
+ 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;
+ if (F_status_is_error_not(main->setting.state.status)) {
+ main->setting.state.status = F_okay;
+ }
}
return;
}
if (main->setting.flag & iki_read_main_flag_whole_d) {
- iki_read_process_buffer_ranges_whole(main, buffer_range);
- }
- else {
- iki_read_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_buffer_ranges_
- void iki_read_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const buffer_range) {
-
- fl_iki_read(&main->cache.buffer, buffer_range, &main->setting.data, &main->setting.state);
-
- if (F_status_is_error(main->setting.state.status)) {
- iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_read));
-
- return;
- }
-
- f_number_unsigned_t i = 0;
- f_number_unsigned_t replaces[main->setting.data.vocabulary.used];
- f_number_unsigned_t wraps[main->setting.data.vocabulary.used];
-
- memset(replaces, 0, sizeof(f_number_unsigned_t) * main->setting.data.vocabulary.used);
- memset(wraps, 0, sizeof(f_number_unsigned_t) * main->setting.data.vocabulary.used);
-
- main->setting.map_replaces = replaces;
- main->setting.map_wraps = wraps;
-
- for (; i < main->setting.data.delimits.used; ++i) {
- main->cache.buffer.string[main->setting.data.delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
- } // for
-
- iki_read_identify_alteration(main);
-
- 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 = F_true;
-
- f_file_stream_lock(main->program.output.to);
-
- for (i = 0; i < main->setting.data.vocabulary.used; ++i) {
-
- for (j = 0; j < main->setting.names.used; ++j) {
-
- if (f_compare_dynamic_partial_string(main->setting.names.array[j].string, main->cache.buffer, main->setting.names.array[j].used, main->setting.data.vocabulary.array[i]) == F_equal_to) {
- unmatched = F_false;
-
- if (main->setting.flag & iki_read_main_flag_at_d) {
- if (matches < main->setting.at) {
- matches++;
-
- continue;
- }
-
- if (matches++ > main->setting.at) break;
- }
-
- iki_read_print_data(&main->program.output, i);
-
- f_print_dynamic_raw(f_string_eol_s, main->program.output.to);
- }
- } // for
- } // for
-
- f_file_stream_unlock(main->program.output.to);
-
- if (unmatched) {
- main->setting.state.status = F_data_not;
- }
- else {
- main->setting.state.status = F_okay;
+ if (main->callback.process_buffer_ranges_whole) {
+ main->callback.process_buffer_ranges_whole(main, &buffer_range);
}
}
else {
- if (main->setting.data.variable.used) {
- if (main->setting.flag & iki_read_main_flag_at_d) {
- if (main->setting.at < main->setting.data.variable.used) {
- f_file_stream_lock(main->program.output.to);
-
- iki_read_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);
-
- main->setting.state.status = F_okay;
- }
- else {
- main->setting.state.status = F_data_not;
- }
- }
- else {
- f_file_stream_lock(main->program.output.to);
-
- for (i = 0; i < main->setting.data.variable.used; ++i) {
-
- iki_read_print_data(&main->program.output, i);
-
- f_print_dynamic_raw(f_string_eol_s, main->program.output.to);
- } // for
-
- f_file_stream_unlock(main->program.output.to);
-
- main->setting.state.status = F_okay;
- }
- }
- else {
- main->setting.state.status = F_data_not;
+ if (main->callback.process_buffer_ranges) {
+ main->callback.process_buffer_ranges(main, &buffer_range);
}
}
- }
-#endif // _di_iki_read_process_buffer_ranges_
-
-#ifndef _di_iki_read_process_buffer_ranges_whole_
- void iki_read_process_buffer_ranges_whole(iki_read_main_t * const main, const f_range_t buffer_range) {
-
- f_range_t range = buffer_range;
-
- fl_iki_read(&main->cache.buffer, &range, &main->setting.data, &main->setting.state);
-
- if (F_status_is_error(main->setting.state.status)) {
- iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_read));
-
- return;
- }
-
- f_number_unsigned_t i = 0;
-
- for (; i < main->setting.data.delimits.used; ++i) {
- main->cache.buffer.string[main->setting.data.delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
- } // for
-
- if (!main->setting.data.variable.used) {
- fll_print_dynamic_partial(main->cache.buffer, buffer_range, main->program.output.to);
-
- main->setting.state.status = F_okay;
-
- return;
- }
-
- f_number_unsigned_t replaces[main->setting.data.vocabulary.used];
- f_number_unsigned_t wraps[main->setting.data.vocabulary.used];
-
- memset(replaces, 0, sizeof(f_number_unsigned_t) * main->setting.data.vocabulary.used);
- memset(wraps, 0, sizeof(f_number_unsigned_t) * main->setting.data.vocabulary.used);
-
- main->setting.map_replaces = replaces;
- main->setting.map_wraps = wraps;
-
- iki_read_identify_alteration(main);
-
- {
- f_number_unsigned_t j = 0;
- f_number_unsigned_t k = 0;
- f_number_unsigned_t stop = main->setting.data.variable.used;
-
- i = buffer_range.start;
- range = buffer_range;
-
- f_file_stream_lock(main->program.output.to);
-
- while (i <= range.stop && j < stop) {
-
- if (i < main->setting.data.variable.array[j].start) {
- range.start = i;
- range.stop = main->setting.data.variable.array[j].start - 1;
-
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
-
- range.start = main->setting.data.variable.array[j].stop + 1;
- range.stop = buffer_range.stop;
-
- i = main->setting.data.variable.array[j].start;
- }
-
- if (main->setting.names.used) {
- for (k = 0; k < main->setting.names.used; ++k) {
- if (f_compare_dynamic_partial_string(main->setting.names.array[k].string, main->cache.buffer, main->setting.names.array[k].used, main->setting.data.vocabulary.array[j]) == F_equal_to) break;
- } // for
-
- if (k < main->setting.names.used) {
- iki_read_print_data(&main->program.output, j);
- }
- }
- else {
- iki_read_print_data(&main->program.output, j);
- }
-
- i = main->setting.data.variable.array[j].stop + 1;
- ++j;
- } // while
-
- if (i <= buffer_range.stop) {
- range.start = i;
- f_print_dynamic_partial(main->cache.buffer, range, main->program.output.to);
- }
-
- f_file_stream_unlock(main->program.output.to);
- }
-
- main->setting.state.status = F_okay;
- }
-#endif // _di_iki_read_process_buffer_ranges_whole_
-
-#ifndef _di_iki_read_process_buffer_total_
- void iki_read_process_buffer_total(iki_read_main_t * const main) {
-
- f_range_t range = macro_f_range_t_initialize_2(main->cache.buffer.used);
-
- iki_read_process_line(main, &range);
-
- if (main->setting.state.status == F_true) {
- if (range.start > main->cache.buffer.used) {
- fll_print_format("%r%r", main->program.output.to, f_string_ascii_0_s, f_string_eol_s);
-
- main->setting.state.status = F_okay;
-
- return;
- }
- }
- else if (main->setting.state.status == F_data_not) {
- fll_print_format("%r%r", main->program.output.to, f_string_ascii_0_s, f_string_eol_s);
+ if (F_status_is_error_not(main->setting.state.status)) {
main->setting.state.status = F_okay;
-
- return;
}
-
- fl_iki_read(&main->cache.buffer, &range, &main->setting.data, &main->setting.state);
-
- if (F_status_is_error(main->setting.state.status)) {
- iki_read_print_error(&main->program.error, macro_iki_read_f(fl_iki_read));
-
- return;
- }
-
- f_number_unsigned_t i = 0;
- f_number_unsigned_t total = 0;
-
- for (; i < main->setting.data.delimits.used; ++i) {
- main->cache.buffer.string[main->setting.data.delimits.array[i]] = f_iki_syntax_placeholder_s.string[0];
- } // for
-
- if (main->program.parameters.array[iki_read_parameter_name_e].result & f_console_result_value_e) {
- f_string_dynamic_t name = f_string_dynamic_t_initialize;
-
- f_number_unsigned_t index = 0;
- f_number_unsigned_t j = 0;
-
- range.start = 0;
-
- for (i = 0; i < main->program.parameters.array[iki_read_parameter_name_e].values.used; ++i) {
-
- if (iki_read_signal_check(main)) return;
-
- index = main->program.parameters.array[iki_read_parameter_name_e].values.array[i];
- name.used = 0;
-
- main->setting.state.status = f_string_dynamic_append_nulless(main->program.parameters.arguments.array[index], &name);
-
- if (F_status_is_error(main->setting.state.status)) {
- iki_read_print_error(&main->program.error, macro_iki_read_f(f_string_dynamic_append_nulless));
-
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &name.string, &name.used, &name.size);
-
- return;
- }
-
- range.stop = name.used - 1;
-
- for (j = 0; j < main->setting.data.vocabulary.used; ++j) {
-
- main->setting.state.status = f_compare_dynamic_partial(name, main->cache.buffer, range, main->setting.data.vocabulary.array[j]);
-
- if (main->setting.state.status == F_equal_to) ++total;
- } // for
- } // for
-
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &name.string, &name.used, &name.size);
- }
- else {
- total = main->setting.data.variable.used;
- }
-
- // If the "at" position is within the actual total, then the total at the given position is 1, otherwise is 0.
- if (main->program.parameters.array[iki_read_parameter_at_e].result & f_console_result_value_e) {
- if (main->setting.at < total) {
- total = 1;
- }
- else {
- total = 0;
- }
- }
-
- fll_print_format("%ul%r", main->program.output.to, total, f_string_eol_s);
-
- main->setting.state.status = F_okay;
}
-#endif // _di_iki_read_process_buffer_total_
+#endif // _di_iki_read_process_buffer_
#ifdef __cplusplus
} // extern "C"
/**
* Process a given buffer.
*
- * This will print error messages.
+ * This will print error messages, except for errors in callbacks.
+ * The callbacks should handle their own error printing.
*
* @param main
* The main program data.
*
* F_interrupt (with error bit) on (exit) signal received.
*
- * Errors (with error bit) from: iki_read_process_at().
- * Errors (with error bit) from: iki_read_process_buffer_ranges().
- * Errors (with error bit) from: iki_read_process_buffer_ranges_whole().
+ * 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 iki_read_process_at()
- * @see iki_read_process_buffer_ranges()
- * @see iki_read_process_buffer_ranges_whole()
+ * @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_
-/**
- * Process a given buffer, printing the given range.
- *
- * @param main
- * The main program data.
- *
- * Must not be NULL.
- * @param buffer_range
- * The range within the buffer to process.
- *
- * Must not be NULL.
- *
- * @return
- * F_okay on success.
- * F_data_not on success, but nothing to print.
- *
- * Status codes (with error bit) are returned on any problem.
- */
-#ifndef _di_iki_read_process_buffer_ranges_
- extern void iki_read_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const buffer_range);
-#endif // _di_iki_read_process_buffer_ranges_
-
-/**
- * Process a given buffer, printing the given buffer in whole mode based on the given ranges.
- *
- * The entire variable is replaced with the value from the associated ranges.
- *
- * @param main
- * The main program data.
- *
- * Must not be NULL.
- *
- * @return
- * F_okay on success.
- * F_data_not on success, but nothing to print.
- *
- * Status codes (with error bit) are returned on any problem.
- */
-#ifndef _di_iki_read_process_buffer_ranges_whole_
- extern void iki_read_process_buffer_ranges_whole(iki_read_main_t * const main, const f_range_t buffer_range);
-#endif // _di_iki_read_process_buffer_ranges_whole_
-
-/**
- * Process a given buffer, printing the total.
- *
- * @param main
- * The main program data.
- *
- * Must not be NULL.
- *
- * @return
- * F_okay on success.
- *
- * Status codes (with error bit) are returned on any problem.
- */
-#ifndef _di_iki_read_process_buffer_total_
- extern void iki_read_process_buffer_total(iki_read_main_t * const main);
-#endif // _di_iki_read_process_buffer_total_
-
#ifdef __cplusplus
} // extern "C"
#endif
build_libraries-monolithic -lfll
build_sources_program eki/main.c
-build_sources_program eki/common.c eki/eki_read.c eki/print.c eki/process.c
+build_sources_program eki/common.c eki/eki_read.c eki/identify.c eki/print.c eki/process.c
-build_sources_headers eki/common.h eki/eki_read.h eki/print.h eki/process.h
+build_sources_headers eki/common.h eki/eki_read.h eki/identify.h eki/print.h eki/process.h
build_sources_documentation man
build_libraries-monolithic -lfll
build_sources_program iki/main.c
-build_sources_program iki/common.c iki/iki_read.c iki/print.c iki/process.c
+build_sources_program iki/common.c iki/identify.c iki/iki_read.c iki/print.c iki/process.c
-build_sources_headers iki/common.h iki/iki_read.h iki/print.h iki/process.h
+build_sources_headers iki/common.h iki/identify.h iki/iki_read.h iki/print.h iki/process.h
build_sources_documentation man