From 740d5fc88d6e05edf2a7267c422642bd14cc473c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 26 Nov 2024 00:01:15 -0600 Subject: [PATCH] Progress: Begin adding the eki_write program by extending iki_write. This is a bit rushed, so I will have additional passes to make. --- level_3/iki_write/c/eki/common.c | 127 ++++++++++++++++++++++++ level_3/iki_write/c/eki/common.h | 66 ++++++++++++ level_3/iki_write/c/eki/eki_write.c | 10 ++ level_3/iki_write/c/eki/eki_write.h | 76 ++++++++++++++ level_3/iki_write/c/eki/main.c | 77 ++++++++++++++ level_3/iki_write/c/{main => eki}/main.h | 8 +- level_3/iki_write/c/eki/print.c | 84 ++++++++++++++++ level_3/iki_write/c/eki/print.h | 81 +++++++++++++++ level_3/iki_write/c/eki/process.c | 127 ++++++++++++++++++++++++ level_3/iki_write/c/eki/process.h | 77 ++++++++++++++ level_3/iki_write/c/iki/common.c | 102 +++++++++++++++++++ level_3/iki_write/c/iki/common.h | 66 ++++++++++++ level_3/iki_write/c/iki/iki_write.c | 10 ++ level_3/iki_write/c/iki/iki_write.h | 76 ++++++++++++++ level_3/iki_write/c/{main => iki}/main.c | 9 +- level_3/iki_write/c/iki/main.h | 38 +++++++ level_3/iki_write/c/iki/print.c | 61 ++++++++++++ level_3/iki_write/c/iki/print.h | 63 ++++++++++++ level_3/iki_write/c/iki/process.c | 118 ++++++++++++++++++++++ level_3/iki_write/c/iki/process.h | 77 ++++++++++++++ level_3/iki_write/c/main/common.c | 79 +++------------ level_3/iki_write/c/main/common.h | 6 +- level_3/iki_write/c/main/common/print.c | 2 + level_3/iki_write/c/main/common/print.h | 2 + level_3/iki_write/c/main/common/string.c | 5 - level_3/iki_write/c/main/common/string.h | 18 +--- level_3/iki_write/c/main/common/type.c | 5 +- level_3/iki_write/c/main/common/type.h | 42 ++++++-- level_3/iki_write/c/main/iki_write.c | 56 ++--------- level_3/iki_write/c/main/iki_write.h | 1 - level_3/iki_write/c/main/print/error.c | 20 +--- level_3/iki_write/c/main/print/error.h | 20 ---- level_3/iki_write/c/main/print/message.c | 25 ++--- level_3/iki_write/c/main/print/message.h | 26 +++-- level_3/iki_write/c/main/process.c | 43 -------- level_3/iki_write/c/main/process.h | 47 --------- level_3/iki_write/data/build/fakefile | 8 +- level_3/iki_write/data/build/settings | 8 +- level_3/iki_write/data/build/settings.eki_write | 71 +++++++++++++ level_3/iki_write/data/build/settings.iki_write | 71 +++++++++++++ 40 files changed, 1601 insertions(+), 307 deletions(-) create mode 100644 level_3/iki_write/c/eki/common.c create mode 100644 level_3/iki_write/c/eki/common.h create mode 100644 level_3/iki_write/c/eki/eki_write.c create mode 100644 level_3/iki_write/c/eki/eki_write.h create mode 100644 level_3/iki_write/c/eki/main.c rename level_3/iki_write/c/{main => eki}/main.h (83%) create mode 100644 level_3/iki_write/c/eki/print.c create mode 100644 level_3/iki_write/c/eki/print.h create mode 100644 level_3/iki_write/c/eki/process.c create mode 100644 level_3/iki_write/c/eki/process.h create mode 100644 level_3/iki_write/c/iki/common.c create mode 100644 level_3/iki_write/c/iki/common.h create mode 100644 level_3/iki_write/c/iki/iki_write.c create mode 100644 level_3/iki_write/c/iki/iki_write.h rename level_3/iki_write/c/{main => iki}/main.c (84%) create mode 100644 level_3/iki_write/c/iki/main.h create mode 100644 level_3/iki_write/c/iki/print.c create mode 100644 level_3/iki_write/c/iki/print.h create mode 100644 level_3/iki_write/c/iki/process.c create mode 100644 level_3/iki_write/c/iki/process.h delete mode 100644 level_3/iki_write/c/main/process.c delete mode 100644 level_3/iki_write/c/main/process.h create mode 100644 level_3/iki_write/data/build/settings.eki_write create mode 100644 level_3/iki_write/data/build/settings.iki_write diff --git a/level_3/iki_write/c/eki/common.c b/level_3/iki_write/c/eki/common.c new file mode 100644 index 0000000..ea8b1ef --- /dev/null +++ b/level_3/iki_write/c/eki/common.c @@ -0,0 +1,127 @@ +#include "eki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_write_eki_s_ + const f_string_static_t iki_write_program_name_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_name_s, 0, IKI_WRITE_program_name_s_length); + const f_string_static_t iki_write_program_name_long_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_name_long_s, 0, IKI_WRITE_program_name_long_s_length); +#endif // _di_iki_write_eki_s_ + +#ifndef _di_iki_write_eki_setting_load_ + void iki_write_eki_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main) { + + if (!main) return; + + if (main->program.parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) return; + if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) return; + if (main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) return; + + f_number_unsigned_t index = 0; + f_console_parameter_t * const content = &main->program.parameters.array[iki_write_parameter_content_e]; + + if (main->program.parameters.array[iki_write_parameter_object_e].result & f_console_result_value_e) { + f_console_parameter_t * const object = &main->program.parameters.array[iki_write_parameter_object_e]; + f_string_dynamicss_t * const objectss = &main->setting.objectss; + + objectss->used = 0; + + main->setting.state.status = f_memory_arrays_resize(object->values.used, sizeof(f_string_dynamics_t), (void **) &objectss->array, &objectss->used, &objectss->size, &f_string_dynamicss_delete_callback); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); + + return; + } + + f_number_unsigned_t at_content = 0; + f_number_unsigned_t at_object = 0; + + // Construct the array without allocating any more memory by setting this as a static string (used > 0, size = 0). + for (index = 0; at_object < object->values.used; ) { + + main->setting.state.status = f_memory_array_increase(main->setting.state.step_small, sizeof(f_string_dynamic_t), (void **) &objectss->array[objectss->used].array, &objectss->array[objectss->used].used, &objectss->array[objectss->used].size); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_array_increase)); + + return; + } + + index = object->values.array[at_object]; + + objectss->array[objectss->used].array[objectss->array[objectss->used].used].string = main->program.parameters.arguments.array[index].string; + objectss->array[objectss->used].array[objectss->array[objectss->used].used].used = main->program.parameters.arguments.array[index].used; + objectss->array[objectss->used].array[objectss->array[objectss->used].used].size = 0; + ++objectss->array[objectss->used].used; + + if (++at_object >= object->locations.used || object->locations.array[at_object] > content->locations.array[at_content] || object->locations.array[at_object] == content->locations.array[at_content] && object->locations_sub.array[at_object] > content->locations_sub.array[at_content]) { + main->setting.state.status = f_memory_array_increase(main->setting.state.step_small, sizeof(f_string_dynamics_t), (void **) &objectss->array, &objectss->used, &objectss->size); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_array_increase)); + + return; + } + + objectss->used++; + ++at_content; + + + if (at_object < object->values.used && at_content >= content->values.used) { + iki_write_print_eki_error_objects_match_content(&main->program.error); + + main->setting.state.status = F_status_set_error(F_parameter); + + return; + } + } + } // for + + main->setting.flag |= iki_write_main_flag_object_d; + } + else if (main->program.parameters.array[iki_write_parameter_object_e].result & f_console_result_found_e) { + main->setting.state.status = F_status_set_error(F_parameter); + + fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, iki_write_long_object_s); + + return; + } + + if (main->program.parameters.array[iki_write_parameter_content_e].result & f_console_result_value_e) { + main->setting.contents.used = 0; + + main->setting.state.status = f_memory_arrays_resize(content->values.used, sizeof(f_string_dynamic_t), (void **) &main->setting.contents.array, &main->setting.contents.used, &main->setting.contents.size, &f_string_dynamics_delete_callback); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); + + return; + } + + // Construct the array without allocating any more memory by setting this as a static string (used > 0, size = 0). + for (index = 0; main->setting.contents.used < content->values.used; ) { + + index = content->values.array[main->setting.contents.used]; + + main->setting.contents.array[main->setting.contents.used].string = main->program.parameters.arguments.array[index].string; + main->setting.contents.array[main->setting.contents.used].used = main->program.parameters.arguments.array[index].used; + main->setting.contents.array[main->setting.contents.used++].size = 0; + } // for + + main->setting.flag |= iki_write_main_flag_content_d; + } + else if (main->program.parameters.array[iki_write_parameter_content_e].result & f_console_result_found_e) { + main->setting.state.status = F_status_set_error(F_parameter); + + fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, iki_write_long_content_s); + + return; + } + } +#endif // _di_iki_write_eki_setting_load_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/eki/common.h b/level_3/iki_write/c/eki/common.h new file mode 100644 index 0000000..b213ed3 --- /dev/null +++ b/level_3/iki_write/c/eki/common.h @@ -0,0 +1,66 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides the common data structures. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _iki_write_eki_common_h +#define _iki_write_eki_common_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The EKI write specific strings. + */ +#ifndef _di_iki_write_eki_s_ + #define IKI_WRITE_program_name_s "eki_write" + #define IKI_WRITE_program_name_long_s "EKI Write" + + #define IKI_WRITE_program_name_s_length 9 + #define IKI_WRITE_program_name_long_s_length 9 + + extern const f_string_static_t iki_write_program_name_s; + extern const f_string_static_t iki_write_program_name_long_s; +#endif // _di_iki_write_eki_s_ + +/** + * Perform the program setting load process for EKI. + * + * This prints error messages as appropriate. + * + * If either main or setting is NULL, then this immediately returns without doing anything. + * + * @param arguments + * The parameters passed to the process (often referred to as command line arguments). + * @param main + * The program and settings data. + * + * This alters main.setting.state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_console_parameter_process(). + * Errors (with error bit) from: f_file_stream_open(). + * Errors (with error bit) from: fll_program_parameter_process_context(). + * Errors (with error bit) from: fll_program_parameter_process_verbosity_standard(). + * + * @see f_console_parameter_process() + * @see f_file_stream_open() + * @see fll_program_parameter_process_context() + * @see fll_program_parameter_process_verbosity_standard() + */ +#ifndef _di_iki_write_eki_setting_load_ + extern void iki_write_eki_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main); +#endif // _di_iki_write_eki_setting_load_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_eki_common_h diff --git a/level_3/iki_write/c/eki/eki_write.c b/level_3/iki_write/c/eki/eki_write.c new file mode 100644 index 0000000..eafe507 --- /dev/null +++ b/level_3/iki_write/c/eki/eki_write.c @@ -0,0 +1,10 @@ +#include "eki_write.h" +#include "../main/iki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/eki/eki_write.h b/level_3/iki_write/c/eki/eki_write.h new file mode 100644 index 0000000..01f4c32 --- /dev/null +++ b/level_3/iki_write/c/eki/eki_write.h @@ -0,0 +1,76 @@ +/** + * FLL - Level 3 + * + * Project: FSS Read + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * This program provides EKI write. + */ +#ifndef _iki_write_eki_write_h +#define _iki_write_eki_write_h + +// Libc includes. +#include +#include +#include +#include +#include + +// FLL-0 includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _di_thread_support_ + #include +#endif // _di_thread_support_ + +// FLL-1 includes. +#include +#include +#include + +// FLL-2 includes. +#include +#include +#include +#include +#include + +// IKI Write includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_eki_write_h diff --git a/level_3/iki_write/c/eki/main.c b/level_3/iki_write/c/eki/main.c new file mode 100644 index 0000000..f410530 --- /dev/null +++ b/level_3/iki_write/c/eki/main.c @@ -0,0 +1,77 @@ +#include "eki_write.h" +#include "../main/iki_write.h" + +int main(const int argc, const f_string_t *argv, const f_string_t *envp) { + + iki_write_main_t data = iki_write_main_t_initialize; + + data.program.debug.flag |= iki_write_print_flag_debug_d | iki_write_print_flag_out_d; + data.program.error.flag |= iki_write_print_flag_error_d | iki_write_print_flag_out_d; + data.program.output.flag |= iki_write_print_flag_out_d; + data.program.message.flag |= iki_write_print_flag_message_d | iki_write_print_flag_out_d; + data.program.warning.flag |= iki_write_print_flag_warning_d | iki_write_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.callback.load_objects_content_pipe = &iki_write_eki_load_objects_content_pipe; + data.callback.print_help = &iki_write_eki_print_message_help; + data.callback.process_objects_content = &iki_write_eki_process_objects_content; + + f_console_parameter_t parameters[] = iki_write_console_parameter_t_initialize; + data.program.parameters.array = parameters; + data.program.parameters.used = iki_write_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_write_setting_load(arguments, &data, &iki_write_eki_setting_load); + } + + iki_write_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_write_thread_signal, (void *) &data); + + if (F_status_is_error(data.setting.state.status)) { + iki_write_print_error(&data.program.error, macro_iki_write_f(f_thread_create)); + } + else { + { + const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp); + + iki_write_setting_load(arguments, &data, &iki_write_eki_setting_load); + } + + if (!iki_write_signal_check(&data)) { + iki_write_main(&data); + } + + f_thread_cancel(id_signal); + f_thread_join(id_signal, 0); + } + } + #endif // _di_thread_support_ + + iki_write_main_delete(&data); + + fll_program_standard_set_down(&data.program); + + return F_status_is_error(data.setting.state.status) ? 1 : 0; +} diff --git a/level_3/iki_write/c/main/main.h b/level_3/iki_write/c/eki/main.h similarity index 83% rename from level_3/iki_write/c/main/main.h rename to level_3/iki_write/c/eki/main.h index 15e6e38..5dfff03 100644 --- a/level_3/iki_write/c/main/main.h +++ b/level_3/iki_write/c/eki/main.h @@ -6,10 +6,10 @@ * 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_write" program functionality in some manner. + * Anything that wants to include this should be providing the "fss_write" program functionality in some manner. */ -#ifndef _iki_write_main_h -#define _iki_write_main_h +#ifndef _iki_write_eki_main_h +#define _iki_write_eki_main_h #ifdef __cplusplus extern "C" { @@ -35,4 +35,4 @@ extern int main(const int argc, const f_string_t *argv, const f_string_t *envp); } // extern "C" #endif -#endif // _iki_write_main_h +#endif // _iki_write_eki_main_h diff --git a/level_3/iki_write/c/eki/print.c b/level_3/iki_write/c/eki/print.c new file mode 100644 index 0000000..b3201ef --- /dev/null +++ b/level_3/iki_write/c/eki/print.c @@ -0,0 +1,84 @@ +#include "eki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_write_print_eki_error_objects_match_content_ + f_status_t iki_write_print_eki_error_objects_match_content(fl_print_t * const print) { + + if (!print) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + fll_print_format("%[%QThe Objects must have a matching Content.%]%r", print->to, print->set->error, print->prefix, print->set->error, f_string_eol_s); + + return F_okay; + } +#endif // _di_iki_write_print_eki_error_objects_match_content_ + +#ifndef _di_iki_write_eki_print_error_objects_not_valid_ + f_status_t iki_write_eki_print_error_objects_not_valid(fl_print_t * const print, const f_string_statics_t objects) { + + if (!print) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + f_file_stream_lock(print->to); + + fl_print_format("%[%QOne or more of the Objects ", print->to, print->set->error, print->prefix); + + for (f_number_unsigned_t i = 0; i < objects.used; ++i) { + + fl_print_format("'%]", print->to, print->set->error); + fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, objects.array[i], print->set->notable); + fl_print_format("%['%Q", print->to, print->set->error); + + if (i + 1 < objects.used) { + fl_print_format(", ", print->to); + } + } // for + + fl_print_format(" is not a valid IKI Object (IKI Vocabulary).%]%r", print->to, print->set->error, f_string_eol_s); + + f_file_stream_unlock(print->to); + + return F_okay; + } +#endif // _di_iki_write_eki_print_error_objects_not_valid_ + +#ifndef _di_iki_write_eki_print_message_help_ + void iki_write_eki_print_message_help(fl_print_t * const print) { + + if (!print) return; + + f_file_stream_lock(print->to); + + fll_program_print_help_header(print, iki_write_program_name_long_s, iki_write_program_version_s); + + iki_write_print_message_help(print); + + f_print_dynamic_raw(f_string_eol_s, print->to); + + fll_program_print_help_usage(print, iki_write_program_name_s, f_string_empty_s); + + iki_write_print_message_help_note(print); + + iki_write_eki_print_message_help_note_pipe(print); + + f_file_stream_flush(print->to); + f_file_stream_unlock(print->to); + } +#endif // _di_iki_write_eki_print_message_help_ + +#ifndef _di_iki_write_eki_print_message_help_note_pipe_ + void iki_write_eki_print_message_help_note_pipe(fl_print_t * const print) { + + if (!print) return; + fl_print_format("%r When piping main to this program, a single form-feed character (\\f) (U+000C) must be used to separate each Object set from the Content.%r", print->to, f_string_eol_s, f_string_eol_s); + fl_print_format(" Each Object within an Object set is is separated by a single backspace character (\\b) (U+0008).%r", print->to, f_string_eol_s); + fl_print_format(" Each Object set must be followed by a Content.%r", print->to, f_string_eol_s); + } +#endif // _di_iki_write_eki_print_message_help_note_pipe_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/eki/print.h b/level_3/iki_write/c/eki/print.h new file mode 100644 index 0000000..69824e9 --- /dev/null +++ b/level_3/iki_write/c/eki/print.h @@ -0,0 +1,81 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _eki_write_eki_print_h +#define _eki_write_eki_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print error message about the Objects not having a matching Content. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_iki_write_print_eki_error_objects_match_content_ + extern f_status_t iki_write_print_eki_error_objects_match_content(fl_print_t * const print); +#endif // _di_iki_write_print_eki_error_objects_match_content_ + +/** + * Print error message about an Object not being valid. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + * @param objects + * The a strings representing the objects that are not valid. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_iki_write_print_eki_error_objects_not_valid_ + extern f_status_t iki_write_eki_print_error_objects_not_valid(fl_print_t * const print, const f_string_statics_t objects); +#endif // _di_iki_write_print_eki_error_objects_not_valid_ + +/** + * Print help for EKI write. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_write_eki_print_message_help_ + extern void iki_write_eki_print_message_help(fl_print_t * const print); +#endif // _di_iki_write_eki_print_message_help_ + +/** + * Print note pipe help for EKI write. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_write_eki_print_message_help_note_pipe_ + extern void iki_write_eki_print_message_help_note_pipe(fl_print_t * const print); +#endif // _di_iki_write_eki_print_message_help_note_pipe_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _eki_write_eki_print_h diff --git a/level_3/iki_write/c/eki/process.c b/level_3/iki_write/c/eki/process.c new file mode 100644 index 0000000..8316c4c --- /dev/null +++ b/level_3/iki_write/c/eki/process.c @@ -0,0 +1,127 @@ +#include "eki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_write_eki_load_objects_content_pipe_ + void iki_write_eki_load_objects_content_pipe(void * const void_main, const f_range_t range, bool * const object_ended) { + + if (!void_main) return; + + iki_write_main_t * const main = (iki_write_main_t *) void_main; + + if (!object_ended || !main->callback.process_objects_content) { + main->setting.state.status = F_status_set_error(F_parameter); + + iki_write_print_error(&main->program.error, macro_iki_write_f(iki_write_callback_load_objects_content_pipe)); + + return; + } + + if (*object_ended) { + main->cache.content.used = 0; + + if (main->cache.buffer.used) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.content); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_string_dynamic_partial_append_nulless)); + + *object_ended = F_false; + + return; + } + } + + main->callback.process_objects_content((void *) main, main->cache.objects, main->cache.content); + + if (F_status_is_error(main->setting.state.status)) { + *object_ended = F_false; + + return; + } + + fll_print_dynamic_raw(f_string_eol_s, main->program.output.to); + + *object_ended = F_false; + main->cache.objects.used = 0; + } + else { + f_range_t range_object = range; + + f_memory_array_increase(main->setting.state.step_small, sizeof(f_string_dynamic_t), (void **) &main->cache.objects.array, &main->cache.objects.used, &main->cache.objects.size); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_array_increase)); + + *object_ended = F_false; + + return; + } + + main->cache.objects.array[0].used = 0; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.objects.array[0]); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_string_dynamic_partial_append_nulless)); + + *object_ended = F_false; + + return; + } + + *object_ended = F_true; + ++main->cache.objects.used; + } + } +#endif // _di_iki_write_eki_load_objects_content_pipe_ + +#ifndef _di_iki_write_eki_process_objects_content_ + void iki_write_eki_process_objects_content(void * const void_main, const f_string_statics_t objects, const f_string_static_t content) { + + if (!void_main) return; + + iki_write_main_t * const main = (iki_write_main_t *) void_main; + + { + f_number_unsigned_t i = 0; + + for (; i < objects.used; ++i) { + if (objects.array[i].used) break; + } // for + + if (!objects.used || i == objects.used) { + main->setting.state.status = F_status_set_error(F_failure); + + fll_program_print_error_missing_variable_not_zero(&main->program.error, iki_write_object_s); + + return; + } + } + + main->cache.iki.used = 0; + + f_iki_eki_write(objects, content, main->setting.quote, &main->cache.iki, &main->setting.state); + + if (F_status_is_error(main->setting.state.status)) { + if (F_status_set_fine(main->setting.state.status) == F_syntax) { + iki_write_eki_print_error_objects_not_valid(&main->program.error, objects); + } + else { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_iki_write)); + } + + return; + } + + f_print_dynamic(main->cache.iki, main->program.output.to); + + main->setting.state.status = F_okay; + } +#endif // _di_iki_write_eki_process_objects_content_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/eki/process.h b/level_3/iki_write/c/eki/process.h new file mode 100644 index 0000000..e9fadc5 --- /dev/null +++ b/level_3/iki_write/c/eki/process.h @@ -0,0 +1,77 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides the process functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _iki_write_eki_process_h +#define _iki_write_eki_process_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Load the Objects and Content from the given pipe information. + * + * This function prints errors. + * + * @param main + * The program and settings data. + * + * Must not be NULL. + * + * This alters main.setting.state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_iki_write(). + * + * F_failure (with error bit) for any other failure. + * @param objects + * The objects to process and print. + * @param content + * The content to process and print. + * + * @see f_iki_write() + */ +#ifndef _di_iki_write_eki_load_objects_content_pipe_ + extern void iki_write_eki_load_objects_content_pipe(void * const main, const f_range_t range, bool * const object_ended); +#endif // _di_iki_write_eki_load_objects_content_pipe_ + +/** + * Process a given object and content, printing it. + * + * This function prints errors. + * + * @param main + * The program and settings data. + * + * Must not be NULL. + * + * This alters main.setting.state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_iki_eki_write(). + * + * F_failure (with error bit) for any other failure. + * @param objects + * The objects to process and print. + * @param content + * The content to process and print. + * + * @see f_iki_eki_write() + */ +#ifndef _di_iki_write_eki_process_objects_content_ + extern void iki_write_eki_process_objects_content(void * const main, const f_string_statics_t objects, const f_string_static_t content); +#endif // _di_iki_write_eki_process_objects_content_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_eki_process_h diff --git a/level_3/iki_write/c/iki/common.c b/level_3/iki_write/c/iki/common.c new file mode 100644 index 0000000..bd9b0a1 --- /dev/null +++ b/level_3/iki_write/c/iki/common.c @@ -0,0 +1,102 @@ +#include "iki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_write_iki_s_ + const f_string_static_t iki_write_program_name_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_name_s, 0, IKI_WRITE_program_name_s_length); + const f_string_static_t iki_write_program_name_long_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_name_long_s, 0, IKI_WRITE_program_name_long_s_length); +#endif // _di_iki_write_iki_s_ + +#ifndef _di_iki_write_iki_setting_load_ + void iki_write_iki_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main) { + + if (!main) return; + + if (main->program.parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) return; + if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) return; + if (main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) return; + + f_number_unsigned_t index = 0; + + if (main->program.parameters.array[iki_write_parameter_object_e].result & f_console_result_value_e) { + f_number_unsigneds_t * const values = &main->program.parameters.array[iki_write_parameter_object_e].values; + + main->setting.objectss.used = 0; + + main->setting.state.status = f_memory_arrays_resize(values->used, sizeof(f_string_dynamics_t), (void **) &main->setting.objectss.array, &main->setting.objectss.used, &main->setting.objectss.size, &f_string_dynamicss_delete_callback); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); + + return; + } + + // Construct the array without allocating any more memory by setting this as a static string (used > 0, size = 0). + for (index = 0; main->setting.objectss.used < values->used; ) { + + main->setting.state.status = f_memory_arrays_resize(1, sizeof(f_string_dynamic_t), (void **) &main->setting.objectss.array[main->setting.objectss.used].array, &main->setting.objectss.array[main->setting.objectss.used].used, &main->setting.objectss.array[main->setting.objectss.used].size, &f_string_dynamics_delete_callback); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); + + return; + } + + index = values->array[main->setting.objectss.used]; + + main->setting.objectss.array[main->setting.objectss.used].array[0].string = main->program.parameters.arguments.array[index].string; + main->setting.objectss.array[main->setting.objectss.used].array[0].used = main->program.parameters.arguments.array[index].used; + main->setting.objectss.array[main->setting.objectss.used].array[0].size = 0; + main->setting.objectss.array[main->setting.objectss.used++].used = 1; + } // for + + main->setting.flag |= iki_write_main_flag_object_d; + } + else if (main->program.parameters.array[iki_write_parameter_object_e].result & f_console_result_found_e) { + main->setting.state.status = F_status_set_error(F_parameter); + + fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, iki_write_long_object_s); + + return; + } + + if (main->program.parameters.array[iki_write_parameter_content_e].result & f_console_result_value_e) { + f_number_unsigneds_t * const values = &main->program.parameters.array[iki_write_parameter_content_e].values; + + main->setting.contents.used = 0; + + main->setting.state.status = f_memory_arrays_resize(values->used, sizeof(f_string_dynamic_t), (void **) &main->setting.contents.array, &main->setting.contents.used, &main->setting.contents.size, &f_string_dynamics_delete_callback); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); + + return; + } + + // Construct the array without allocating any more memory by setting this as a static string (used > 0, size = 0). + for (index = 0; main->setting.contents.used < values->used; ) { + + index = values->array[main->setting.contents.used]; + + main->setting.contents.array[main->setting.contents.used].string = main->program.parameters.arguments.array[index].string; + main->setting.contents.array[main->setting.contents.used].used = main->program.parameters.arguments.array[index].used; + main->setting.contents.array[main->setting.contents.used++].size = 0; + } // for + + main->setting.flag |= iki_write_main_flag_content_d; + } + else if (main->program.parameters.array[iki_write_parameter_content_e].result & f_console_result_found_e) { + main->setting.state.status = F_status_set_error(F_parameter); + + fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, iki_write_long_content_s); + + return; + } + } +#endif // _di_iki_write_iki_setting_load_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/iki/common.h b/level_3/iki_write/c/iki/common.h new file mode 100644 index 0000000..c4afb16 --- /dev/null +++ b/level_3/iki_write/c/iki/common.h @@ -0,0 +1,66 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides the common data structures. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _iki_write_iki_common_h +#define _iki_write_iki_common_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The IKI write specific strings. + */ +#ifndef _di_iki_write_iki_s_ + #define IKI_WRITE_program_name_s "iki_write" + #define IKI_WRITE_program_name_long_s "IKI Write" + + #define IKI_WRITE_program_name_s_length 9 + #define IKI_WRITE_program_name_long_s_length 9 + + extern const f_string_static_t iki_write_program_name_s; + extern const f_string_static_t iki_write_program_name_long_s; +#endif // _di_iki_write_iki_s_ + +/** + * Perform the program setting load process for IKI. + * + * This prints error messages as appropriate. + * + * If either main or setting is NULL, then this immediately returns without doing anything. + * + * @param arguments + * The parameters passed to the process (often referred to as command line arguments). + * @param main + * The program and settings data. + * + * This alters main.setting.state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_console_parameter_process(). + * Errors (with error bit) from: f_file_stream_open(). + * Errors (with error bit) from: fll_program_parameter_process_context(). + * Errors (with error bit) from: fll_program_parameter_process_verbosity_standard(). + * + * @see f_console_parameter_process() + * @see f_file_stream_open() + * @see fll_program_parameter_process_context() + * @see fll_program_parameter_process_verbosity_standard() + */ +#ifndef _di_iki_write_iki_setting_load_ + extern void iki_write_iki_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main); +#endif // _di_iki_write_iki_setting_load_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_iki_common_h diff --git a/level_3/iki_write/c/iki/iki_write.c b/level_3/iki_write/c/iki/iki_write.c new file mode 100644 index 0000000..42626dd --- /dev/null +++ b/level_3/iki_write/c/iki/iki_write.c @@ -0,0 +1,10 @@ +#include "iki_write.h" +#include "../main/iki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/iki/iki_write.h b/level_3/iki_write/c/iki/iki_write.h new file mode 100644 index 0000000..f2f2c45 --- /dev/null +++ b/level_3/iki_write/c/iki/iki_write.h @@ -0,0 +1,76 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * This program provides IKI write. + */ +#ifndef _iki_write_iki_write_h +#define _iki_write_iki_write_h + +// Libc includes. +#include +#include +#include +#include +#include + +// FLL-0 includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _di_thread_support_ + #include +#endif // _di_thread_support_ + +// FLL-1 includes. +#include +#include +#include + +// FLL-2 includes. +#include +#include +#include +#include +#include + +// IKI Write includes. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_iki_write_h diff --git a/level_3/iki_write/c/main/main.c b/level_3/iki_write/c/iki/main.c similarity index 84% rename from level_3/iki_write/c/main/main.c rename to level_3/iki_write/c/iki/main.c index 68f6e87..a068605 100644 --- a/level_3/iki_write/c/main/main.c +++ b/level_3/iki_write/c/iki/main.c @@ -1,4 +1,5 @@ #include "iki_write.h" +#include "../main/iki_write.h" int main(const int argc, const f_string_t *argv, const f_string_t *envp) { @@ -15,6 +16,10 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { data.program.output.custom = (void *) &data; data.program.warning.custom = (void *) &data; + data.callback.load_objects_content_pipe = &iki_write_iki_load_objects_content_pipe; + data.callback.print_help = &iki_write_iki_print_message_help; + data.callback.process_objects_content = &iki_write_iki_process_objects_content; + f_console_parameter_t parameters[] = iki_write_console_parameter_t_initialize; data.program.parameters.array = parameters; data.program.parameters.used = iki_write_parameter_total_d; @@ -32,7 +37,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { { const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp); - iki_write_setting_load(arguments, &data); + iki_write_setting_load(arguments, &data, &iki_write_iki_setting_load); } iki_write_main(&data); @@ -51,7 +56,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { { const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp); - iki_write_setting_load(arguments, &data); + iki_write_setting_load(arguments, &data, &iki_write_iki_setting_load); } if (!iki_write_signal_check(&data)) { diff --git a/level_3/iki_write/c/iki/main.h b/level_3/iki_write/c/iki/main.h new file mode 100644 index 0000000..a316d96 --- /dev/null +++ b/level_3/iki_write/c/iki/main.h @@ -0,0 +1,38 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * 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 "fss_write" program functionality in some manner. + */ +#ifndef _iki_write_iki_main_h +#define _iki_write_iki_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_write_iki_main_h diff --git a/level_3/iki_write/c/iki/print.c b/level_3/iki_write/c/iki/print.c new file mode 100644 index 0000000..68788c4 --- /dev/null +++ b/level_3/iki_write/c/iki/print.c @@ -0,0 +1,61 @@ +#include "iki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_write_iki_print_error_object_not_valid_ + f_status_t iki_write_iki_print_error_object_not_valid(fl_print_t * const print, const f_string_static_t object) { + + if (!print) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + f_file_stream_lock(print->to); + + fl_print_format("%[%QThe Object '%]", print->to, print->set->error, print->prefix, print->set->error); + fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, object, print->set->notable); + fl_print_format("%[' is not a valid IKI Object (IKI Vocabulary).%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); + + f_file_stream_unlock(print->to); + + return F_okay; + } +#endif // _di_iki_write_iki_print_error_object_not_valid_ + +#ifndef _di_iki_write_iki_print_message_help_ + void iki_write_iki_print_message_help(fl_print_t * const print) { + + if (!print) return; + + f_file_stream_lock(print->to); + + fll_program_print_help_header(print, iki_write_program_name_long_s, iki_write_program_version_s); + + iki_write_print_message_help(print); + + f_print_dynamic_raw(f_string_eol_s, print->to); + + fll_program_print_help_usage(print, iki_write_program_name_s, f_string_empty_s); + + iki_write_print_message_help_note(print); + + iki_write_iki_print_message_help_note_pipe(print); + + f_file_stream_flush(print->to); + f_file_stream_unlock(print->to); + } +#endif // _di_iki_write_iki_print_message_help_ + +#ifndef _di_iki_write_iki_print_message_help_note_pipe_ + void iki_write_iki_print_message_help_note_pipe(fl_print_t * const print) { + + if (!print) return; + + fl_print_format("%r When piping main to this program, a single form-feed character (\\f) (U+000C) must be used to separate each Object from each Content.%r", print->to, f_string_eol_s, f_string_eol_s); + fl_print_format(" Each Object must be followed by a Content.%r", print->to, f_string_eol_s); + } +#endif // _di_iki_write_iki_print_message_help_note_pipe_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/iki/print.h b/level_3/iki_write/c/iki/print.h new file mode 100644 index 0000000..a75e0b6 --- /dev/null +++ b/level_3/iki_write/c/iki/print.h @@ -0,0 +1,63 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _iki_write_iki_print_h +#define _iki_write_iki_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print error message about an Object not being valid. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + * @param object + * The a string representing the object that is not valid. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + */ +#ifndef _di_iki_write_iki_print_error_object_not_valid_ + extern f_status_t iki_write_iki_print_error_object_not_valid(fl_print_t * const print, const f_string_static_t object); +#endif // _di_iki_write_iki_print_error_object_not_valid_ + +/** + * Print help for IKI write. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_write_iki_print_message_help_ + extern void iki_write_iki_print_message_help(fl_print_t * const print); +#endif // _di_iki_write_iki_print_message_help_ + +/** + * Print note pipe help for IKI write. + * + * @param print + * The output structure to print to. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_write_iki_print_message_help_note_pipe_ + extern void iki_write_iki_print_message_help_note_pipe(fl_print_t * const print); +#endif // _di_iki_write_iki_print_message_help_note_pipe_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_iki_print_h diff --git a/level_3/iki_write/c/iki/process.c b/level_3/iki_write/c/iki/process.c new file mode 100644 index 0000000..8ff02b4 --- /dev/null +++ b/level_3/iki_write/c/iki/process.c @@ -0,0 +1,118 @@ +#include "iki_write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_write_iki_load_objects_content_pipe_ + void iki_write_iki_load_objects_content_pipe(void * const void_main, const f_range_t range, bool * const object_ended) { + + if (!void_main) return; + + iki_write_main_t * const main = (iki_write_main_t *) void_main; + + if (!object_ended || !main->callback.process_objects_content) { + main->setting.state.status = F_status_set_error(F_parameter); + + iki_write_print_error(&main->program.error, macro_iki_write_f(iki_write_callback_load_objects_content_pipe)); + + return; + } + + if (*object_ended) { + main->cache.content.used = 0; + + if (main->cache.buffer.used) { + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.content); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_string_dynamic_partial_append_nulless)); + + *object_ended = F_false; + + return; + } + } + + main->callback.process_objects_content((void *) main, main->cache.objects, main->cache.content); + + if (F_status_is_error(main->setting.state.status)) { + *object_ended = F_false; + + return; + } + + fll_print_dynamic_raw(f_string_eol_s, main->program.output.to); + + *object_ended = F_false; + main->cache.objects.used = 0; + } + else { + f_memory_array_increase(main->setting.state.step_small, sizeof(f_string_dynamic_t), (void **) &main->cache.objects.array, &main->cache.objects.used, &main->cache.objects.size); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_array_increase)); + + *object_ended = F_false; + + return; + } + + main->cache.objects.array[main->cache.objects.used].used = 0; + + main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.objects.array[0]); + + if (F_status_is_error(main->setting.state.status)) { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_string_dynamic_partial_append_nulless)); + + *object_ended = F_false; + + return; + } + + *object_ended = F_true; + ++main->cache.objects.used; + } + } +#endif // _di_iki_write_iki_load_objects_content_pipe_ + +#ifndef _di_iki_write_iki_process_objects_content_ + void iki_write_iki_process_objects_content(void * const void_main, const f_string_statics_t objects, const f_string_static_t content) { + + if (!void_main) return; + + iki_write_main_t * const main = (iki_write_main_t *) void_main; + + // Only the first index is used because IKI only supports one Object (Vocabulary). + if (!objects.used || !objects.array[0].used) { + main->setting.state.status = F_status_set_error(F_failure); + + fll_program_print_error_missing_variable_not_zero(&main->program.error, iki_write_object_s); + + return; + } + + main->cache.iki.used = 0; + + f_iki_write(objects.array[0], content, main->setting.quote, &main->cache.iki, &main->setting.state); + + if (F_status_is_error(main->setting.state.status)) { + if (F_status_set_fine(main->setting.state.status) == F_syntax) { + iki_write_iki_print_error_object_not_valid(&main->program.error, objects.array[0]); + } + else { + iki_write_print_error(&main->program.error, macro_iki_write_f(f_iki_write)); + } + + return; + } + + f_print_dynamic(main->cache.iki, main->program.output.to); + + main->setting.state.status = F_okay; + } +#endif // _di_iki_write_iki_process_objects_content_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_write/c/iki/process.h b/level_3/iki_write/c/iki/process.h new file mode 100644 index 0000000..30da911 --- /dev/null +++ b/level_3/iki_write/c/iki/process.h @@ -0,0 +1,77 @@ +/** + * FLL - Level 3 + * + * Project: IKI Write + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides the process functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _iki_write_iki_process_h +#define _iki_write_iki_process_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Load the Objects and Content from the given pipe information. + * + * This function prints errors. + * + * @param main + * The program and settings data. + * + * Must not be NULL. + * + * This alters main.setting.state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_iki_write(). + * + * F_failure (with error bit) for any other failure. + * @param objects + * The objects to process and print. + * @param content + * The content to process and print. + * + * @see f_iki_write() + */ +#ifndef _di_iki_write_iki_load_objects_content_pipe_ + extern void iki_write_iki_load_objects_content_pipe(void * const main, const f_range_t range, bool * const object_ended); +#endif // _di_iki_write_iki_load_objects_content_pipe_ + +/** + * Process a given object and content, printing it. + * + * This function prints errors. + * + * @param main + * The program and settings data. + * + * Must not be NULL. + * + * This alters main.setting.state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_iki_write(). + * + * F_failure (with error bit) for any other failure. + * @param objects + * The objects to process and print. + * @param content + * The content to process and print. + * + * @see f_iki_write() + */ +#ifndef _di_iki_write_iki_process_objects_content_ + extern void iki_write_iki_process_objects_content(void * const main, const f_string_statics_t objects, const f_string_static_t content); +#endif // _di_iki_write_iki_process_objects_content_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _iki_write_iki_process_h diff --git a/level_3/iki_write/c/main/common.c b/level_3/iki_write/c/main/common.c index cf62d63..2ef9099 100644 --- a/level_3/iki_write/c/main/common.c +++ b/level_3/iki_write/c/main/common.c @@ -5,7 +5,7 @@ extern "C" { #endif #ifndef _di_iki_write_setting_load_ - void iki_write_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main) { + void iki_write_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main, void (*callback)(const f_console_arguments_t arguments, iki_write_main_t * const main)) { if (!main) return; @@ -41,6 +41,17 @@ extern "C" { main->program.output.to.stream = F_type_output_d; main->program.output.to.flag = F_file_flag_create_d | F_file_flag_write_only_d | F_file_flag_append_d; + if (callback) { + callback(arguments, main); + if (F_status_is_error(main->setting.state.status)) return; + + if (main->setting.state.status == F_done) { + main->setting.state.status = F_okay; + + return; + } + } + if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) { main->setting.flag |= iki_write_main_flag_help_d; @@ -98,72 +109,6 @@ extern "C" { return; } - if (main->program.parameters.array[iki_write_parameter_object_e].result & f_console_result_value_e) { - f_number_unsigneds_t * const values = &main->program.parameters.array[iki_write_parameter_object_e].values; - - main->setting.objects.used = 0; - - main->setting.state.status = f_memory_arrays_resize(values->used, sizeof(f_string_dynamic_t), (void **) &main->setting.objects.array, &main->setting.objects.used, &main->setting.objects.size, &f_string_dynamics_delete_callback); - - if (F_status_is_error(main->setting.state.status)) { - iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); - - return; - } - - // Construct the array without allocating any more memory by setting this as a static string (used > 0, size = 0). - for (f_number_unsigned_t index = 0; main->setting.objects.used < values->used; ) { - - index = values->array[main->setting.objects.used]; - - main->setting.objects.array[main->setting.objects.used].string = main->program.parameters.arguments.array[index].string; - main->setting.objects.array[main->setting.objects.used].used = main->program.parameters.arguments.array[index].used; - main->setting.objects.array[main->setting.objects.used++].size = 0; - } // for - - main->setting.flag |= iki_write_main_flag_object_d; - } - else if (main->program.parameters.array[iki_write_parameter_object_e].result & f_console_result_found_e) { - main->setting.state.status = F_status_set_error(F_parameter); - - fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, iki_write_long_object_s); - - return; - } - - if (main->program.parameters.array[iki_write_parameter_content_e].result & f_console_result_value_e) { - f_number_unsigneds_t * const values = &main->program.parameters.array[iki_write_parameter_content_e].values; - - main->setting.contents.used = 0; - - main->setting.state.status = f_memory_arrays_resize(values->used, sizeof(f_string_dynamic_t), (void **) &main->setting.contents.array, &main->setting.contents.used, &main->setting.contents.size, &f_string_dynamics_delete_callback); - - if (F_status_is_error(main->setting.state.status)) { - iki_write_print_error(&main->program.error, macro_iki_write_f(f_memory_arrays_resize)); - - return; - } - - // Construct the array without allocating any more memory by setting this as a static string (used > 0, size = 0). - for (f_number_unsigned_t index = 0; main->setting.contents.used < values->used; ) { - - index = values->array[main->setting.contents.used]; - - main->setting.contents.array[main->setting.contents.used].string = main->program.parameters.arguments.array[index].string; - main->setting.contents.array[main->setting.contents.used].used = main->program.parameters.arguments.array[index].used; - main->setting.contents.array[main->setting.contents.used++].size = 0; - } // for - - main->setting.flag |= iki_write_main_flag_content_d; - } - else if (main->program.parameters.array[iki_write_parameter_content_e].result & f_console_result_found_e) { - main->setting.state.status = F_status_set_error(F_parameter); - - fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, iki_write_long_content_s); - - return; - } - if (!(main->program.pipe & fll_program_data_pipe_input_e) && !(main->setting.flag & (iki_write_main_flag_content_d | iki_write_parameter_object_e))) { main->setting.state.status = F_status_set_error(F_parameter); diff --git a/level_3/iki_write/c/main/common.h b/level_3/iki_write/c/main/common.h index 4dc2388..aff245c 100644 --- a/level_3/iki_write/c/main/common.h +++ b/level_3/iki_write/c/main/common.h @@ -35,6 +35,10 @@ extern "C" { * Errors (with error bit) from: f_file_stream_open(). * Errors (with error bit) from: fll_program_parameter_process_context(). * Errors (with error bit) from: fll_program_parameter_process_verbosity_standard(). + * @param callback + * (optional) Designate a function to call after performing the initial processing, but before printing help. + * If the function returns F_done, then this function immediately returns, resetting status to F_okay. + * Set to NULL to disable. * * @see f_console_parameter_process() * @see f_file_stream_open() @@ -42,7 +46,7 @@ extern "C" { * @see fll_program_parameter_process_verbosity_standard() */ #ifndef _di_iki_write_setting_load_ - extern void iki_write_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main); + extern void iki_write_setting_load(const f_console_arguments_t arguments, iki_write_main_t * const main, void (*callback)(const f_console_arguments_t arguments, iki_write_main_t * const main)); #endif // _di_iki_write_setting_load_ #ifdef __cplusplus diff --git a/level_3/iki_write/c/main/common/print.c b/level_3/iki_write/c/main/common/print.c index d22642b..9f1b546 100644 --- a/level_3/iki_write/c/main/common/print.c +++ b/level_3/iki_write/c/main/common/print.c @@ -10,12 +10,14 @@ extern "C" { "f_file_read", "f_file_stream_open", "f_iki_write", + "f_memory_array_increase", "f_memory_arrays_resize", "f_string_dynamic_partial_append_nulless", "f_string_dynamic_seek_to", "f_thread_create", "fll_program_parameter_process_context_standard", "fll_program_parameter_process_verbosity_standard", + "iki_write_callback_load_objects_content_pipe", }; #endif // _di_iki_write_f_a_ diff --git a/level_3/iki_write/c/main/common/print.h b/level_3/iki_write/c/main/common/print.h index bba8c09..c4cfb9d 100644 --- a/level_3/iki_write/c/main/common/print.h +++ b/level_3/iki_write/c/main/common/print.h @@ -43,12 +43,14 @@ extern "C" { iki_write_f_f_file_read_e, iki_write_f_f_file_stream_open_e, iki_write_f_f_iki_write_e, + iki_write_f_f_memory_array_increase_e, iki_write_f_f_memory_arrays_resize_e, iki_write_f_f_string_dynamic_partial_append_nulless_e, iki_write_f_f_string_dynamic_seek_to_e, iki_write_f_f_thread_create_e, iki_write_f_fll_program_parameter_process_context_standard_e, iki_write_f_fll_program_parameter_process_verbosity_standard_e, + iki_write_f_iki_write_callback_load_objects_content_pipe_e, }; // enum #endif // _di_iki_write_f_e_ diff --git a/level_3/iki_write/c/main/common/string.c b/level_3/iki_write/c/main/common/string.c index eb4f925..24ac386 100644 --- a/level_3/iki_write/c/main/common/string.c +++ b/level_3/iki_write/c/main/common/string.c @@ -8,11 +8,6 @@ extern "C" { const f_string_static_t iki_write_program_version_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_version_s, 0, IKI_WRITE_program_version_s_length); #endif // _di_iki_write_program_version_s_ -#ifndef _di_iki_write_program_name_s_ - const f_string_static_t iki_write_program_name_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_name_s, 0, IKI_WRITE_program_name_s_length); - const f_string_static_t iki_write_program_name_long_s = macro_f_string_static_t_initialize_1(IKI_WRITE_program_name_long_s, 0, IKI_WRITE_program_name_long_s_length); -#endif // _di_iki_write_program_name_s_ - #ifndef _di_iki_write_s_ const f_string_static_t iki_write_object_s = macro_f_string_static_t_initialize_1(IKI_WRITE_object_s, 0, IKI_WRITE_object_s_length); #endif // _di_iki_write_s_ diff --git a/level_3/iki_write/c/main/common/string.h b/level_3/iki_write/c/main/common/string.h index c1468f5..17058fc 100644 --- a/level_3/iki_write/c/main/common/string.h +++ b/level_3/iki_write/c/main/common/string.h @@ -46,20 +46,6 @@ extern "C" { #endif // _di_iki_write_program_version_s_ /** - * The program name. - */ -#ifndef _di_iki_write_program_name_s_ - #define IKI_WRITE_program_name_s "iki_write" - #define IKI_WRITE_program_name_long_s "IKI Write" - - #define IKI_WRITE_program_name_s_length 9 - #define IKI_WRITE_program_name_long_s_length 9 - - extern const f_string_static_t iki_write_program_name_s; - extern const f_string_static_t iki_write_program_name_long_s; -#endif // _di_iki_write_program_name_s_ - -/** * Special strings used by this program. */ #ifndef _di_iki_write_s_ @@ -68,6 +54,10 @@ extern "C" { #define IKI_WRITE_object_s_length 6 extern const f_string_static_t iki_write_object_s; + + // These are defined by the individual programs. + extern const f_string_static_t iki_write_program_name_s; + extern const f_string_static_t iki_write_program_name_long_s; #endif // _di_iki_write_s_ /** diff --git a/level_3/iki_write/c/main/common/type.c b/level_3/iki_write/c/main/common/type.c index 11f9da4..c91ad31 100644 --- a/level_3/iki_write/c/main/common/type.c +++ b/level_3/iki_write/c/main/common/type.c @@ -12,7 +12,8 @@ extern "C" { 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->content.string, &cache->content.used, &cache->content.size); f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->iki.string, &cache->iki.used, &cache->iki.size); - f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->object.string, &cache->object.used, &cache->object.size); + + f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &cache->objects.array, &cache->objects.used, &cache->objects.size, &f_string_dynamics_delete_callback); } #endif // _di_iki_write_cache_delete_ @@ -33,8 +34,8 @@ extern "C" { if (!setting) return; - f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &setting->objects.array, &setting->objects.used, &setting->objects.size, &f_string_dynamics_delete_callback); f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &setting->contents.array, &setting->contents.used, &setting->contents.size, &f_string_dynamics_delete_callback); + f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &setting->objectss.array, &setting->objectss.used, &setting->objectss.size, &f_string_dynamicss_delete_callback); } #endif // _di_iki_write_setting_delete_ diff --git a/level_3/iki_write/c/main/common/type.h b/level_3/iki_write/c/main/common/type.h index 35d4f69..9c2babc 100644 --- a/level_3/iki_write/c/main/common/type.h +++ b/level_3/iki_write/c/main/common/type.h @@ -17,19 +17,45 @@ extern "C" { #endif /** + * The IKI write callbacks. + * + * load_objects_content_pipe: Load the Objects and Content from the pipe. + * + * print_help: Print the main help message. + * + * process_objects_content: Process an Objects and Content set. + */ +#ifndef _di_iki_write_callback_t_ + typedef struct { + void (*load_objects_content_pipe)(void * const main, const f_range_t range, bool * const object_ended); + + 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); + } iki_write_callback_t; + + #define iki_write_callback_t_initialize \ + { \ + 0, \ + 0, \ + 0, \ + } +#endif // _di_iki_write_callback_t_ + +/** * The iki write main program cache. * * buffer: A buffer used during processing the file. * content: A buffer used to hold a Content during processing. * iki: A buffer used for writing the IKI during processing. - * object: A buffer used to hold an Object during processing. + * objects: A buffer used to hold Objects during processing. */ #ifndef _di_iki_write_setting_t_ typedef struct { f_string_dynamic_t buffer; f_string_dynamic_t content; f_string_dynamic_t iki; - f_string_dynamic_t object; + f_string_dynamics_t objects; } iki_write_cache_t; #define iki_write_cache_t_initialize \ @@ -37,7 +63,7 @@ extern "C" { f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ + f_string_dynamics_t_initialize, \ } #endif // _di_iki_write_cache_t_ @@ -54,8 +80,8 @@ extern "C" { * * quote: This holds the quote used during processing. * - * objects: An array of objects passed as values to the "--object" parameter. - * contents: An array of objects passed as values to the "--content" parameter and must match the length of objects. + * contents: An array of content passed as values to the "--content" parameter and must match the length of objects. + * objectss: An array of an array of objects passed as values to the "--object" parameter. */ #ifndef _di_iki_write_setting_t_ typedef struct { @@ -66,8 +92,8 @@ extern "C" { f_string_static_t quote; - f_string_dynamics_t objects; f_string_dynamics_t contents; + f_string_dynamicss_t objectss; } iki_write_setting_t; #define iki_write_setting_t_initialize \ @@ -77,7 +103,7 @@ extern "C" { f_state_t_initialize, \ f_string_static_t_initialize, \ f_string_dynamics_t_initialize, \ - f_string_dynamics_t_initialize, \ + f_string_dynamicss_t_initialize, \ } #endif // _di_iki_write_setting_t_ @@ -91,6 +117,7 @@ extern "C" { #ifndef _di_iki_write_main_t_ typedef struct { iki_write_cache_t cache; + iki_write_callback_t callback; fll_program_data_t program; iki_write_setting_t setting; } iki_write_main_t; @@ -98,6 +125,7 @@ extern "C" { #define iki_write_main_t_initialize \ { \ iki_write_cache_t_initialize, \ + iki_write_callback_t_initialize, \ fll_program_data_t_initialize, \ iki_write_setting_t_initialize, \ } diff --git a/level_3/iki_write/c/main/iki_write.c b/level_3/iki_write/c/main/iki_write.c index f5c0ea6..b6389bd 100644 --- a/level_3/iki_write/c/main/iki_write.c +++ b/level_3/iki_write/c/main/iki_write.c @@ -13,7 +13,9 @@ extern "C" { if (main->setting.flag & iki_write_main_flag_version_copyright_help_d) { if (main->setting.flag & iki_write_main_flag_help_d) { - iki_write_print_message_help(&main->program.message); + if (main->callback.print_help) { + main->callback.print_help(&main->program.output); + } } else if (main->setting.flag & iki_write_main_flag_version_d) { fll_program_print_version(&main->program.message, iki_write_program_version_s); @@ -36,8 +38,8 @@ extern "C" { pipe.size_read = 1; main->cache.buffer.used = 0; - main->cache.object.used = 0; main->cache.content.used = 0; + main->cache.objects.used = 0; range.start = 0; @@ -108,47 +110,9 @@ extern "C" { range.stop = range.start - 1; range.start = previous; - if (object_ended) { - main->cache.content.used = 0; - - if (main->cache.buffer.used) { - main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.content); - - if (F_status_is_error(main->setting.state.status)) { - iki_write_print_error(&main->program.error, macro_iki_write_f(f_string_dynamic_partial_append_nulless)); - - object_ended = F_false; - - break; - } - } - - iki_write_process(main, main->cache.object, main->cache.content); - - if (F_status_is_error(main->setting.state.status)) { - object_ended = F_false; - - break; - } - - fll_print_dynamic_raw(f_string_eol_s, main->program.output.to); - - object_ended = F_false; - } - else { - main->cache.object.used = 0; - - main->setting.state.status = f_string_dynamic_partial_append_nulless(main->cache.buffer, range, &main->cache.object); - - if (F_status_is_error(main->setting.state.status)) { - iki_write_print_error(&main->program.error, macro_iki_write_f(f_string_dynamic_partial_append_nulless)); - - object_ended = F_false; - - break; - } - - object_ended = F_true; + if (main->callback.load_objects_content_pipe) { + main->callback.load_objects_content_pipe((void *) main, range, &object_ended); + if (F_status_is_error(main->setting.state.status)) break; } // Restore the range, positioned after the new line. @@ -163,7 +127,7 @@ extern "C" { } while (status != F_okay_eof || main->cache.buffer.used || object_ended); - if (object_ended) { + if (F_status_is_error_not(main->setting.state.status) && object_ended) { main->setting.state.status = F_status_set_error(F_parameter); fll_program_print_error_pipe_object_without_content(&main->program.error); @@ -171,7 +135,7 @@ extern "C" { } if (F_status_is_error_not(main->setting.state.status) && F_status_set_fine(main->setting.state.status) != F_interrupt) { - for (f_number_unsigned_t i = 0; i < main->setting.objects.used; ++i) { + for (f_number_unsigned_t i = 0; i < main->setting.objectss.used; ++i) { if (!((++main->program.signal_check) % iki_write_signal_check_d)) { if (fll_program_standard_signal_received(&main->program)) { @@ -183,7 +147,7 @@ extern "C" { main->program.signal_check = 0; } - iki_write_process(main, main->setting.objects.array[i], main->setting.contents.array[i]); + main->callback.process_objects_content((void *) main, main->setting.objectss.array[i], main->setting.contents.array[i]); if (F_status_is_error(main->setting.state.status)) break; fll_print_dynamic_raw(f_string_eol_s, main->program.output.to); diff --git a/level_3/iki_write/c/main/iki_write.h b/level_3/iki_write/c/main/iki_write.h index 192f656..c46b6ef 100644 --- a/level_3/iki_write/c/main/iki_write.h +++ b/level_3/iki_write/c/main/iki_write.h @@ -64,7 +64,6 @@ #include #include #include -#include #include #include diff --git a/level_3/iki_write/c/main/print/error.c b/level_3/iki_write/c/main/print/error.c index fa389dc..a234f34 100644 --- a/level_3/iki_write/c/main/print/error.c +++ b/level_3/iki_write/c/main/print/error.c @@ -38,7 +38,7 @@ extern "C" { f_file_stream_lock(print->to); - fl_print_format("%[%QNo main provided, either pipe the main data or use the '%]", print->to, print->set->error, print->prefix, print->set->error); + fl_print_format("%[%QNo data provided, either pipe the main data or use the '%]", print->to, print->set->error, print->prefix, print->set->error); fl_print_format(f_string_format_rr_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, iki_write_long_object_s, print->set->notable); fl_print_format("%[' and the '%]", print->to, print->set->error, print->set->error); fl_print_format(f_string_format_rr_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, iki_write_long_content_s, print->set->notable); @@ -50,24 +50,6 @@ extern "C" { } #endif // _di_iki_write_print_error_main_missing_ -#ifndef _di_iki_write_print_error_object_not_valid_ - f_status_t iki_write_print_error_object_not_valid(fl_print_t * const print, const f_string_static_t object) { - - if (!print) return F_status_set_error(F_output_not); - if (print->verbosity < f_console_verbosity_error_e) return F_output_not; - - f_file_stream_lock(print->to); - - fl_print_format("%[%QThe object '%]", print->to, print->set->error, print->prefix, print->set->error); - fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, object, print->set->notable); - fl_print_format("%[' is not a valid IKI Object (IKI Vocabulary).%]%r", print->to, print->set->error, print->set->error, f_string_eol_s); - - f_file_stream_unlock(print->to); - - return F_okay; - } -#endif // _di_iki_write_print_error_object_not_valid_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/iki_write/c/main/print/error.h b/level_3/iki_write/c/main/print/error.h index 245f428..1bb156a 100644 --- a/level_3/iki_write/c/main/print/error.h +++ b/level_3/iki_write/c/main/print/error.h @@ -86,26 +86,6 @@ extern "C" { extern f_status_t iki_write_print_error_main_missing(fl_print_t * const print); #endif // _di_iki_write_print_error_main_missing_ -/** - * Print error message about an Object not being valid. - * - * @param print - * The output structure to print to. - * - * This does not alter print.custom.setting.state.status. - * @param object - * The a string representing the object that is missing. - * - * @return - * F_okay on success. - * F_output_not on success, but no printing is performed. - * - * F_output_not (with error bit) if setting is NULL. - */ -#ifndef _di_iki_write_print_error_object_not_valid_ - extern f_status_t iki_write_print_error_object_not_valid(fl_print_t * const print, const f_string_static_t object); -#endif // _di_iki_write_print_error_object_not_valid_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/iki_write/c/main/print/message.c b/level_3/iki_write/c/main/print/message.c index 038afbc..161d546 100644 --- a/level_3/iki_write/c/main/print/message.c +++ b/level_3/iki_write/c/main/print/message.c @@ -5,11 +5,9 @@ extern "C" { #endif #ifndef _di_iki_write_print_message_help_ - f_status_t iki_write_print_message_help(fl_print_t * const print) { + void iki_write_print_message_help(fl_print_t * const print) { - if (!print) return F_status_set_error(F_output_not); - - f_file_stream_lock(print->to); + if (!print) return; fll_program_print_help_header(print, iki_write_program_name_long_s, iki_write_program_version_s); @@ -33,27 +31,22 @@ extern "C" { fll_program_print_help_option(print, iki_write_short_object_s, iki_write_long_object_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " The Object to write."); fll_program_print_help_option(print, iki_write_short_single_s, iki_write_long_single_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Use single quotes (U+0027)."); fll_program_print_help_option(print, iki_write_short_wrap_s, iki_write_long_wrap_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Wrap the vocabulary name."); + } +#endif // _di_iki_write_print_message_help_ - f_print_dynamic_raw(f_string_eol_s, print->to); +#ifndef _di_iki_write_print_message_help_note_ + void iki_write_print_message_help_note(fl_print_t * const print) { - fll_program_print_help_usage(print, iki_write_program_name_s, f_string_empty_s); + if (!print) return; fl_print_format("%r %[Notes:%]%r", print->to, f_string_eol_s, print->set->important, print->set->important, f_string_eol_s); fl_print_format(" This program will accept Object and Content strings to generate an IKI string, such as %[object:\"content\"%].%r", print->to, print->set->notable, print->set->notable, f_string_eol_s); fl_print_format(" Each Object must have a Content (and each Content must have an Object).%r%r", print->to, f_string_eol_s, f_string_eol_s); fl_print_format(" The Object is also called the Vocabulary.%r", print->to, f_string_eol_s); - fl_print_format(" A complete Object and Content set is also called a Variable.%r%r", print->to, f_string_eol_s, f_string_eol_s); - - fl_print_format(" When piping main to this program, a single form-feed character (\\f) (U+000C) must be used to separate each Object from each Content.%r", print->to, f_string_eol_s); - fl_print_format(" Furthermore, each Object must be followed by a Content.%r", print->to, f_string_eol_s); - - f_file_stream_flush(print->to); - f_file_stream_unlock(print->to); - - return F_okay; + fl_print_format(" A complete Object and Content set is also called a Variable.%r", print->to, f_string_eol_s); } -#endif // _di_iki_write_print_message_help_ +#endif // _di_iki_write_print_message_help_note_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/iki_write/c/main/print/message.h b/level_3/iki_write/c/main/print/message.h index 277f96e..044739c 100644 --- a/level_3/iki_write/c/main/print/message.h +++ b/level_3/iki_write/c/main/print/message.h @@ -22,18 +22,30 @@ extern "C" { * @param print * The output structure to print to. * - * This does not alter print.custom.setting.state.status. - * - * @return - * F_okay on success. - * F_output_not on success, but no printing is performed. + * The print.custom is expected to be of type iki_write_main_t. * - * F_output_not (with error bit) if setting is NULL. + * This does not alter print.custom.setting.state.status. */ #ifndef _di_iki_write_print_message_help_ - extern f_status_t iki_write_print_message_help(fl_print_t * const print); + extern void iki_write_print_message_help(fl_print_t * const print); #endif // _di_iki_write_print_message_help_ +/** + * Print standard parts of the help regarding notes. + * + * This is expected to be called as part of the help printing and does not perform any locking. + * + * @param print + * The output structure to print to. + * + * The print.custom is expected to be of type iki_write_main_t. + * + * This does not alter print.custom.setting.state.status. + */ +#ifndef _di_iki_write_print_message_help_note_ + extern void iki_write_print_message_help_note(fl_print_t * const print); +#endif // _di_iki_write_print_message_help_note_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/iki_write/c/main/process.c b/level_3/iki_write/c/main/process.c deleted file mode 100644 index 3fd6316..0000000 --- a/level_3/iki_write/c/main/process.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "iki_write.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_iki_write_process_ - void iki_write_process(iki_write_main_t * const main, const f_string_static_t object, const f_string_static_t content) { - - if (!main) return; - - if (!object.used) { - main->setting.state.status = F_status_set_error(F_failure); - - fll_program_print_error_missing_variable_not_zero(&main->program.error, iki_write_object_s); - - return; - } - - main->cache.iki.used = 0; - - f_iki_write(object, content, main->setting.quote, &main->cache.iki, &main->setting.state); - - if (F_status_is_error(main->setting.state.status)) { - if (F_status_set_fine(main->setting.state.status) == F_syntax) { - iki_write_print_error_object_not_valid(&main->program.error, object); - } - else { - iki_write_print_error(&main->program.error, macro_iki_write_f(f_iki_write)); - } - - return; - } - - f_print_dynamic(main->cache.iki, main->program.output.to); - - main->setting.state.status = F_okay; - } -#endif // _di_iki_write_process_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/iki_write/c/main/process.h b/level_3/iki_write/c/main/process.h deleted file mode 100644 index 59d5b50..0000000 --- a/level_3/iki_write/c/main/process.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: IKI Write - * API Version: 0.7 - * Licenses: lgpl-2.1-or-later - * - * Provides the process functionality. - * - * This is auto-included and should not need to be explicitly included. - */ -#ifndef _iki_write_write_process_h -#define _iki_write_write_process_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Process a given object and content, printing it. - * - * @param main - * The program and settings data. - * - * This alters main.setting.state.status: - * F_okay on success. - * - * Errors (with error bit) from: f_iki_write(). - * - * F_failure (with error bit) for any other failure. - * @param object - * The object to validate and print. - * @param content - * The content to escape and print. - * - * @see iki_write_print_error_object_not_valid() - * @see f_iki_write() - */ -#ifndef _di_iki_write_process_ - extern void iki_write_process(iki_write_main_t * const main, const f_string_static_t object, const f_string_static_t content); -#endif // _di_iki_write_process_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _iki_write_write_process_h diff --git a/level_3/iki_write/data/build/fakefile b/level_3/iki_write/data/build/fakefile index 4f46ac8..a8fe208 100644 --- a/level_3/iki_write/data/build/fakefile +++ b/level_3/iki_write/data/build/fakefile @@ -8,14 +8,18 @@ settings: environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH main: - build + build settings + build settings.eki_write + build settings.iki_write install: shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' + shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' -s data/build/settings.eki_write + shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' -s data/build/settings.iki_write help: print - print context:'title'Fakefile Options for IKI Write Program.context:'reset' + print context:'title'Fakefile Options for IKI Write Programs.context:'reset' print print The following operations are available\: diff --git a/level_3/iki_write/data/build/settings b/level_3/iki_write/data/build/settings index 5f3acd7..22f1777 100644 --- a/level_3/iki_write/data/build/settings +++ b/level_3/iki_write/data/build/settings @@ -1,5 +1,7 @@ # fss-0001 # +# Builds the main library of the project with all parts except "main" program related. +# # Modes: # - android: Compile on an android system (using Termux; may need modification depending on the android system). # - clang: Use CLang rather than the default, which is generally GCC. @@ -38,11 +40,9 @@ build_libraries-individual_thread -lf_thread build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll -build_sources_library main/iki_write.c main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c main/print/error.c main/print/message.c main/process.c main/signal.c main/thread.c - -build_sources_program main/main.c +build_sources_library main/iki_write.c main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c main/print/error.c main/print/message.c main/signal.c main/thread.c -build_sources_headers main/iki_write.h main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h main/print/error.h main/print/message.h main/process.h main/signal.h main/thread.h +build_sources_headers main/iki_write.h main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h main/print/error.h main/print/message.h main/signal.h main/thread.h build_sources_documentation man diff --git a/level_3/iki_write/data/build/settings.eki_write b/level_3/iki_write/data/build/settings.eki_write new file mode 100644 index 0000000..917dda7 --- /dev/null +++ b/level_3/iki_write/data/build/settings.eki_write @@ -0,0 +1,71 @@ +# fss-0001 +# +# Builds the "iki_write" program. +# This must be called after the "setting". +# + +build_name eki_write + +version_major 0 +version_minor 7 +version_micro 0 +version_file micro +version_target minor + +modes android clang coverage fanalyzer gcc gcc_13 individual individual_thread level monolithic test thread threadless +modes_default monolithic thread gcc + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c +build_libraries -lc -liki_write +build_libraries-individual -lfll_error -lfll_iki -lfll_print -lfll_program -lfl_iki -lfl_print -lf_color -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_pipe -lf_print -lf_rip -lf_signal -lf_string -lf_type_array -lf_utf +build_libraries-individual_thread -lf_thread +build_libraries-level -lfll_2 -lfll_1 -lfll_0 +build_libraries-monolithic -lfll + +build_sources_program eki/common.c eki/eki_write.c eki/main.c eki/print.c eki/process.c + +build_sources_headers eki/common.h eki/eki_write.h eki/print.h eki/process.h + +build_sources_documentation man + +build_script yes +build_shared yes +build_static no + +path_headers program/iki_write + +has_path_standard yes +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +environment PATH LD_LIBRARY_PATH +environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +#defines -D_di_libcap_ +defines -D_libcap_legacy_only_ +defines-android -D_di_f_thread_attribute_affinity_get_ -D_di_f_thread_attribute_affinity_set_ -D_di_f_thread_attribute_concurrency_get_ -D_di_f_thread_attribute_concurrency_set_ -D_di_f_thread_attribute_default_get_ -D_di_f_thread_attribute_default_set_ -D_di_f_thread_cancel_ -D_di_f_thread_cancel_state_set_ -D_di_f_thread_cancel_test_ -D_di_f_thread_join_try_ -D_di_f_thread_join_timed_ -D_pthread_mutex_prioceiling_unsupported_ -D_di_f_thread_semaphore_file_close_ -D_di_f_thread_semaphore_file_open_ -D_di_f_thread_semaphore_file_delete_ -D_di_f_thread_cancel_type_set_ +defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_ +defines-threadless -D_di_thread_support_ + +flags -O2 -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces +flags -fstack-clash-protection -fno-delete-null-pointer-checks +flags -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now +flags-android -Wno-implicit-function-declaration -Wl,-z,norelro +flags-clang -Wno-logical-op-parentheses +flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/ +flags-fanalyzer -fanalyzer +flags-gcc_13 -fstrict-flex-arrays=3 +flags-test -O0 -fstack-protector-strong -Wall +flags-thread -pthread + +flags_library -fPIC +flags_object -fPIC +flags_program -fPIE +flags_program-android -fPIE -Wl,-z,relro diff --git a/level_3/iki_write/data/build/settings.iki_write b/level_3/iki_write/data/build/settings.iki_write new file mode 100644 index 0000000..cc9da19 --- /dev/null +++ b/level_3/iki_write/data/build/settings.iki_write @@ -0,0 +1,71 @@ +# fss-0001 +# +# Builds the "iki_write" program. +# This must be called after the "setting". +# + +build_name iki_write + +version_major 0 +version_minor 7 +version_micro 0 +version_file micro +version_target minor + +modes android clang coverage fanalyzer gcc gcc_13 individual individual_thread level monolithic test thread threadless +modes_default monolithic thread gcc + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c +build_libraries -lc -liki_write +build_libraries-individual -lfll_error -lfll_iki -lfll_print -lfll_program -lfl_iki -lfl_print -lf_color -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_pipe -lf_print -lf_rip -lf_signal -lf_string -lf_type_array -lf_utf +build_libraries-individual_thread -lf_thread +build_libraries-level -lfll_2 -lfll_1 -lfll_0 +build_libraries-monolithic -lfll + +build_sources_program iki/common.c iki/iki_write.c iki/main.c iki/print.c iki/process.c + +build_sources_headers iki/common.h iki/iki_write.h iki/print.h iki/process.h + +build_sources_documentation man + +build_script yes +build_shared yes +build_static no + +path_headers program/iki_write + +has_path_standard yes +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +environment PATH LD_LIBRARY_PATH +environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +#defines -D_di_libcap_ +defines -D_libcap_legacy_only_ +defines-android -D_di_f_thread_attribute_affinity_get_ -D_di_f_thread_attribute_affinity_set_ -D_di_f_thread_attribute_concurrency_get_ -D_di_f_thread_attribute_concurrency_set_ -D_di_f_thread_attribute_default_get_ -D_di_f_thread_attribute_default_set_ -D_di_f_thread_cancel_ -D_di_f_thread_cancel_state_set_ -D_di_f_thread_cancel_test_ -D_di_f_thread_join_try_ -D_di_f_thread_join_timed_ -D_pthread_mutex_prioceiling_unsupported_ -D_di_f_thread_semaphore_file_close_ -D_di_f_thread_semaphore_file_open_ -D_di_f_thread_semaphore_file_delete_ -D_di_f_thread_cancel_type_set_ +defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_ +defines-threadless -D_di_thread_support_ + +flags -O2 -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces +flags -fstack-clash-protection -fno-delete-null-pointer-checks +flags -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now +flags-android -Wno-implicit-function-declaration -Wl,-z,norelro +flags-clang -Wno-logical-op-parentheses +flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/ +flags-fanalyzer -fanalyzer +flags-gcc_13 -fstrict-flex-arrays=3 +flags-test -O0 -fstack-protector-strong -Wall +flags-thread -pthread + +flags_library -fPIC +flags_object -fPIC +flags_program -fPIE +flags_program-android -fPIE -Wl,-z,relro -- 1.8.3.1