From 8bea8f48c022c70984d76592dbc62048501a1209 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 12 Nov 2021 21:13:27 -0600 Subject: [PATCH] Update: Remove old color print functions. These functions are still present for migration and just in case. Now that I am using fl_print_format() I feel there is no reason to keep and maintain this code. Get rid of it. --- level_1/fl_print/c/print.c | 86 ------ level_1/fl_print/c/print.h | 102 ------- level_2/fll_print/c/print.c | 126 -------- level_2/fll_print/c/print.h | 102 ------- level_3/controller/c/private-rule_print.c | 6 +- level_3/utf8/c/main.c | 53 ++++ level_3/utf8/c/private-common.c | 177 +++++++++++ level_3/utf8/c/private-common.h | 138 +++++++++ level_3/utf8/c/private-utf8.c | 400 +++++++++++++++++++++++++ level_3/utf8/c/private-utf8.h | 179 ++++++++++++ level_3/utf8/c/utf8.c | 470 ++++++++++++++++++++++++++++++ level_3/utf8/c/utf8.h | 311 ++++++++++++++++++++ level_3/utf8/data/build/defines | 2 + level_3/utf8/data/build/dependencies | 21 ++ level_3/utf8/data/build/settings | 78 +++++ 15 files changed, 1831 insertions(+), 420 deletions(-) create mode 100644 level_3/utf8/c/main.c create mode 100644 level_3/utf8/c/private-common.c create mode 100644 level_3/utf8/c/private-common.h create mode 100644 level_3/utf8/c/private-utf8.c create mode 100644 level_3/utf8/c/private-utf8.h create mode 100644 level_3/utf8/c/utf8.c create mode 100644 level_3/utf8/c/utf8.h create mode 100644 level_3/utf8/data/build/defines create mode 100644 level_3/utf8/data/build/dependencies create mode 100644 level_3/utf8/data/build/settings diff --git a/level_1/fl_print/c/print.c b/level_1/fl_print/c/print.c index 3fbeab1..8529557 100644 --- a/level_1/fl_print/c/print.c +++ b/level_1/fl_print/c/print.c @@ -5,92 +5,6 @@ extern "C" { #endif -#ifndef _di_fl_print_color_ - f_status_t fl_print_color(const f_string_static_t buffer, const f_color_set_t set, FILE *output) { - - if (!buffer.used) { - return F_data_not; - } - - f_status_t status = F_none; - - if (set.before) { - status = f_print_terminated(set.before->string, output); - if (F_status_is_error(status)) return status; - } - - status = f_print(buffer.string, buffer.used, output); - - if (set.after) { - - // attempt to always print the closing color, even on error. - if (F_status_is_error(status)) { - f_print_terminated(set.after->string, output); - } - else { - status = f_print_terminated(set.after->string, output); - if (F_status_is_error(status)) return status; - } - } - - return status; - } -#endif // _di_fl_print_color_ - -#ifndef _di_fl_print_color_after_ - f_status_t fl_print_color_after(const f_color_set_t set, FILE *output) { - - if (set.after) { - return f_print_terminated(set.after->string, output); - } - - return F_data_not; - } -#endif // _di_fl_print_color_after_ - -#ifndef _di_fl_print_color_before_ - f_status_t fl_print_color_before(const f_color_set_t set, FILE *output) { - - if (set.before) { - return f_print_terminated(set.before->string, output); - } - - return F_data_not; - } -#endif // _di_fl_print_color_before_ - -#ifndef _di_fl_print_color_terminated_ - f_status_t fl_print_color_terminated(const f_string_t string, const f_color_set_t set, FILE *output) { - - if (!*string) { - return F_data_not; - } - - f_status_t status = F_none; - - if (set.before) { - status = f_print_terminated(set.before->string, output); - if (F_status_is_error(status)) return status; - } - - status = f_print_terminated(string, output); - - if (set.after) { - - // attempt to always print the closing color, even on error. - if (F_status_is_error(status)) { - f_print_terminated(set.after->string, output); - } - else { - status = f_print_terminated(set.after->string, output); - if (F_status_is_error(status)) return status; - } - } - - return status; - } -#endif // _di_fl_print_color_terminated_ - #ifndef _di_fl_print_format_ f_status_t fl_print_format(const f_string_t string, FILE *output, ...) { #ifndef _di_level_1_parameter_checking_ diff --git a/level_1/fl_print/c/print.h b/level_1/fl_print/c/print.h index 37b0ead..7887545 100644 --- a/level_1/fl_print/c/print.h +++ b/level_1/fl_print/c/print.h @@ -34,108 +34,6 @@ extern "C" { #endif /** - * Print the string with the given color set printed before and after as appropriate to the file stream. - * - * No before/after colors are printed when the string is determined to be empty. - * - * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. - * - * @param buffer - * The string to print. - * @param set - * The color set to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed. - * - * Success from: f_print(). - * - * Errors (with error bit) from: f_print() - * Errors (with error bit) from: f_print_terminated(). - * - * @see f_print() - * @see f_print_terminated() - */ -#ifndef _di_fl_print_color_ - extern f_status_t fl_print_color(const f_string_static_t buffer, const f_color_set_t set, FILE *output); -#endif // _di_fl_print_color_ - -/** - * Print the "after" part of a color set to the given file stream. - * - * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. - * - * @param set - * The color set to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed (such as when color code is NULL). - * - * Success from: f_print_terminated(). - * - * Errors (with error bit) from: f_print_terminated(). - * - * @see f_print_terminated() - */ -#ifndef _di_fl_print_color_after_ - extern f_status_t fl_print_color_after(const f_color_set_t set, FILE *output); -#endif // _di_fl_print_color_after_ - -/** - * Print the "after" part of a color set to the given file stream. - * - * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. - * - * @param set - * The color set to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed (such as when color code is NULL). - * - * Success from: f_print_terminated(). - * - * Errors (with error bit) from: f_print_terminated(). - * - * @see f_print_terminated() - */ -#ifndef _di_fl_print_color_before_ - extern f_status_t fl_print_color_before(const f_color_set_t set, FILE *output); -#endif // _di_fl_print_color_before_ - -/** - * Print the NULL-terminated string with the given color set printed before and after as appropriate to the file stream. - * - * No before/after colors are printed when the string is determined to be empty. - * - * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. - * - * @param string - * The string to print. - * @param set - * The color set to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed. - * - * Success from: f_print_terminated(). - * - * Errors (with error bit) from: f_print_terminated(). - * - * @see f_print_terminated() - */ -#ifndef _di_fl_print_color_terminated_ - extern f_status_t fl_print_color_terminated(const f_string_t string, const f_color_set_t set, FILE *output); -#endif // _di_fl_print_color_terminated_ - -/** * A formatted print function similar to (but not the same as) the c-library fprintf() function. * * This function attempts to operate as closely to how fprintf() operates, however, there are notable differences. diff --git a/level_2/fll_print/c/print.c b/level_2/fll_print/c/print.c index e54115b..13b7720 100644 --- a/level_2/fll_print/c/print.c +++ b/level_2/fll_print/c/print.c @@ -43,132 +43,6 @@ extern "C" { } #endif // _di_fll_print_character_safely_ -#ifndef _di_fll_print_color_ - f_status_t fll_print_color(const f_string_static_t buffer, const f_color_set_t set, FILE *output) { - - if (!buffer.used) { - return F_data_not; - } - - f_status_t status = F_none; - - flockfile(output); - - if (set.before) { - status = f_print_terminated(set.before->string, output); - - if (F_status_is_error(status)) { - funlockfile(output); - - return status; - } - } - - status = f_print(buffer.string, buffer.used, output); - - if (set.after) { - - // attempt to always print the closing color, even on error. - if (F_status_is_error(status)) { - f_print_terminated(set.after->string, output); - } - else { - status = f_print_terminated(set.after->string, output); - - if (F_status_is_error(status)) { - funlockfile(output); - - return status; - } - } - } - - funlockfile(output); - - return status; - } -#endif // _di_fll_print_color_ - -#ifndef _di_fll_print_color_after_ - f_status_t fll_print_color_after(const f_color_set_t set, FILE *output) { - - if (set.after) { - flockfile(output); - - const f_status_t status = f_print_terminated(set.after->string, output); - - funlockfile(output); - - return status; - } - - return F_data_not; - } -#endif // _di_fll_print_color_after_ - -#ifndef _di_fll_print_color_before_ - f_status_t fll_print_color_before(const f_color_set_t set, FILE *output) { - - if (set.before) { - flockfile(output); - - const f_status_t status = f_print_terminated(set.before->string, output); - - funlockfile(output); - - return status; - } - - return F_data_not; - } -#endif // _di_fll_print_color_before_ - -#ifndef _di_fll_print_color_terminated_ - f_status_t fll_print_color_terminated(const f_string_t string, const f_color_set_t set, FILE *output) { - - if (!*string) { - return F_data_not; - } - - f_status_t status = F_none; - - flockfile(output); - - if (set.before) { - status = f_print_terminated(set.before->string, output); - - if (F_status_is_error(status)) { - funlockfile(output); - - return status; - } - } - - status = f_print_terminated(set.before->string, output); - - if (set.after) { - - // attempt to always print the closing color, even on error. - if (F_status_is_error(status)) { - f_print_terminated(set.after->string, output); - } - else { - status = f_print_terminated(set.after->string, output); - - if (F_status_is_error(status)) { - funlockfile(output); - - return status; - } - } - } - - funlockfile(output); - - return status; - } -#endif // _di_fll_print_color_terminated_ - #ifndef _di_fll_print_dynamic_ f_status_t fll_print_dynamic(const f_string_static_t buffer, FILE *output) { diff --git a/level_2/fll_print/c/print.h b/level_2/fll_print/c/print.h index a46b994..8490503 100644 --- a/level_2/fll_print/c/print.h +++ b/level_2/fll_print/c/print.h @@ -98,108 +98,6 @@ extern "C" { #endif // _di_fll_print_character_safely_ /** - * This is a variation of fl_print_color() that uses locking. - * - * @param buffer - * The string to print. - * @param set - * The color set to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed. - * - * Success from: f_print(). - * - * Errors (with error bit) from: f_print() - * Errors (with error bit) from: f_print_terminated(). - * - * @see f_print() - * @see f_print_terminated() - * @see fl_print_color() - */ -#ifndef _di_fll_print_color_ - extern f_status_t fll_print_color(const f_string_static_t buffer, const f_color_set_t set, FILE *output); -#endif // _di_fll_print_color_ - -/** - * This is a variation of fl_print_color_after() that uses locking. - * - * @param set - * The color set. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed (such as when color code is NULL). - * F_parameter (with error bit) if a parameter is invalid. - * - * Success from: f_print_terminated(). - * - * Errors (with error bit) from: f_print_terminated(). - * - * @see flockfile() - * @see funlockfile() - * - * @see f_print_terminated() - * @see fl_print_color_after() - */ -#ifndef _di_fll_print_color_after_ - extern f_status_t fll_print_color_after(const f_color_set_t set, FILE *output); -#endif // _di_fll_print_color_after_ - -/** - * This is a variation of fl_print_color_before() that uses locking. - * - * @param set - * The color set. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed (such as when color code is NULL). - * F_parameter (with error bit) if a parameter is invalid. - * - * Success from: f_print_terminated(). - * - * Errors (with error bit) from: f_print_terminated(). - * - * @see flockfile() - * @see funlockfile() - * - * @see f_print_terminated() - * @see fl_print_color_before() - */ -#ifndef _di_fll_print_color_before_ - extern f_status_t fll_print_color_before(const f_color_set_t set, FILE *output); -#endif // _di_fll_print_color_before_ - -/** - * This is a variation of fl_print_color_terminated() that uses locking. - * - * @param string - * The string to print. - * @param set - * The color set to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_data_not if nothing is printed. - * - * Success from: f_print_terminated(). - * - * Errors (with error bit) from: f_print_terminated(). - * - * @see f_print_terminated() - * @see fl_print_color_terminated() - */ -#ifndef _di_fll_print_color_terminated_ - extern f_status_t fll_print_color_terminated(const f_string_t string, const f_color_set_t set, FILE *output); -#endif // _di_fll_print_color_terminated_ - -/** * This is a variation of f_print_dynamic() that uses locking. * * @param buffer diff --git a/level_3/controller/c/private-rule_print.c b/level_3/controller/c/private-rule_print.c index 07223e8..b9912dc 100644 --- a/level_3/controller/c/private-rule_print.c +++ b/level_3/controller/c/private-rule_print.c @@ -86,8 +86,7 @@ extern "C" { fl_print_format("%[%S%]", print->to.stream, print->notable, name, print->notable); if (status == F_control_group || status == F_limit || status == F_processor || status == F_schedule) { - fl_print_format("%[' failed due to a failure to setup the '%]", print->to.stream, print->context, print->context); - fl_print_color_before(print->notable, print->to.stream); + fl_print_format("%[' failed due to a failure to setup the '%]%[", print->to.stream, print->context, print->context, print->notable); if (status == F_control_group) { f_print_terminated(controller_control_group_s, print->to.stream); @@ -102,8 +101,7 @@ extern "C" { f_print_terminated(controller_scheduler_s, print->to.stream); } - fl_print_color_after(print->notable, print->to.stream); - fl_print_format("%['.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); + fl_print_format("%]%['.%]%c", print->to.stream, print->notable, print->context, print->context, f_string_eol_s[0]); } else if (WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0) { const uint8_t code = WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0; diff --git a/level_3/utf8/c/main.c b/level_3/utf8/c/main.c new file mode 100644 index 0000000..5c91bb9 --- /dev/null +++ b/level_3/utf8/c/main.c @@ -0,0 +1,53 @@ +#include "utf8.h" + +int main(const int argc, const f_string_t *argv) { + + const f_console_arguments_t arguments = { argc, argv }; + utf8_main_t data = utf8_main_t_initialize; + + if (f_pipe_input_exists()) { + data.process_pipe = F_true; + } + + // Handle signals so that program can cleanly exit, deallocating as appropriate. + { + f_signal_set_empty(&data.signal.set); + f_signal_set_add(F_signal_abort, &data.signal.set); + f_signal_set_add(F_signal_broken_pipe, &data.signal.set); + f_signal_set_add(F_signal_hangup, &data.signal.set); + f_signal_set_add(F_signal_interrupt, &data.signal.set); + f_signal_set_add(F_signal_quit, &data.signal.set); + f_signal_set_add(F_signal_termination, &data.signal.set); + + f_status_t status = f_signal_mask(SIG_BLOCK, &data.signal.set, 0); + + if (F_status_is_error_not(status)) { + status = f_signal_open(&data.signal); + + // If there is an error opening a signal descriptor, then do not handle signals. + if (F_status_is_error(status)) { + f_signal_mask(SIG_UNBLOCK, &data.signal.set, 0); + f_signal_close(&data.signal); + } + } + } + + const f_status_t status = utf8_main(&data, &arguments); + + // Flush output pipes before closing. + fflush(F_type_output_d); + fflush(F_type_error_d); + + // Close all open file descriptors. + close(F_type_descriptor_output_d); + close(F_type_descriptor_input_d); + close(F_type_descriptor_error_d); + + f_signal_close(&data.signal); + + if (F_status_is_error(status) || status == F_false) { + return 1; + } + + return 0; +} diff --git a/level_3/utf8/c/private-common.c b/level_3/utf8/c/private-common.c new file mode 100644 index 0000000..b625b78 --- /dev/null +++ b/level_3/utf8/c/private-common.c @@ -0,0 +1,177 @@ +#include "utf8.h" +#include "private-common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_print_error_no_from_ + void utf8_print_error_no_from(utf8_main_t * const main) { + + if (main->error.verbosity == f_console_verbosity_quiet) return; + + fll_print_format("%c%[%sNo from sources are specified, please pipe data, designate a file, or add parameters.%]%c", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context, f_string_eol_s[0]); + } +#endif // _di_utf8_print_error_no_from_ + +#ifndef _di_utf8_print_error_no_value_ + void utf8_print_error_no_value(utf8_main_t * const main, const f_string_t parameter) { + + if (main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, main->context.set.error); + fl_print_format("%[%s%S%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, parameter, main->context.set.notable); + fl_print_format("%[' is specified, but no value was given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } +#endif // _di_utf8_print_error_no_value_ + +#ifndef _di_utf8_print_error_parameter_conflict_ + void utf8_print_error_parameter_conflict(utf8_main_t * const main, const f_string_t first, const f_string_t second) { + + if (main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(main->output.to.stream); + + fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%S%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, first, main->error.notable); + fl_print_format("%[' cannot be used with the parameter '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%S%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, second, main->error.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } +#endif // _di_utf8_print_error_parameter_conflict_ + +#ifndef _di_utf8_print_error_parameter_file_name_empty_ + void utf8_print_error_parameter_file_name_empty(utf8_main_t * const main, const f_array_length_t index) { + + if (main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SNo file specified at parameter index %]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, main->context.set.error); + fl_print_format("%[%ul%]", main->error.to.stream, main->context.set.notable, index, main->context.set.notable); + fl_print_format("%[.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } +#endif // _di_utf8_print_error_parameter_file_name_empty_ + +#ifndef _di_utf8_print_error_parameter_file_not_found_ + void utf8_print_error_parameter_file_not_found(utf8_main_t * const main, const bool from, const f_string_t name) { + + if (main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SFailed to find the %s file '%]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, from ? utf8_string_from_s : utf8_string_to_s, main->context.set.error); + fl_print_format("%[%S%]", main->error.to.stream, main->context.set.notable, name, main->context.set.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } +#endif // _di_utf8_print_error_parameter_file_not_found_ + +#ifndef _di_utf8_print_error_parameter_file_to_too_many_ + void utf8_print_error_parameter_file_to_too_many(utf8_main_t * const main) { + + if (main->error.verbosity == f_console_verbosity_quiet) return; + + fll_print_format("%c%[%SToo many %s files specified, there may only be one to file.%]%c", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, utf8_string_to_s, main->context.set.error, f_string_eol_s[0]); + } +#endif // _di_utf8_print_error_parameter_file_to_too_many_ + +#ifndef _di_utf8_print_section_header_file_ + void utf8_print_section_header_file(utf8_main_t * const main, const f_string_t name) { + + if (main->output.verbosity == f_console_verbosity_quiet) return; + if (main->parameters[utf8_parameter_headers].result == f_console_result_none) return; + + flockfile(main->output.to.stream); + + fl_print_format("%c%[File%] ", main->output.to.stream, f_string_eol_s[0], main->output.set->title, main->output.set->title); + fl_print_format("%[%S%]:%c", main->output.to.stream, main->output.set->notable, name, main->output.set->notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } +#endif // _di_utf8_print_section_header_file_ + +#ifndef _di_utf8_print_section_header_parameter_ + void utf8_print_section_header_parameter(utf8_main_t * const main, const f_array_length_t index) { + + if (main->output.verbosity == f_console_verbosity_quiet) return; + if (main->parameters[utf8_parameter_headers].result == f_console_result_none) return; + + flockfile(main->output.to.stream); + + fl_print_format("%c%[Parameter%] ", main->output.to.stream, f_string_eol_s[0], main->output.set->title, main->output.set->title); + fl_print_format("%[%ul%]:%c", main->output.to.stream, main->output.set->notable, index, main->output.set->notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } +#endif // _di_utf8_print_section_header_parameter_ + +#ifndef _di_utf8_print_section_header_pipe_ + void utf8_print_section_header_pipe(utf8_main_t * const main) { + + if (main->output.verbosity == f_console_verbosity_quiet) return; + if (main->parameters[utf8_parameter_headers].result == f_console_result_none) return; + + fll_print_format("%c%[Pipe%]:%c", main->output.to.stream, f_string_eol_s[0], main->output.set->title, main->output.set->title, f_string_eol_s[0]); + } +#endif // _di_utf8_print_section_header_pipe_ + +#ifndef _di_utf8_print_signal_received_ + void utf8_print_signal_received(utf8_main_t * const main, const f_status_t signal) { + + if (main->warning.verbosity != f_console_verbosity_verbose) return; + + // Must flush and reset color because the interrupt may have interrupted the middle of a print function. + fflush(main->warning.to.stream); + + flockfile(main->warning.to.stream); + + fl_print_format("%]%c%c%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s[0], f_string_eol_s[0], main->context.set.warning, main->context.set.warning); + fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable); + fl_print_format("%[.%]%c", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } +#endif // _di_utf8_print_signal_received_ + +#ifndef _di_utf8_signal_received_ + f_status_t utf8_signal_received(utf8_main_t * const main) { + + if (!main->signal.id) { + return F_false; + } + + struct signalfd_siginfo information; + + memset(&information, 0, sizeof(struct signalfd_siginfo)); + + if (f_signal_read(main->signal, 0, &information) == F_signal) { + switch (information.ssi_signo) { + case F_signal_abort: + case F_signal_broken_pipe: + case F_signal_hangup: + case F_signal_interrupt: + case F_signal_quit: + case F_signal_termination: + utf8_print_signal_received(main, information.ssi_signo); + + return information.ssi_signo; + } + } + + return F_false; + } +#endif // _di_utf8_signal_received_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/utf8/c/private-common.h b/level_3/utf8/c/private-common.h new file mode 100644 index 0000000..b7f40ca --- /dev/null +++ b/level_3/utf8/c/private-common.h @@ -0,0 +1,138 @@ +/** + * FLL - Level 3 + * + * Project: UTF-8 + * API Version: 0.5 + * Licenses: lgplv2.1 + */ +#ifndef _PRIVATE_common_h +#define _PRIVATE_common_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print error message for when no sources are provided. + * + * @param main + * The main program data. + */ +#ifndef _di_utf8_print_error_no_from_ + extern void utf8_print_error_no_from(utf8_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_no_from_ + +/** + * Print error message for when no sources are provided. + * + * @param main + * The main program data. + * @param parameter_1 + * The long parameter name. + */ +#ifndef _di_utf8_print_error_no_value_ + extern void utf8_print_error_no_value(utf8_main_t * const main, const f_string_t parameter) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_no_value_ + +/** + * Print error message for two parameters not being allowed to be used together. + * + * @param main + * The main program data. + * @param first + * The long parameter name for the first parameter. + * @param second + * The long parameter name for the second parameter. + */ +#ifndef _di_utf8_print_error_parameter_conflict_ + extern void utf8_print_error_parameter_conflict(utf8_main_t * const main, const f_string_t first, const f_string_t second) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_conflict_ + +/** + * Print error message for when the file parameter is an empty string. + * + * @param main + * The main program data. + * @param index + * The index within the argv[] array where the empty string is found. + */ +#ifndef _di_utf8_print_error_parameter_file_name_empty_ + extern void utf8_print_error_parameter_file_name_empty(utf8_main_t * const main, const f_array_length_t index) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_file_name_empty_ + +/** + * Print error message for when no sources are provided in the main program parameters. + * + * @param main + * The main program data. + * @param from + * If TRUE, then this is a from file (source file). + * If FALSE, then this is a to file (destination file). + * @param name + * The file path name. + */ +#ifndef _di_utf8_print_error_parameter_file_not_found_ + extern void utf8_print_error_parameter_file_not_found(utf8_main_t * const main, const bool from, const f_string_t name) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_file_not_found_ + +/** + * Print error message for when too many 'to' destinations are specified. + * + * @param main + * The main program data. + */ +#ifndef _di_utf8_print_error_parameter_file_to_too_many_ + extern void utf8_print_error_parameter_file_to_too_many(utf8_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_file_to_too_many_ + +/** + * Print the input file section header. + * + * @param main + * The main program data. + * @param name + * The name of the file. + */ +#ifndef _di_utf8_print_section_header_file_ + extern void utf8_print_section_header_file(utf8_main_t * const main, const f_string_t name) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_section_header_file_ + +/** + * Print the input parameter section header. + * + * @param main + * The main program data. + * @param index + * The index position of the parameter. + */ +#ifndef _di_utf8_print_section_header_parameter_ + extern void utf8_print_section_header_parameter(utf8_main_t * const main, const f_array_length_t index) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_section_header_parameter_ + +/** + * Print the input pipe section header. + * + * @param main + * The main program data. + */ +#ifndef _di_utf8_print_section_header_pipe_ + extern void utf8_print_section_header_pipe(utf8_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_section_header_pipe_ + +/** + * Print a message about a process signal being recieved, such as an interrupt signal. + * + * @param main + * The main program data. + * @param signal + * The signal code received. + */ +#ifndef _di_utf8_print_signal_received_ + extern void utf8_print_signal_received(utf8_main_t * const main, const f_status_t signal) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_signal_received_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_common_h diff --git a/level_3/utf8/c/private-utf8.c b/level_3/utf8/c/private-utf8.c new file mode 100644 index 0000000..7689cde --- /dev/null +++ b/level_3/utf8/c/private-utf8.c @@ -0,0 +1,400 @@ +#include "utf8.h" +#include "private-common.h" +#include "private-utf8.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_convert_binary_ + f_status_t utf8_convert_binary(utf8_main_t * const main, const f_string_static_t character) { + + f_status_t status = F_none; + + f_string_t prepend = ""; + f_string_t append = ""; + f_color_set_t error = f_color_set_t_initialize; + + if (main->mode & utf8_mode_to_codepoint_d) { + if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { + if (main->parameters[utf8_parameter_headers].result == f_console_result_found) { + prepend = " "; + } + else { + prepend = " "; + } + + append = f_string_eol_s; + } + else { + error = main->output.set->error; + prepend = " "; + } + } + + uint32_t codepoint = 0; + + if (character.used) { + status = f_utf_unicode_to(character.string, character.used, &codepoint); + } + else { + status = F_status_set_error(F_utf); + } + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_utf) { + if (main->parameters[utf8_parameter_strip_invalid].result == f_console_result_none) { + if (main->mode & utf8_mode_to_binary_d) { + fl_print_format("%s%[", main->output.to.stream, prepend, error); + + for (f_array_length_t i = 0; i < character.used; ++i) { + f_print_character(character.string[i], main->output.to.stream); + } // for + + fl_print_format("%s%[", main->output.to.stream, error, append); + } + else { + fl_print_format("%s%[0x", main->output.to.stream, prepend, error); + + for (uint8_t i = 0; i < character.used; ++i) { + fl_print_format("%02_uii", main->output.to.stream, (uint8_t) character.string[i]); + } // for + + fl_print_format("%]%s", main->output.to.stream, error, append); + } + } + } + else { + if (main->error.verbosity != f_console_verbosity_quiet) { + fl_print_format("%c%[%SFailed to decode character '%]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->context.set.error); + fl_print_format("%[%r%]", main->error.to.stream, main->context.set.notable, character, main->context.set.notable); + fl_print_format("%[', error status code%] ", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + fl_print_format("%[%S%]", main->error.to.stream, main->context.set.notable, F_status_set_fine(status), main->context.set.notable); + fl_print_format("%[.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + } + + return status; + } + } + else if (main->parameters[utf8_parameter_verify].result == f_console_result_none) { + if (main->mode & utf8_mode_to_binary_d) { + f_print_terminated(prepend, main->output.to.stream); + + for (f_array_length_t i = 0; i < character.used; ++i) { + f_print_character(character.string[i], main->output.to.stream); + } // for + + f_print_terminated(append, main->output.to.stream); + } + else { + if (character.used < 4) { + fl_print_format("%sU+%04_U%s", main->output.to.stream, prepend, codepoint, append); + } + else { + fl_print_format("%sU+%06_U%s", main->output.to.stream, prepend, codepoint, append); + } + } + } + + if (F_status_is_error(status)) { + return F_utf; + } + + return F_none; + } +#endif // _di_utf8_convert_binary_ + +#ifndef _di_utf8_convert_codepoint_ + f_status_t utf8_convert_codepoint(utf8_main_t * const main, const f_string_static_t character, uint8_t *mode) { + + f_status_t status = F_none; + + // @todo + + + return F_none; + } +#endif // _di_utf8_convert_codepoint_ + +#ifndef _di_utf8_process_file_binary_ + f_status_t utf8_process_file_binary(utf8_main_t * const main, const f_file_t file) { + + f_status_t status = F_none; + bool valid = F_true; + bool next = F_true; + uint8_t mode = 0; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + char block_character[4] = { 0, 0, 0, 0 }; + f_string_static_t character = macro_f_string_static_t_initialize(block_character, 4); + + do { + status = f_file_read_block(file, &main->buffer); + + if (status == F_none_eof && !main->buffer.used) break; + + for (i = 0; F_status_is_fine(status) && i < main->buffer.used; ) { + + status = utf8_signal_received(main); + + if (status) { + utf8_print_signal_received(main, status); + + status = F_status_set_error(F_signal); + break; + } + else { + status = F_none; + } + + // Get the current width only when processing a new block. + if (next) { + character.used = macro_f_utf_byte_width(main->buffer.string[i]); + next = F_false; + } + + for (; j < character.used && i < main->buffer.used; ++j, ++i) { + character.string[j] = main->buffer.string[i]; + } // for + + if (j == character.used) { + if (main->mode & utf8_mode_from_binary_d) { + status = utf8_convert_binary(main, character); + } + else { + // @todo: check character and determine status. + /*private_utf8_codepoint_modes_ready = 1, + private_utf8_codepoint_modes_begin, + private_utf8_codepoint_modes_number, + private_utf8_codepoint_modes_end, + private_utf8_codepoint_modes_bad,*/ + status = utf8_convert_codepoint(main, character, &mode); + } + + if (status == F_utf) { + valid = F_false; + } + + j = 0; + next = F_true; + } + } // for + + i = 0; + main->buffer.used = 0; + + } while (F_status_is_fine(status) && status != F_signal); + + // Handle last (incomplete) character when the buffer ended before the character is supposed to end. + if (status != F_signal && next == F_false) { + character.used = j; + + if (main->mode & utf8_mode_from_binary_d) { + status = utf8_convert_binary(main, character); + } + else { + // @todo: check character and determine status. + /*private_utf8_codepoint_modes_ready = 1, + private_utf8_codepoint_modes_begin, + private_utf8_codepoint_modes_number, + private_utf8_codepoint_modes_end, + private_utf8_codepoint_modes_bad,*/ + status = utf8_convert_codepoint(main, character, &mode); + } + + if (status == F_utf) { + valid = F_false; + } + } + + main->buffer.used = 0; + + if (F_status_is_error(status)) { + return status; + } + + return valid; + } +#endif // _di_utf8_process_file_binary_ + +#ifndef _di_utf8_process_file_codepoint_ + f_status_t utf8_process_file_codepoint(utf8_main_t * const main, const f_file_t file) { + + f_status_t status = F_none; + bool valid = F_true; + bool next = F_true; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + char block[4] = { 0, 0, 0, 0 }; + f_string_static_t character = macro_f_string_static_t_initialize(block, 4); + + do { + status = f_file_read_block(file, &main->buffer); + + if (status == F_none_eof && !main->buffer.used) break; + + for (i = 0; F_status_is_fine(status) && i < main->buffer.used; ) { + + status = utf8_signal_received(main); + + if (status) { + utf8_print_signal_received(main, status); + + status = F_status_set_error(F_signal); + break; + } + else { + status = F_none; + } + + // Get the current width only when processing a new block. + if (next) { + character.used = macro_f_utf_byte_width(main->buffer.string[i]); + next = F_false; + } + + for (; j < character.used && i < main->buffer.used; ++j, ++i) { + character.string[j] = main->buffer.string[i]; + } // for + + if (j == character.used) { + status = utf8_convert_binary(main, character); + + if (status == F_utf) { + valid = F_false; + } + + j = 0; + next = F_true; + } + } // for + + i = 0; + main->buffer.used = 0; + + } while (F_status_is_fine(status) && status != F_signal); + + // Handle last (incomplete) character when the buffer ended before the character is supposed to end. + if (status != F_signal && next == F_false) { + character.used = j; + + status = utf8_convert_binary(main, character); + + if (status == F_utf) { + valid = F_false; + } + } + + main->buffer.used = 0; + + if (F_status_is_error(status)) { + return status; + } + + return valid; + } +#endif // _di_utf8_process_file_codepoint_ + +#ifndef _di_utf8_process_text_ + f_status_t utf8_process_text(utf8_main_t * const main, const f_string_t text) { + + if (!text) { + return F_true; + } + + f_status_t status = F_none; + bool valid = F_true; + uint8_t mode = 0; + + f_string_static_t character = macro_f_string_static_t_initialize(text, 4); + + flockfile(main->output.to.stream); + + while (*character.string && F_status_is_error_not(status)) { + + status = utf8_signal_received(main); + + if (status) { + utf8_print_signal_received(main, status); + + status = F_status_set_error(F_signal); + break; + } + else { + status = F_none; + } + + character.used = macro_f_utf_byte_width(*character.string); + + // Re-adjust used if buffer ended before the character is supposed to end. + if (character.string[0]) { + if (character.used > 1) { + if (character.string[1]) { + if (character.used > 2) { + if (character.string[2]) { + if (character.used > 3) { + if (character.string[3]) { + character.used = 4; + } + else { + character.used = 3; + } + } + } + else { + character.used = 2; + } + } + } + else { + character.used = 1; + } + } + } + else { + character.used = 0; + } + + if (main->mode & utf8_mode_from_binary_d) { + status = utf8_convert_binary(main, character); + } + else { + // @todo: check character and determine status. + /*private_utf8_codepoint_modes_ready = 1, + private_utf8_codepoint_modes_begin, + private_utf8_codepoint_modes_number, + private_utf8_codepoint_modes_end, + private_utf8_codepoint_modes_bad,*/ + status = utf8_convert_codepoint(main, character, &mode); + } + + character.string += character.used; + + if (status == F_utf) { + valid = F_false; + } + } // while + + if (F_status_is_error(status)) { + funlockfile(main->output.to.stream); + + return status; + } + + if (main->parameters[utf8_parameter_verify].result == f_console_result_none) { + f_print_character(f_string_eol_s[0], main->output.to.stream); + } + + funlockfile(main->output.to.stream); + + return valid; + } +#endif // _di_utf8_process_text_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/utf8/c/private-utf8.h b/level_3/utf8/c/private-utf8.h new file mode 100644 index 0000000..7c48eeb --- /dev/null +++ b/level_3/utf8/c/private-utf8.h @@ -0,0 +1,179 @@ +/** + * FLL - Level 3 + * + * Project: UTF-8 + * API Version: 0.5 + * Licenses: lgplv2.1 + */ +#ifndef _PRIVATE_utf8_h +#define _PRIVATE_utf8_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @todo make this a define rather than an enum so that "bad/invalid" can be passed along with different state values. + * Or do some sort of trick ("XXX >> 1, to get enum value such that the first bit represents valid/invalid). + * private_utf8_codepoint_modes_*: + * - ready: The codepoint has yet to be processed, skip leading spaces until first 'U' is matched. + * - begin: The first 'U' is matched, look for the '+'. + * - number: The '+' is matched, process numbers. + * - end: The last number is reached (at either whitespace or EOS/EOF). + * - bad: This is not a valid codepoint. + */ +#ifndef _di_private_utf8_codepoint_modes_ + enum { + private_utf8_codepoint_modes_ready = 1, + private_utf8_codepoint_modes_begin, + private_utf8_codepoint_modes_number, + private_utf8_codepoint_modes_end, + private_utf8_codepoint_modes_bad, + }; +#endif // _di_private_utf8_codepoint_modes_ + +/** + * Convert a binary character to another format. + * + * This automatically determines the output format and is also handles the verify process. + * + * @param main + * The main program data. + * @param character + * The a single character to convert. + * This does not stop on NULL and will process all text until text.used. + * + * @return + * F_none on success. + * F_utf on invalid UTF-8 (which is still "success" when verifying). + * + * F_utf (with error bit) if not verifying and + * + * Errors (with error bit) from: f_utf_unicode_to() + */ +#ifndef _di_utf8_convert_binary_ + extern f_status_t utf8_convert_binary(utf8_main_t * const main, const f_string_static_t character) F_attribute_visibility_internal_d; +#endif // _di_utf8_convert_binary_ + +/** + * Convert a codepoint character representation to another format. + * + * This automatically determines the output format and is also handles the verify process. + * + * @param main + * The main program data. + * @param character + * The a single character to convert. + * This does not stop on NULL and will process all text until text.used. + * @param mode + * Designate the mode in which the curent state is being processed. + * + * @return + * F_none on success. + * F_utf on invalid UTF-8 (which is still "success" when verifying). + * + * F_utf (with error bit) if not verifying and + * + * Errors (with error bit) from: f_utf_unicode_to() + */ +#ifndef _di_utf8_convert_codepoint_ + extern f_status_t utf8_convert_codepoint(utf8_main_t * const main, const f_string_static_t text, uint8_t *mode) F_attribute_visibility_internal_d; +#endif // _di_utf8_convert_codepoint_ + +/** + * Process file as a binary input, handling conversion or verification as appropriate. + * + * @param main + * The main program data. + * @param file + * The file stream to process. + * This file may contain NULLs. + * + * @return + * F_true on success and is valid. + * F_false on success and contains invalid sequences. + * F_signal on (exit) signal received. + * + * Errors (with error bit) from: utf8_convert_binary() + * Errors (with error bit) from: utf8_convert_codepoint() + * + * @see utf8_convert_binary() + * @see utf8_signal_received() + */ +#ifndef _di_utf8_process_file_binary_ + extern f_status_t utf8_process_file_binary(utf8_main_t * const main, const f_file_t file) F_attribute_visibility_internal_d; +#endif // _di_utf8_process_file_binary_ + +/** + * Process file as a codepoint input, handling conversion or verification as appropriate. + * + * @param main + * The main program data. + * @param file + * The file stream to process. + * This file may contain NULLs. + * + * @return + * F_true on success and is valid. + * F_false on success and contains invalid sequences. + * F_signal on (exit) signal received. + * + * Errors (with error bit) from: utf8_convert_binary() + * Errors (with error bit) from: utf8_convert_codepoint() + * + * @see utf8_convert_binary() + * @see utf8_convert_codepoint() + * @see utf8_signal_received() + */ +#ifndef _di_utf8_process_file_codepoint_ + extern f_status_t utf8_process_file_codepoint(utf8_main_t * const main, const f_file_t file) F_attribute_visibility_internal_d; +#endif // _di_utf8_process_file_codepoint_ + +/** + * Convert the text from one format to other another format or verify text. + * + * @param main + * The main program data. + * @param text + * This represent a single text data. + * This text is NULL terminated and can therefore not contain any NULLs. + * + * @return + * F_true on success and is valid. + * F_false on success and contains invalid sequences. + * F_signal on (exit) signal received. + * + * Errors (with error bit) from: utf8_convert_binary() + * Errors (with error bit) from: utf8_convert_codepoint() + * + * @see utf8_convert_binary() + * @see utf8_convert_codepoint() + * @see utf8_signal_received() + */ +#ifndef _di_utf8_process_text_ + extern f_status_t utf8_process_text(utf8_main_t * const main, const f_string_t text) F_attribute_visibility_internal_d; +#endif // _di_utf8_process_text_ + +/** + * Check to see if a process signal is received. + * + * Only signals that are blocked via main.signal will be received. + * + * @param main + * The main program data. + * + * @return + * A positive number representing a valid signal on signal received. + * F_false on no signal received. + * + * @see f_signal_read() + */ +#ifndef _di_utf8_signal_received_ + extern f_status_t utf8_signal_received(utf8_main_t * const main); +#endif // _di_utf8_signal_received_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_utf8_h diff --git a/level_3/utf8/c/utf8.c b/level_3/utf8/c/utf8.c new file mode 100644 index 0000000..7839c0f --- /dev/null +++ b/level_3/utf8/c/utf8.c @@ -0,0 +1,470 @@ +#include "utf8.h" +#include "private-common.h" +#include "private-utf8.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_print_help_ + f_status_t utf8_print_help(const f_file_t file, const f_color_context_t context) { + + flockfile(file.stream); + + fll_program_print_help_header(file, context, utf8_program_name_long_s, utf8_version_s); + + fll_program_print_help_option(file, context, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message."); + fll_program_print_help_option(file, context, f_console_standard_short_dark_s, f_console_standard_long_dark_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on dark backgrounds."); + fll_program_print_help_option(file, context, f_console_standard_short_light_s, f_console_standard_long_light_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on light backgrounds."); + fll_program_print_help_option(file, context, f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, "Do not file in color."); + fll_program_print_help_option(file, context, f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, silencing most output."); + fll_program_print_help_option(file, context, f_console_standard_short_normal_s, f_console_standard_long_normal_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Set verbosity to normal file."); + fll_program_print_help_option(file, context, f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Increase verbosity beyond normal output."); + fll_program_print_help_option(file, context, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, significantly increasing verbosity beyond normal output."); + fll_program_print_help_option(file, context, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number."); + + f_print_character(f_string_eol_s[0], file.stream); + + fll_program_print_help_option(file, context, utf8_short_from_binary_s, utf8_long_from_binary_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The expected input format is binary (character data)."); + fll_program_print_help_option(file, context, utf8_short_from_codepoint_s, utf8_long_from_codepoint_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The expected input format is codepoint (such as U+0000)."); + fll_program_print_help_option(file, context, utf8_short_from_file_s, utf8_long_from_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use the given file as the input source."); + + f_print_character(f_string_eol_s[0], file.stream); + + fll_program_print_help_option(file, context, utf8_short_to_binary_s, utf8_long_to_binary_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The output format is binary (character data)."); + fll_program_print_help_option(file, context, utf8_short_to_codepoint_s, utf8_long_to_codepoint_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The output format is codepoint (such as U+0000)."); + fll_program_print_help_option(file, context, utf8_short_to_file_s, utf8_long_to_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use the given file as the output destination."); + + f_print_character(f_string_eol_s[0], file.stream); + + fll_program_print_help_option(file, context, utf8_short_headers_s, utf8_long_headers_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print headers for each section (pipe, file, or parameter)."); + fll_program_print_help_option(file, context, utf8_short_strip_invalid_s, utf8_long_strip_invalid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Strip invalid Unicode characters."); + fll_program_print_help_option(file, context, utf8_short_verify_s, utf8_long_verify_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Only perform verification of valid sequences."); + + f_print_character(f_string_eol_s[0], file.stream); + f_print_character(f_string_eol_s[0], file.stream); + + fll_program_print_help_usage(file, context, utf8_program_name_s, "filename(s)"); + + fl_print_format(" The default behavior is to assume the expected input is binary from the command line to be output to the screen as codepoints.%c%c", file.stream, f_string_eol_s[0], f_string_eol_s[0]); + + fl_print_format(" Multiple input sources are allowed but only a single output destination is allowed.%c%c", file.stream, f_string_eol_s[0], f_string_eol_s[0]); + + fl_print_format(" When using the parameter '%[%s%s%]', only invalid data is printed and 0 is returned if valid or 1 is returned if invalid.%c", file.stream, context.set.notable, f_console_symbol_long_enable_s, utf8_long_verify_s, context.set.notable, f_string_eol_s[0]); + + funlockfile(file.stream); + + return F_none; + } +#endif // _di_utf8_print_help_ + +#ifndef _di_utf8_main_ + f_status_t utf8_main(utf8_main_t * const main, const f_console_arguments_t *arguments) { + + f_status_t status = F_none; + + { + const f_console_parameters_t parameters = macro_f_console_parameters_t_initialize(main->parameters, utf8_total_parameters_d); + + // Identify priority of color parameters. + { + f_console_parameter_id_t ids[3] = { utf8_parameter_no_color, utf8_parameter_light, utf8_parameter_dark }; + const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 3); + + status = fll_program_parameter_process(*arguments, parameters, choices, F_true, &main->remaining, &main->context); + + main->output.set = &main->context.set; + main->error.set = &main->context.set; + main->warning.set = &main->context.set; + + if (main->context.set.error.before) { + main->output.context = f_color_set_empty_s; + main->output.notable = main->context.set.notable; + + main->error.context = main->context.set.error; + main->error.notable = main->context.set.notable; + + main->warning.context = main->context.set.warning; + main->warning.notable = main->context.set.notable; + } + else { + f_color_set_t *sets[] = { &main->output.context, &main->output.notable, &main->error.context, &main->error.notable, &main->warning.context, &main->warning.notable, 0 }; + + fll_program_parameter_process_empty(&main->context, sets); + } + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process", F_true); + + utf8_main_delete(main); + + return F_status_set_error(status); + } + } + + // Identify priority of verbosity related parameters. + { + f_console_parameter_id_t ids[4] = { utf8_parameter_verbosity_quiet, utf8_parameter_verbosity_normal, utf8_parameter_verbosity_verbose, utf8_parameter_verbosity_debug }; + f_console_parameter_id_t choice = 0; + const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 4); + + status = f_console_parameter_prioritize_right(parameters, choices, &choice); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_console_parameter_prioritize_right", F_true); + + utf8_main_delete(main); + + return status; + } + + if (choice == utf8_parameter_verbosity_quiet) { + main->output.verbosity = f_console_verbosity_quiet; + main->error.verbosity = f_console_verbosity_quiet; + main->warning.verbosity = f_console_verbosity_quiet; + } + else if (choice == utf8_parameter_verbosity_normal) { + main->output.verbosity = f_console_verbosity_normal; + main->error.verbosity = f_console_verbosity_normal; + main->warning.verbosity = f_console_verbosity_normal; + } + else if (choice == utf8_parameter_verbosity_verbose) { + main->output.verbosity = f_console_verbosity_verbose; + main->error.verbosity = f_console_verbosity_verbose; + main->warning.verbosity = f_console_verbosity_verbose; + } + else if (choice == utf8_parameter_verbosity_debug) { + main->output.verbosity = f_console_verbosity_debug; + main->error.verbosity = f_console_verbosity_debug; + main->warning.verbosity = f_console_verbosity_debug; + } + } + + // Identify and prioritize from mode parameters. + { + f_console_parameter_id_t ids[4] = { utf8_parameter_from_binary, utf8_parameter_from_codepoint }; + f_console_parameter_id_t choice = 0; + const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 2); + + status = f_console_parameter_prioritize_right(parameters, choices, &choice); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_console_parameter_prioritize_right", F_true); + + utf8_main_delete(main); + + return status; + } + + if (choice == utf8_parameter_from_binary) { + if (main->mode & utf8_mode_from_codepoint_d) { + main->mode -= utf8_mode_from_codepoint_d; + } + + main->mode |= utf8_mode_from_binary_d; + } + else if (choice == utf8_parameter_from_codepoint) { + if (main->mode & utf8_mode_from_binary_d) { + main->mode -= utf8_mode_from_binary_d; + } + + main->mode |= utf8_mode_from_codepoint_d; + } + } + + // Identify and prioritize to mode parameters. + { + f_console_parameter_id_t ids[4] = { utf8_parameter_to_binary, utf8_parameter_to_codepoint }; + f_console_parameter_id_t choice = 0; + const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 2); + + status = f_console_parameter_prioritize_right(parameters, choices, &choice); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_console_parameter_prioritize_right", F_true); + + utf8_main_delete(main); + + return status; + } + + if (choice == utf8_parameter_to_binary) { + if (main->mode & utf8_mode_to_codepoint_d) { + main->mode -= utf8_mode_to_codepoint_d; + } + + main->mode |= utf8_mode_to_binary_d; + } + else if (choice == utf8_parameter_to_codepoint) { + if (main->mode & utf8_mode_to_binary_d) { + main->mode -= utf8_mode_to_binary_d; + } + + main->mode |= utf8_mode_to_codepoint_d; + } + } + + status = F_none; + } + + if (main->parameters[utf8_parameter_help].result == f_console_result_found) { + utf8_print_help(main->output.to, main->context); + + utf8_main_delete(main); + return F_none; + } + + if (main->parameters[utf8_parameter_version].result == f_console_result_found) { + fll_program_print_version(main->output.to, utf8_version_s); + + utf8_main_delete(main); + return F_none; + } + + if (main->parameters[utf8_parameter_from_binary].result == f_console_result_found) { + if (main->parameters[utf8_parameter_from_codepoint].result == f_console_result_found) { + utf8_print_error_parameter_conflict(main, utf8_long_from_binary_s, utf8_long_from_codepoint_s); + + status = F_status_set_error(F_parameter); + } + } + + if (F_status_is_error_not(status) && main->parameters[utf8_parameter_to_binary].result == f_console_result_found) { + if (main->parameters[utf8_parameter_to_codepoint].result == f_console_result_found) { + utf8_print_error_parameter_conflict(main, utf8_long_to_binary_s, utf8_long_to_codepoint_s); + + status = F_status_set_error(F_parameter); + } + } + + if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { + if (main->parameters[utf8_parameter_strip_invalid].result == f_console_result_found) { + utf8_print_error_parameter_conflict(main, utf8_long_verify_s, utf8_long_strip_invalid_s); + + status = F_status_set_error(F_parameter); + } + } + + if (F_status_is_error_not(status)) { + if (main->parameters[utf8_parameter_from_file].result == f_console_result_additional) { + f_array_length_t i = 0; + f_array_length_t index = 0; + + for (; i < main->parameters[utf8_parameter_from_file].values.used; ++i) { + + index = main->parameters[utf8_parameter_from_file].values.array[i]; + + if (arguments->argv[index][0]) { + if (!f_file_exists(arguments->argv[index])) { + utf8_print_error_parameter_file_not_found(main, F_true, arguments->argv[index]); + + if (F_status_is_error_not(status)) { + status = F_status_set_error(F_file_found_not); + } + } + } + else { + utf8_print_error_parameter_file_name_empty(main, index); + + if (F_status_is_error_not(status)) { + status = F_status_set_error(F_parameter); + } + } + } // for + } + else if (main->parameters[utf8_parameter_from_file].result == f_console_result_found) { + utf8_print_error_no_value(main, utf8_long_from_file_s); + + status = F_status_set_error(F_parameter); + } + } + + bool valid = F_true; + + if (F_status_is_error_not(status)) { + if (main->parameters[utf8_parameter_to_file].result == f_console_result_additional) { + if (main->parameters[utf8_parameter_to_file].values.used > 1) { + utf8_print_error_parameter_file_to_too_many(main); + + status = F_status_set_error(F_parameter); + } + else { + const f_array_length_t index = main->parameters[utf8_parameter_to_file].values.array[0]; + + if (arguments->argv[index][0]) { + if (!f_file_exists(arguments->argv[index])) { + utf8_print_error_parameter_file_not_found(main, F_false, arguments->argv[index]); + + status = F_status_set_error(F_file_found_not); + } + } + else { + utf8_print_error_parameter_file_name_empty(main, index); + + status = F_status_set_error(F_parameter); + } + } + } + else if (main->parameters[utf8_parameter_to_file].result == f_console_result_found) { + utf8_print_error_no_value(main, utf8_long_to_file_s); + + status = F_status_set_error(F_parameter); + } + else { + main->destination = main->output.to; + } + } + + if (F_status_is_error_not(status)) { + if (main->parameters[utf8_parameter_from_file].result == f_console_result_none && !(main->process_pipe || main->remaining.used)) { + utf8_print_error_no_from(main); + + status = F_status_set_error(F_parameter); + } + } + + if (F_status_is_error_not(status)) { + status = F_none; + + if (main->process_pipe) { + f_file_t file = f_file_t_initialize; + + file.id = F_type_descriptor_input_d; + file.stream = F_type_input_d; + + utf8_print_section_header_pipe(main); + + if (main->mode & utf8_mode_from_binary_d) { + status = utf8_process_file_binary(main, file); + } + else { + status = utf8_process_file_codepoint(main, file); + } + + if (F_status_is_error(status)) { + fll_error_file_print(main->error, F_status_set_fine(status), main->mode & utf8_mode_from_binary_d ? "utf8_process_file_binary" : "utf8_process_file_codepoint", F_true, 0, utf8_string_process_s, fll_error_file_type_pipe); + } + } + + if (F_status_is_error_not(status) && status != F_signal && main->parameters[utf8_parameter_from_file].result == f_console_result_additional) { + f_array_length_t i = 0; + f_array_length_t index = 0; + + f_file_t file = f_file_t_initialize; + file.size_read = 32768; + + for (; i < main->parameters[utf8_parameter_from_file].values.used && status != F_signal; ++i) { + + if (utf8_signal_received(main)) { + status = F_status_set_error(F_signal); + break; + } + + index = main->parameters[utf8_parameter_from_file].values.array[i]; + + utf8_print_section_header_file(main, arguments->argv[index]); + + status = f_file_stream_open(arguments->argv[index], 0, &file); + + if (F_status_is_error(status)) { + fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_open", F_true, arguments->argv[index], utf8_string_open_s, fll_error_file_type_file); + + break; + } + + if (main->mode & utf8_mode_from_binary_d) { + status = utf8_process_file_binary(main, file); + } + else { + status = utf8_process_file_codepoint(main, file); + } + + f_file_stream_close(F_true, &file); + + if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { + if (status == F_false) { + valid = F_false; + } + } + + if (F_status_is_error(status)) { + fll_error_file_print(main->error, F_status_set_fine(status), main->mode & utf8_mode_from_binary_d ? "utf8_process_file_binary" : "utf8_process_file_codepoint", F_true, arguments->argv[index], utf8_string_process_s, fll_error_file_type_file); + + break; + } + } // for + } + + if (F_status_is_error_not(status) && status != F_signal && main->remaining.used) { + f_array_length_t i = 0; + f_array_length_t index = 0; + + for (; F_status_is_error_not(status) && i < main->remaining.used; ++i) { + + if (utf8_signal_received(main)) { + status = F_status_set_error(F_signal); + break; + } + + index = main->remaining.array[i]; + + utf8_print_section_header_parameter(main, index); + + status = utf8_process_text(main, arguments->argv[index]); + + if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { + if (status == F_false) { + valid = F_false; + } + } + } // for + } + } + + if (main->output.verbosity != f_console_verbosity_quiet) { + if (F_status_set_fine(status) == F_interrupt) { + fflush(main->output.to.stream); + } + + fll_print_terminated(f_string_eol_s, main->output.to.stream); + } + + utf8_main_delete(main); + + if (F_status_is_error(status)) { + return status; + } + + return valid; + } +#endif // _di_utf8_main_ + +#ifndef _di_utf8_main_delete_ + f_status_t utf8_main_delete(utf8_main_t *main) { + + for (f_array_length_t i = 0; i < utf8_total_parameters_d; ++i) { + + macro_f_array_lengths_t_delete_simple(main->parameters[i].locations); + macro_f_array_lengths_t_delete_simple(main->parameters[i].locations_sub); + macro_f_array_lengths_t_delete_simple(main->parameters[i].values); + } // for + + macro_f_string_dynamic_t_delete_simple(main->buffer); + macro_f_string_dynamic_t_delete_simple(main->file_input); + macro_f_string_dynamic_t_delete_simple(main->file_output); + macro_f_string_dynamic_t_delete_simple(main->text); + + macro_f_string_dynamic_t_delete_simple(main->separate_character); + macro_f_string_dynamic_t_delete_simple(main->separate_source); + + macro_f_array_lengths_t_delete_simple(main->remaining); + + macro_f_color_context_t_delete_simple(main->context); + + return F_none; + } +#endif // _di_utf8_main_delete_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/utf8/c/utf8.h b/level_3/utf8/c/utf8.h new file mode 100644 index 0000000..585d05e --- /dev/null +++ b/level_3/utf8/c/utf8.h @@ -0,0 +1,311 @@ +/** + * FLL - Level 3 + * + * Project: UTF-8 + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * This is intendend to support Unicode 14.0. + * + * This is a program for handling basic UTF-8 related conversions. + * - Convert from UTF-8 character to binary. + * - Convert from Unicode Codepoint (such as U+0000) to binary. + * - Convert from UTF-8 binary to character. + * - Convert from UTF-8 binary to Unicode Codepoint (such as U+0000). + */ +#ifndef _utf8_h + +// libc includes +#include +#include +#include +#include + +// fll-0 includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fll-1 includes +#include +#include +#include +#include +#include + +// fll-2 includes +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_program_version_ + #define utf8_program_version_major_s F_string_ascii_0_s + #define utf8_program_version_minor_s F_string_ascii_5_s + #define utf8_program_version_micro_s F_string_ascii_7_s + + #ifndef utf8_program_version_nano_prefix_s + #define utf8_program_version_nano_prefix_s + #endif + + #ifndef utf8_program_version_nano_s + #define utf8_program_version_nano_s + #endif + + #define utf8_version_s utf8_program_version_major_s F_string_ascii_period_s utf8_program_version_minor_s F_string_ascii_period_s utf8_program_version_micro_s utf8_program_version_nano_prefix_s utf8_program_version_nano_s +#endif // _di_utf8_program_version_ + +#ifndef _di_utf8_program_name_ + #define utf8_program_name_s "utf8" + #define utf8_program_name_long_s "UTF-8" +#endif // _di_utf8_program_name_ + +/** + * Set to at least 4 to provide a UTF-8 friendly allocation step. + */ +#ifndef _di_utf8_default_allocation_step_ + #define utf8_default_allocation_step_d 4 +#endif // _di_utf8_default_allocation_step_ + +#ifndef _di_utf8_defines_ + #define utf8_string_from_s "from" + #define utf8_string_to_s "to" + + #define utf8_string_open_s "open" + #define utf8_string_process_s "process" + + #define utf8_string_verified_valid_s "Verified Valid" + #define utf8_string_verified_valid_not_s "Verified Invalid" + + #define utf8_string_from_s_length 4 + #define utf8_string_to_s_length 2 + + #define utf8_string_open_s_length 4 + #define utf8_string_process_s_length 7 + + #define utf8_string_verified_valid_s_length 14 + #define utf8_string_verified_valid_not_s_length 16 + + #define utf8_character_valid_not_s "�" + + #define utf8_short_from_binary_s "b" + #define utf8_short_from_codepoint_s "c" + #define utf8_short_from_file_s "f" + + #define utf8_short_headers_s "H" + #define utf8_short_strip_invalid_s "s" + #define utf8_short_verify_s "v" + + #define utf8_short_to_binary_s "B" + #define utf8_short_to_codepoint_s "C" + #define utf8_short_to_file_s "F" + + #define utf8_long_from_binary_s "from_binary" + #define utf8_long_from_codepoint_s "from_codepoint" + #define utf8_long_from_file_s "from_file" + + #define utf8_long_headers_s "headers" + #define utf8_long_strip_invalid_s "strip_invalid" + #define utf8_long_verify_s "verify" + + #define utf8_long_to_binary_s "to_binary" + #define utf8_long_to_codepoint_s "to_codepoint" + #define utf8_long_to_file_s "to_file" + + enum { + utf8_parameter_help, + utf8_parameter_light, + utf8_parameter_dark, + utf8_parameter_no_color, + utf8_parameter_verbosity_quiet, + utf8_parameter_verbosity_normal, + utf8_parameter_verbosity_verbose, + utf8_parameter_verbosity_debug, + utf8_parameter_version, + + utf8_parameter_from_binary, + utf8_parameter_from_codepoint, + utf8_parameter_from_file, + + utf8_parameter_headers, + utf8_parameter_strip_invalid, + + utf8_parameter_to_binary, + utf8_parameter_to_codepoint, + utf8_parameter_to_file, + + utf8_parameter_verify, + }; + + #define utf8_console_parameter_t_initialize \ + { \ + f_console_parameter_t_initialize(f_console_standard_short_help_s, f_console_standard_long_help_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(f_console_standard_short_light_s, f_console_standard_long_light_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_dark_s, f_console_standard_long_dark_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_normal_s, f_console_standard_long_normal_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_debug_s, f_console_standard_long_debug_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(f_console_standard_short_version_s, f_console_standard_long_version_s, 0, 0, f_console_type_inverse), \ + f_console_parameter_t_initialize(utf8_short_from_binary_s, utf8_long_from_binary_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_from_codepoint_s, utf8_long_from_codepoint_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_from_file_s, utf8_long_from_file_s, 0, 1, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_headers_s, utf8_long_headers_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_strip_invalid_s, utf8_long_strip_invalid_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_to_binary_s, utf8_long_to_binary_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_to_codepoint_s, utf8_long_to_codepoint_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_to_file_s, utf8_long_to_file_s, 0, 1, f_console_type_normal), \ + f_console_parameter_t_initialize(utf8_short_verify_s, utf8_long_verify_s, 0, 0, f_console_type_normal), \ + } + + #define utf8_total_parameters_d 18 +#endif // _di_utf8_defines_ + +/** + * utf8_mode_from_*: + * - binary: The input source is binary. + * - codepoint: The input source is codepoint (U+XXXX or U+XXXXXX). + * + * utf8_mode_to_*: + * - binary: The outout destination is binary. + * - codepoint: The outout destination is codepoint (U+XXXX or U+XXXXXX). + */ +#ifndef _di_utf8_modes_ + #define utf8_mode_from_binary_d 0x1 + #define utf8_mode_from_codepoint_d 0x2 + #define utf8_mode_to_binary_d 0x4 + #define utf8_mode_to_codepoint_d 0x8 +#endif // _di_utf8_modes_ + +#ifndef _di_utf8_main_t_ + typedef struct { + f_console_parameter_t parameters[utf8_total_parameters_d]; + + f_array_lengths_t remaining; + bool process_pipe; + + fl_print_t output; + fl_print_t error; + fl_print_t warning; + + f_signal_t signal; + + f_file_t destination; + uint8_t mode; + + f_string_dynamic_t buffer; + f_string_dynamic_t file_input; + f_string_dynamic_t file_output; + f_string_dynamic_t text; + + f_string_dynamic_t separate_character; + f_string_dynamic_t separate_source; + + f_color_context_t context; + } utf8_main_t; + + #define utf8_main_t_initialize \ + { \ + utf8_console_parameter_t_initialize, \ + f_array_lengths_t_initialize, \ + F_false, \ + fl_print_t_initialize, \ + macro_fl_print_t_initialize_error(), \ + macro_fl_print_t_initialize_warning(), \ + f_signal_t_initialize, \ + f_file_t_initialize, \ + utf8_mode_from_binary_d | utf8_mode_to_codepoint_d, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_color_context_t_initialize, \ + } +#endif // _di_utf8_main_t_ + +/** + * Print help. + * + * @param file + * The file to print to. + * @param context + * The color context settings. + * + * @return + * F_none on success. + */ +#ifndef _di_utf8_print_help_ + extern f_status_t utf8_print_help(const f_file_t file, const f_color_context_t context); +#endif // _di_utf8_print_help_ + +/** + * Execute main program. + * + * Be sure to call utf8_main_delete() after executing this. + * + * If main.signal is non-zero, then this blocks and handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * @param main + * The main program data. + * @param arguments + * The parameters passed to the process. + * + * @return + * F_none on success. + * F_true on success when performing verification and verify passed. + * F_false on success when performing verification and verify failed. + * F_signal on (exit) signal received. + * + * Status codes (with error bit) are returned on any problem. + * + * @see utf8_main_delete() + */ +#ifndef _di_utf8_main_ + extern f_status_t utf8_main(utf8_main_t * const main, const f_console_arguments_t *arguments); +#endif // _di_utf8_main_ + +/** + * Deallocate main. + * + * Be sure to call this after executing utf8_main(). + * + * @param main + * The main program data. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @see utf8_main() + */ +#ifndef _di_utf8_main_delete_ + extern f_status_t utf8_main_delete(utf8_main_t *main); +#endif // _di_utf8_main_delete_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _utf8_h diff --git a/level_3/utf8/data/build/defines b/level_3/utf8/data/build/defines new file mode 100644 index 0000000..c665317 --- /dev/null +++ b/level_3/utf8/data/build/defines @@ -0,0 +1,2 @@ +# fss-0000 + diff --git a/level_3/utf8/data/build/dependencies b/level_3/utf8/data/build/dependencies new file mode 100644 index 0000000..fa07553 --- /dev/null +++ b/level_3/utf8/data/build/dependencies @@ -0,0 +1,21 @@ +# fss-0000 + +f_type +f_status +f_memory +f_string +f_utf +f_color +f_console +f_conversion +f_file +f_pipe +f_print +f_signal +fl_console +fl_conversion +fl_print +fl_string +fll_error +fll_print +fll_program diff --git a/level_3/utf8/data/build/settings b/level_3/utf8/data/build/settings new file mode 100644 index 0000000..2de6a54 --- /dev/null +++ b/level_3/utf8/data/build/settings @@ -0,0 +1,78 @@ +# fss-0001 + +project_name utf8 + +version_major 0 +version_minor 5 +version_micro 7 +version_file micro +version_target minor + +environment + +process_pre +process_post + +modes individual level monolithic +modes_default monolithic + +build_compiler gcc +build_indexer ar +build_indexer_arguments rcs +build_language c +build_libraries -lc +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf +build_libraries-level -lfll_2 -lfll_1 -lfll_0 +build_libraries-monolithic -lfll +build_libraries_shared +build_libraries_static +build_sources_library utf8.c private-common.c private-utf8.c +build_sources_library_shared +build_sources_library_static +build_sources_program main.c +build_sources_program_shared +build_sources_program_static +build_sources_headers utf8.h +build_sources_headers_shared +build_sources_headers_static +build_sources_script +build_sources_setting +build_script yes +build_shared yes +build_static no + +path_headers program/utf8 +path_headers_preserve no +path_library_script script +path_library_shared shared +path_library_static static +path_program_script script +path_program_shared shared +path_program_static static +path_sources +path_standard yes + +search_exclusive yes +search_shared yes +search_static yes + +#defines -D_di_libcap_ -D_di_thread_support_ +defines -D_libcap_legacy_only_ -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_ +defines_library +defines_library_shared +defines_library_static +defines_program +defines_program_shared +defines_program_static +defines_static +defines_shared + +flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses +flags_library -fPIC +flags_library_shared +flags_library_static +flags_program -fPIE +flags_program_shared +flags_program_static +flags_shared +flags_static -- 1.8.3.1