Begin the process of adding the IKI Read program.
--- /dev/null
+#include <level_3/iki_read.h>
+#include "private-iki_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_read_print_help_
+ f_return_status iki_read_print_help(const fl_color_context context) {
+ fll_program_print_help_header(context, iki_read_name_long, iki_read_version);
+
+ fll_program_print_help_option(context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message.");
+ fll_program_print_help_option(context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds.");
+ fll_program_print_help_option(context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds.");
+ fll_program_print_help_option(context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color.");
+ fll_program_print_help_option(context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output.");
+ fll_program_print_help_option(context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output.");
+ fll_program_print_help_option(context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number.");
+
+ printf("%c", f_string_eol[0]);
+
+ fll_program_print_help_option(context, iki_read_short_at, iki_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select variable at this numeric index.");
+ fll_program_print_help_option(context, iki_read_short_line, iki_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, "Print only the variables at the given line.");
+ fll_program_print_help_option(context, iki_read_short_name, iki_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, "Select variables with this name.");
+
+ printf("%c", f_string_eol[0]);
+
+ fll_program_print_help_option(context, iki_read_short_literal, iki_read_long_literal, f_console_symbol_short_enable, f_console_symbol_long_enable, "Print the entire variable instead of the content.");
+ fll_program_print_help_option(context, iki_read_short_object, iki_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the variable name instead of the variable content.");
+ fll_program_print_help_option(context, iki_read_short_raw, iki_read_long_raw, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the raw data instead of the variable data.");
+ fll_program_print_help_option(context, iki_read_short_total, iki_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of variables.");
+
+ printf("%c", f_string_eol[0]);
+
+ fll_program_print_help_option(context, iki_read_short_substitute, iki_read_long_substitute, f_console_symbol_short_enable, f_console_symbol_long_enable,"Substitute the entire variable for the given name and content value with the given string.");
+ fll_program_print_help_option(context, iki_read_short_expand, iki_read_long_expand, f_console_symbol_short_enable, f_console_symbol_long_enable, " Expand all values.");
+
+ fll_program_print_help_usage(context, iki_read_name, "filename(s)");
+
+ fl_color_print(f_type_output, context.important, context.reset, " Notes:");
+
+ printf("%c", f_string_eol[0], f_string_eol[0]);
+
+ printf(" This program will find and print all content following the IKI standard, without focusing on any particular vocabulary specification.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
+ printf(" The ");
+ fl_color_print(f_type_output, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_substitute);
+ printf(" option, requires 3 additional parameters: ");
+
+ fl_color_print(f_type_output, context.notable, context.reset, "<");
+ printf("%s", iki_read_replacement_vocabulary);
+ fl_color_print(f_type_output, context.notable, context.reset, ">");
+ printf(" ");
+ fl_color_print(f_type_output, context.notable, context.reset, "<");
+ printf("%s", iki_read_replacement_replace);
+ fl_color_print(f_type_output, context.notable, context.reset, ">");
+ printf(" ");
+ fl_color_print(f_type_output, context.notable, context.reset, "<");
+ printf("%s", iki_read_replacement_with);
+ fl_color_print(f_type_output, context.notable, context.reset, ">");
+ printf(".%c", f_string_eol[0]);
+
+ fl_color_print(f_type_output, context.notable, context.reset, " %s", iki_read_replacement_vocabulary);
+ printf(": The name of the vocabulary whose content is to be substituted.%c", f_string_eol[0]);
+
+ fl_color_print(f_type_output, context.notable, context.reset, " %s", iki_read_replacement_replace);
+ printf(": The content matching this exact string will be substituted.%c", f_string_eol[0]);
+
+ fl_color_print(f_type_output, context.notable, context.reset, " %s", iki_read_replacement_with);
+ printf(": The new string to use as the substitute.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
+ printf(" The vocabulary and replacement are case-sensitive and must exactly match.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
+ return F_none;
+ }
+#endif // _di_iki_read_print_help_
+
+#ifndef _di_iki_read_main_
+ f_return_status iki_read_main(const f_console_arguments arguments, iki_read_data *data) {
+ f_status status = F_none;
+
+ {
+ f_console_parameters parameters = { data->parameters, iki_read_total_parameters };
+ f_console_parameter_id ids[3] = { iki_read_parameter_no_color, iki_read_parameter_light, iki_read_parameter_dark };
+ f_console_parameter_ids choices = { ids, 3 };
+
+ status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context);
+
+ if (F_status_is_error(status)) {
+ iki_read_delete_data(data);
+ return F_status_set_error(status);
+ }
+
+ status = F_none;
+ }
+
+ if (data->parameters[iki_read_parameter_help].result == f_console_result_found) {
+ iki_read_print_help(data->context);
+
+ iki_read_delete_data(data);
+ return status;
+ }
+ else if (data->parameters[iki_read_parameter_version].result == f_console_result_found) {
+ fll_program_print_version(iki_read_version);
+
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ if (data->parameters[iki_read_parameter_verbose].result == f_console_result_found) {
+ if (data->parameters[iki_read_parameter_quiet].result == f_console_result_found) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, f_console_standard_long_verbose);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, f_console_standard_long_quiet);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ data->verbosity = iki_read_verbosity_verbose;
+ }
+ else if (data->parameters[iki_read_parameter_quiet].result == f_console_result_found) {
+ data->verbosity = iki_read_verbosity_quiet;
+ }
+ else {
+ data->verbosity = iki_read_verbosity_normal;
+ }
+
+ if (data->remaining.used > 0 || data->process_pipe) {
+ if (data->parameters[iki_read_parameter_at].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_at);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a positive number.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ if (data->parameters[iki_read_parameter_line].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_line);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a positive number.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+ else if (data->parameters[iki_read_parameter_line].result == f_console_result_additional) {
+ const f_string_length index = data->parameters[iki_read_parameter_line].additional.array[data->parameters[iki_read_parameter_line].additional.used - 1];
+
+ status = fl_console_parameter_to_number_unsigned(arguments.argv[index], &data->line);
+ if (F_status_is_error(status)) {
+ iki_read_print_error_number_argument(data->context, data->verbosity, F_status_set_fine(status), "fl_console_parameter_to_number_unsigned", iki_read_long_line, arguments.argv[index]);
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ // additional
+ }
+
+ if (data->parameters[iki_read_parameter_name].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_name);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a string.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ if (data->parameters[iki_read_parameter_substitute].result != f_console_result_none) {
+ if (data->parameters[iki_read_parameter_substitute].result == f_console_result_found || data->parameters[iki_read_parameter_substitute].additional.used % 3 != 0) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_substitute);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires 3 strings.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+ }
+
+ if (data->parameters[iki_read_parameter_literal].result == f_console_result_found) {
+ if (data->parameters[iki_read_parameter_object].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ if (data->parameters[iki_read_parameter_total].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ data->mode = iki_read_mode_literal;
+ }
+ else if (data->parameters[iki_read_parameter_object].result == f_console_result_found) {
+ if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ if (data->parameters[iki_read_parameter_total].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ data->mode = iki_read_mode_object;
+ }
+ else if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) {
+ if (data->parameters[iki_read_parameter_total].result == f_console_result_found) {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_read_delete_data(data);
+ return F_status_set_error(F_parameter);
+ }
+
+ data->mode = iki_read_mode_raw;
+ }
+ else if (data->parameters[iki_read_parameter_total].result == f_console_result_found) {
+ data->mode = iki_read_mode_total;
+ }
+ else {
+ data->mode = iki_read_mode_content;
+ }
+
+ if (data->process_pipe) {
+ f_file file = f_file_initialize;
+
+ file.id = f_type_descriptor_input;
+
+ status = f_file_read(file, &data->buffer);
+
+ if (F_status_is_error(status)) {
+ iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_read", "-", "process", F_true, F_true);
+
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ status = iki_read_main_process_file(arguments, "-", data);
+ if (F_status_is_error(status)) {
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ // Clear buffers before continuing.
+ f_macro_string_dynamic_delete_simple(data->buffer);
+ }
+
+ if (data->remaining.used > 0) {
+ f_string_length i = 0;
+ f_string_length total = 0;
+ f_file file = f_file_initialize;
+
+ for (; i < data->remaining.used; i++) {
+ f_macro_file_reset(file);
+ total = 0;
+
+ status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file);
+ if (F_status_is_error(status)) {
+ iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_open", arguments.argv[data->remaining.array[i]], "process", F_true, F_true);
+
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ status = f_file_size_by_id(file.id, &total);
+ if (F_status_is_error(status)) {
+ iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_size_by_id", arguments.argv[data->remaining.array[i]], "process", F_true, F_true);
+
+ f_file_close(&file.id);
+
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ // Skip past empty files.
+ if (total == 0) {
+ f_file_close(&file.id);
+ continue;
+ }
+
+ status = f_file_read_until(file, &data->buffer, total);
+
+ f_file_close(&file.id);
+
+ if (F_status_is_error(status)) {
+ iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_read_until", arguments.argv[data->remaining.array[i]], "process", F_true, F_true);
+
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ status = iki_read_main_process_file(arguments, arguments.argv[data->remaining.array[i]], data);
+ if (F_status_is_error(status)) {
+ iki_read_delete_data(data);
+ return status;
+ }
+
+ // Clear buffers before repeating the loop.
+ f_macro_string_dynamic_delete_simple(data->buffer);
+ } // for
+ }
+ }
+ else {
+ if (data->verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files.");
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ status = F_status_set_error(F_parameter);
+ }
+
+ iki_read_delete_data(data);
+ return status;
+ }
+#endif // _di_iki_read_main_
+
+#ifndef _di_iki_read_delete_data_
+ f_return_status iki_read_delete_data(iki_read_data *data) {
+ f_status status = F_none;
+ f_string_length i = 0;
+
+ while (i < iki_read_total_parameters) {
+ f_macro_string_lengths_delete_simple(data->parameters[i].locations);
+ f_macro_string_lengths_delete_simple(data->parameters[i].additional);
+ i++;
+ } // while
+
+ f_macro_string_lengths_delete_simple(data->remaining);
+ f_macro_string_dynamic_delete_simple(data->buffer);
+ fl_macro_color_context_delete_simple(data->context);
+
+ return F_none;
+ }
+#endif // _di_iki_read_delete_data_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: IKI
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * This is the FSS Basic Read program
+ * This program utilizes the Featureless Linux Library.
+ * This program processes files or other input in fss format and stores the results in the iki_read_data.
+ *
+ * This processes in accordance to the FSS-0000 Basic specification.
+ */
+#ifndef _iki_read_h
+
+// libc includes
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// fll-0 includes
+#include <level_0/type.h>
+#include <level_0/string.h>
+#include <level_0/console.h>
+#include <level_0/conversion.h>
+#include <level_0/file.h>
+#include <level_0/iki.h>
+#include <level_0/pipe.h>
+#include <level_0/print.h>
+
+// fll-1 includes
+#include <level_1/color.h>
+#include <level_1/console.h>
+#include <level_1/iki.h>
+#include <level_1/print.h>
+#include <level_1/string.h>
+
+// fll-2 includes
+#include <level_2/file.h>
+#include <level_2/program.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_read_version_
+ #define iki_read_major_version "0"
+ #define iki_read_minor_version "5"
+ #define iki_read_micro_version "0"
+ #define iki_read_version iki_read_major_version "." iki_read_minor_version "." iki_read_micro_version
+#endif // _di_iki_read_version_
+
+#ifndef _di_iki_read_name_
+ #define iki_read_name "IKI_read"
+ #define iki_read_name_long "IKI Read"
+#endif // _di_iki_read_name_
+
+#ifndef _di_iki_read_defines_
+ enum {
+ iki_read_mode_content = 1,
+ iki_read_mode_literal,
+ iki_read_mode_object,
+ iki_read_mode_raw,
+ iki_read_mode_total,
+ };
+
+ enum {
+ iki_read_verbosity_quiet = 1,
+ iki_read_verbosity_normal,
+ iki_read_verbosity_verbose,
+ iki_read_verbosity_debug,
+ };
+
+ #define iki_read_short_at "a"
+ #define iki_read_short_expand "e"
+ #define iki_read_short_line "l"
+ #define iki_read_short_literal "L"
+ #define iki_read_short_name "n"
+ #define iki_read_short_object "o"
+ #define iki_read_short_raw "r"
+ #define iki_read_short_substitute "s"
+ #define iki_read_short_total "t"
+
+ #define iki_read_long_at "at"
+ #define iki_read_long_expand "expand"
+ #define iki_read_long_line "line"
+ #define iki_read_long_literal "literal"
+ #define iki_read_long_name "name"
+ #define iki_read_long_object "object"
+ #define iki_read_long_raw "raw"
+ #define iki_read_long_substitute "substitute"
+ #define iki_read_long_total "total"
+
+ enum {
+ iki_read_parameter_help,
+ iki_read_parameter_light,
+ iki_read_parameter_dark,
+ iki_read_parameter_no_color,
+ iki_read_parameter_quiet,
+ iki_read_parameter_verbose,
+ iki_read_parameter_version,
+
+ iki_read_parameter_at,
+ iki_read_parameter_expand,
+ iki_read_parameter_line,
+ iki_read_parameter_literal,
+ iki_read_parameter_name,
+ iki_read_parameter_object,
+ iki_read_parameter_raw,
+ iki_read_parameter_substitute,
+ iki_read_parameter_total,
+ };
+
+ #define f_console_parameter_initialize_iki_read \
+ { \
+ f_console_parameter_initialize(f_console_standard_short_help, f_console_standard_long_help, 0, 0, f_console_type_normal), \
+ f_console_parameter_initialize(f_console_standard_short_light, f_console_standard_long_light, 0, 0, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, 0, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, 0, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_quiet, f_console_standard_long_quiet, 0, 0, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_verbose, f_console_standard_long_verbose, 0, 0, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \
+ f_console_parameter_initialize(iki_read_short_at, iki_read_long_at, 0, 1, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_expand, iki_read_long_expand, 0, 0, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_line, iki_read_long_line, 0, 1, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_literal, iki_read_long_literal, 0, 0, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_name, iki_read_long_name, 0, 1, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_object, iki_read_long_object, 0, 0, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_raw, iki_read_long_raw, 0, 0, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_substitute, iki_read_long_substitute, 0, 3, f_console_type_normal), \
+ f_console_parameter_initialize(iki_read_short_total, iki_read_long_total, 0, 0, f_console_type_normal), \
+ }
+
+ #define iki_read_total_parameters 16
+#endif // _di_iki_read_defines_
+
+#ifndef _di_iki_read_replacement_
+ #define iki_read_replacement_vocabulary "vocabulary"
+ #define iki_read_replacement_replace "replace"
+ #define iki_read_replacement_with "with"
+
+ typedef struct {
+ f_string_dynamic vocabulary;
+ f_string_dynamic replace;
+ f_string_dynamic with;
+ } iki_read_replacement;
+
+ #define iki_read_replacement_initialize \
+ { \
+ f_string_dynamic_initialize, \
+ f_string_dynamic_initialize, \
+ f_string_dynamic_initialize, \
+ }
+
+ #define macro_iki_read_replacement_delete_simple(replacement) \
+ f_macro_string_dynamic_delete_simple(replacement.vocabulary); \
+ f_macro_string_dynamic_delete_simple(replacement.replace); \
+ f_macro_string_dynamic_delete_simple(replacement.with);
+
+ #define macro_iki_read_replacement_destroy_simple(replacement) \
+ f_macro_string_dynamic_destroy_simple(replacement.vocabulary); \
+ f_macro_string_dynamic_destroy_simple(replacement.replace); \
+ f_macro_string_dynamic_destroy_simple(replacement.with);
+#endif // _di_iki_read_replacement_
+
+#ifndef _di_iki_read_replacements_
+ typedef struct {
+ iki_read_replacement *array;
+
+ f_array_length size;
+ f_array_length used;
+ } iki_read_replacements;
+
+ #define iki_read_replacements_initialize {0, 0, 0}
+
+ #define macro_iki_read_replacements_clear(replacements) f_macro_memory_structure_clear(replacements)
+
+ #define macro_iki_read_replacements_new(status, replacements, length) f_macro_memory_structure_new(status, replacements, iki_read_replacement, length)
+
+ #define macro_iki_read_replacements_delete_simple(replacements) \
+ replacements.used = replacements.size; \
+ while (replacements.used > 0) { \
+ replacements.used--; \
+ macro_iki_read_replacement_delete_simple(replacements.array[replacements.used]); \
+ } \
+ if (replacements.used == 0) f_macro_memory_structure_delete_simple(replacements, iki_read_replacement)
+
+ #define macro_iki_read_replacements_destroy_simple(replacements) \
+ replacements.used = replacements.size; \
+ while (replacements.used > 0) { \
+ replacements.used--; \
+ macro_iki_read_replacement_destroy_simple(replacements.array[replacements.used]); \
+ } \
+ if (replacements.used == 0) f_macro_memory_structure_destroy_simple(replacements, iki_read_replacement)
+
+ #define macro_iki_read_replacements_resize(status, replacements, new_length) \
+ status = F_none; \
+ if (new_length < replacements.size) { \
+ f_array_length i = replacements.size - new_length; \
+ for (; i < replacements.size; i++) { \
+ macro_iki_read_replacement_delete(status, replacements.array[i]); \
+ if (status != F_none) break; \
+ } \
+ } \
+ if (status == F_none) status = f_memory_resize((void **) & replacements.array, sizeof(iki_read_replacement), replacements.size, new_length); \
+ if (status == F_none) { \
+ if (new_length > replacements.size) { \
+ f_array_length i = replacements.size; \
+ for (; i < new_length; i++) { \
+ memset(&replacements.array[i], 0, sizeof(iki_read_replacement)); \
+ } \
+ } \
+ replacements.size = new_length; \
+ if (replacements.used > replacements.size) replacements.used = new_length; \
+ }
+
+ #define macro_iki_read_replacements_adjust(status, replacements, new_length) \
+ status = F_none; \
+ if (new_length < replacements.size) { \
+ f_array_length i = replacements.size - new_length; \
+ for (; i < replacements.size; i++) { \
+ macro_iki_read_replacement_delete(status, replacements.array[i]); \
+ if (status != F_none) break; \
+ } \
+ } \
+ if (status == F_none) status = f_memory_adjust((void **) & replacements.array, sizeof(iki_read_replacement), replacements.size, new_length); \
+ if (status == F_none) { \
+ if (new_length > replacements.size) { \
+ f_array_length i = replacements.size; \
+ for (; i < new_length; i++) { \
+ memset(&replacements.array[i], 0, sizeof(iki_read_replacement)); \
+ } \
+ } \
+ replacements.size = new_length; \
+ if (replacements.used > replacements.size) replacements.used = new_length; \
+ }
+#endif // _di_iki_read_replacements_
+
+#ifndef _di_iki_read_data_
+ typedef struct {
+ f_console_parameter parameters[iki_read_total_parameters];
+
+ f_string_lengths remaining;
+ bool process_pipe;
+
+ f_number_unsigned line;
+
+ uint8_t mode;
+ uint8_t verbosity;
+
+ f_string_dynamic buffer;
+
+ iki_read_replacements replacements;
+
+ fl_color_context context;
+ } iki_read_data;
+
+ #define iki_read_data_initialize \
+ { \
+ f_console_parameter_initialize_iki_read, \
+ f_string_lengths_initialize, \
+ F_false, \
+ 0, \
+ 0, \
+ 0, \
+ f_string_dynamic_initialize, \
+ iki_read_replacements_initialize, \
+ fl_color_context_initialize, \
+ }
+#endif // _di_iki_read_data_
+
+/**
+ * Print help to standard output.
+ *
+ * @param context
+ * The color context settings.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_iki_read_print_help_
+ extern f_return_status iki_read_print_help(const fl_color_context context);
+#endif // _di_iki_read_print_help_
+
+/**
+ * Execute main program.
+ *
+ * Be sure to call iki_read_delete_data() after executing this.
+ *
+ * @param arguments
+ * The parameters passed to the process.
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see iki_read_delete_data()
+ */
+#ifndef _di_iki_read_main_
+ extern f_return_status iki_read_main(const f_console_arguments arguments, iki_read_data *data);
+#endif // _di_iki_read_main_
+
+/**
+ * Deallocate data.
+ *
+ * Be sure to call this after executing iki_read_main().
+ *
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see iki_read_main()
+ */
+#ifndef _di_iki_read_delete_data_
+ extern f_return_status iki_read_delete_data(iki_read_data *data);
+#endif // _di_iki_read_delete_data_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _iki_read_h
--- /dev/null
+#include <level_3/iki_read.h>
+
+int main(const unsigned long argc, const f_string *argv) {
+ const f_console_arguments arguments = { argc, argv };
+ iki_read_data data = iki_read_data_initialize;
+
+ if (f_pipe_input_exists()) {
+ data.process_pipe = F_true;
+ }
+
+ f_status status = iki_read_main(arguments, &data);
+
+ if (F_status_is_error(status)) {
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+#include <level_3/iki_read.h>
+#include "private-iki_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_read_print_error_
+ f_return_status iki_read_print_error(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const bool fallback) {
+
+ if (status == F_parameter) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid parameter when calling function ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_none;
+ }
+
+ if (status == F_memory_allocation || status == F_memory_reallocation) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Unable to allocate memory in function ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_none;
+ }
+
+ if (fallback && verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: (");
+ fl_color_print(f_type_error, context.notable, context.reset, "%llu", status);
+ fl_color_print(f_type_error, context.error, context.reset, ") in function ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_unknown;
+ }
+#endif // _di_iki_read_print_error_
+
+#ifndef _di_iki_read_print_error_file_
+ bool iki_read_print_error_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string name, const f_string operation, const bool is_file, const bool fallback) {
+ const f_string file_or_directory = is_file ? "file" : "directory";
+
+ if (status == F_file_found_not) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: failed to find %s '", file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_file_found) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: the %s '", file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' already exists.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_parameter) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print(f_type_error, context.error, context.reset, "() for the %s '", file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_name) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid %s name '", file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_memory_out) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "CRITICAL ERROR: Unable to allocate memory, while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_number_overflow) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Overflow while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_directory) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid directory while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_access_denied) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Access denied while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_loop) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Loop while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_prohibited) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Prohibited by system while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (is_file) {
+ if (status == F_directory_found_not) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: failed to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' due to an invalid directory in the path.");
+ }
+
+ return F_false;
+ }
+ }
+ else {
+ if (status == F_directory_found_not) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: failed to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' due to an invalid directory in the path.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_failure) {
+ if (verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: failed to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+ }
+
+ if (iki_read_print_error(context, verbosity, status, function, F_false) == F_unknown && fallback && verbosity != iki_read_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: (");
+ fl_color_print(f_type_error, context.notable, context.reset, "%llu", status);
+ fl_color_print(f_type_error, context.error, context.reset, ") occurred while trying to %s %s '", operation, file_or_directory);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_true;
+ }
+#endif // _di_iki_read_print_error_file_
+
+#ifndef _di_iki_read_print_error_number_argument_
+ void iki_read_print_error_number_argument(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string parameter, const f_string argument) {
+ if (verbosity == iki_read_verbosity_quiet) return;
+
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+
+ if (status == F_parameter) {
+ fl_color_print(f_type_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s()", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, ".");
+ }
+ else if (status == F_number) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The argument '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", argument);
+ fl_color_print(f_type_error, context.error, context.reset, "' is not a valid number for the parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+ else if (status == F_number_underflow) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The argument '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", argument);
+ fl_color_print(f_type_error, context.error, context.reset, "' is too small for the parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+ else if (status == F_number_overflow) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The argument '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", argument);
+ fl_color_print(f_type_error, context.error, context.reset, "' is too large for the parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+ else if (status == F_number_negative) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The argument '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", argument);
+ fl_color_print(f_type_error, context.error, context.reset, "' is negative, which is not allowed for the parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+ else if (status == F_number_positive) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The argument '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", argument);
+ fl_color_print(f_type_error, context.error, context.reset, "' contains a '");
+ fl_color_print(f_type_error, context.notable, context.reset, "+");
+ fl_color_print(f_type_error, context.error, context.reset, "', which is not allowed for the parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+ else if (status == F_data_not) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' must not be an empty string.");
+ }
+ else {
+ fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: (");
+ fl_color_print(f_type_error, context.notable, context.reset, "%llu", status);
+ fl_color_print(f_type_error, context.error, context.reset, ") has occurred while calling ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s()", function);
+ fl_color_print(f_type_error, context.error, context.reset, "' for the parameter '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter);
+ fl_color_print(f_type_error, context.error, context.reset, "' with the value '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", argument);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+ }
+#endif // _di_iki_read_print_error_number_argument_
+
+#ifndef _di_iki_read_main_process_file_
+ f_return_status iki_read_main_process_file(const f_console_arguments arguments, const f_string filename, iki_read_data *data) {
+ f_status status = F_none;
+
+ f_iki_variable variable = f_iki_variable_initialize;
+ f_iki_vocabulary vocabulary = f_iki_vocabulary_initialize;
+ f_iki_content content = f_iki_content_initialize;
+
+ // @todo
+
+ f_macro_iki_variable_delete_simple(variable);
+ f_macro_iki_vocabulary_delete_simple(vocabulary);
+ f_macro_iki_content_delete_simple(content);
+
+ return F_none;
+ }
+#endif // _di_iki_read_main_process_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#ifndef _PRIVATE_iki_read_h
+#define _PRIVATE_iki_read_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print generic error messages.
+ *
+ * @param context
+ * The color context.
+ * @param verbosity
+ * The verbosity level, which determines if and what should be printed.
+ * @param status
+ * The status code representing an error.
+ * @param function
+ * The name of the function where the error happened.
+ * @param fallback
+ * Set to F_true to print the fallback error message for unknown errors.
+ *
+ * @return
+ * F_none is returned on successful print of known errors.
+ * F_unknown is returned if the status code has no print message.
+ */
+#ifndef _di_iki_read_print_error_
+ extern f_return_status iki_read_print_error(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const bool fallback) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_read_print_error_
+
+/**
+ * Print file/directory error messages.
+ *
+ * @todo the fll_file_error_print() needs to be reviewed and possibly changed.
+ *
+ * @param context
+ * The color context.
+ * @param verbosity
+ * The verbosity level, which determines if and what should be printed.
+ * @param status
+ * The error status code to report on.
+ * @param function
+ * The function call that returned the error.
+ * @param name
+ * The name of the file or directory.
+ * @param operation
+ * The operation that fails, such as 'create' or 'access'.
+ * @param is_file
+ * Set to TRUE if this is a file and FALSE if this is a directory.
+ * @param fallback
+ * Set to F_true to print the fallback error message for unknown errors.
+ *
+ * @return
+ * F_true is returned if the status code has no print message.
+ * F_false is returned on successful print of known errors.
+ */
+#ifndef _di_iki_read_print_error_file_
+ extern bool iki_read_print_error_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string name, const f_string operation, const bool is_file, const bool fallback) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_read_print_error_file_
+
+/**
+ * Print number argument errors.
+ *
+ * @param context
+ * The color context.
+ * @param verbosity
+ * The verbosity level, which determines if and what should be printed.
+ * @param status
+ * The error status code to report on.
+ * @param function
+ * The function call that returned the error.
+ * @param parameter
+ * The parameter name.
+ * @param argument
+ * The argument value.
+ *
+ * @return
+ * F_true is returned if the status code has no print message.
+ * F_false is returned on successful print of known errors.
+ */
+#ifndef _di_iki_read_print_error_number_argument_
+ extern void iki_read_print_error_number_argument(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string parameter, const f_string argument) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_read_print_error_number_argument_
+
+/**
+ * Process a given file.
+ *
+ * @param arguments
+ * The console arguments passed to the program.
+ * @param file_name
+ * The name of the file being processed.
+ * @param data
+ * The program specific data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_iki_read_main_process_file_
+ extern f_return_status iki_read_main_process_file(const f_console_arguments arguments, const f_string file_name, iki_read_data *data) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_read_main_process_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_iki_read_h
--- /dev/null
+# fss-0000
+
--- /dev/null
+f_type
+f_status
+f_memory
+f_string
+f_utf
+f_color
+f_console
+f_conversion
+f_file
+f_iki
+f_pipe
+f_print
+fl_color
+fl_console
+fl_iki
+fl_string
+fl_utf
+fll_file
+fll_program
--- /dev/null
+# fss-0001
+
+project_name iki_read
+
+version_major 0
+version_minor 5
+version_micro 0
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual level monolithic
+modes_default individual
+
+build_compiler gcc
+build_language c
+build_linker ar
+build_libraries -lc
+build_libraries-individual -lfll_program -lfll_file -lfl_string -lfl_status -lfl_print -lfl_iki -lfl_fss -lfl_console -lfl_color -lf_print -lf_pipe -lf_path -lf_iki -lf_fss -lf_file -lf_environment -lf_conversion -lf_console -lf_utf -lf_memory
+build_libraries-level -lfll_2 -lfll_1 -lfll_0
+build_libraries-monolithic -lfll
+build_sources_library iki_read.c private-iki_read.c
+build_sources_program main.c
+build_sources_headers iki_read.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static yes
+
+path_headers level_3
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE