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.
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_
#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.
}
#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) {
#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
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);
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;
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// fll-0 includes
+#include <fll/level_0/type.h>
+#include <fll/level_0/status.h>
+#include <fll/level_0/memory.h>
+#include <fll/level_0/string.h>
+#include <fll/level_0/utf.h>
+#include <fll/level_0/color.h>
+#include <fll/level_0/console.h>
+#include <fll/level_0/conversion.h>
+#include <fll/level_0/file.h>
+#include <fll/level_0/pipe.h>
+#include <fll/level_0/print.h>
+#include <fll/level_0/signal.h>
+
+// fll-1 includes
+#include <fll/level_1/console.h>
+#include <fll/level_1/conversion.h>
+#include <fll/level_1/print.h>
+#include <fll/level_1/string.h>
+#include <fll/level_1/utf.h>
+
+// fll-2 includes
+#include <fll/level_2/error.h>
+#include <fll/level_2/print.h>
+#include <fll/level_2/program.h>
+
+#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
--- /dev/null
+# fss-0000
+
--- /dev/null
+# 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
--- /dev/null
+# 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