This will further enhancing writing scripts to process FSS files.
This will assist in identifying all of the FSS standards used by a given file.
--- /dev/null
+#include "fss_identify.h"
+#include "private-common.h"
+#include "private-fss_identify.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_identify_print_help_
+ f_status_t fss_identify_print_help(const f_file_t output, const f_color_context_t context) {
+
+ fll_program_print_help_header(output, context, fss_identify_name_long, fss_identify_version);
+
+ fll_program_print_help_option(output, 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(output, 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(output, 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(output, 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 output in color.");
+ fll_program_print_help_option(output, 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 beyond normal output.");
+ fll_program_print_help_option(output, 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 output.");
+ fll_program_print_help_option(output, 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(output, 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, inceasing verbosity beyond normal output.");
+ fll_program_print_help_option(output, 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.");
+
+ fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+ fll_program_print_help_option(output, context, fss_identify_short_name, fss_identify_long_name, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the Identifier name.");
+ fll_program_print_help_option(output, context, fss_identify_short_type, fss_identify_long_type, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the Identifier type.");
+
+ fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+ fll_program_print_help_option(output, context, fss_identify_short_line, fss_identify_long_line, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Identifier at the given line.");
+ fll_program_print_help_option(output, context, fss_identify_short_total, fss_identify_long_total, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the total Identifiers found.");
+
+ fll_program_print_help_usage(output, context, fss_identify_name, "filename(s)");
+
+ fprintf(output.stream, " The ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_line);
+ fprintf(output.stream, " parameter refers to the output lines and not the lines in a given file.%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, " If neither the ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_name);
+ fprintf(output.stream, " nor ", f_string_eol_s[0]);
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_type);
+ fprintf(output.stream, " are specified, then the default behavior is to print both.%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, " When specifying the ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_total);
+ fprintf(output.stream, " parameter, neither the ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_name);
+ fprintf(output.stream, " nor the ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_type);
+ fprintf(output.stream, " parameter may be specified.%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+ return F_none;
+ }
+#endif // _di_fss_identify_print_help_
+
+#ifndef _di_fss_identify_main_
+ f_status_t fss_identify_main(const f_console_arguments_t arguments, fss_identify_main_t *main) {
+ f_status_t status = F_none;
+
+ {
+ const f_console_parameters_t parameters = macro_f_console_parameters_t_initialize(main->parameters, fss_identify_total_parameters);
+
+ {
+ f_console_parameter_id_t ids[3] = { fss_identify_parameter_no_color, fss_identify_parameter_light, fss_identify_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);
+
+ if (main->context.set.error.before) {
+ 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->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)) {
+ if (main->error.verbosity != f_console_verbosity_quiet) {
+ fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process", F_true);
+ fprintf(main->error.to.stream, "%c", f_string_eol_s[0]);
+ }
+
+ fss_identify_main_delete(main);
+
+ return F_status_set_error(status);
+ }
+ }
+
+ // Identify priority of verbosity related parameters.
+ {
+ f_console_parameter_id_t ids[4] = { fss_identify_parameter_verbosity_quiet, fss_identify_parameter_verbosity_normal, fss_identify_parameter_verbosity_verbose, fss_identify_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)) {
+ fss_identify_main_delete(main);
+
+ return status;
+ }
+
+ if (choice == fss_identify_parameter_verbosity_quiet) {
+ main->error.verbosity = f_console_verbosity_quiet;
+ }
+ else if (choice == fss_identify_parameter_verbosity_normal) {
+ main->error.verbosity = f_console_verbosity_normal;
+ }
+ else if (choice == fss_identify_parameter_verbosity_verbose) {
+ main->error.verbosity = f_console_verbosity_verbose;
+ }
+ else if (choice == fss_identify_parameter_verbosity_debug) {
+ main->error.verbosity = f_console_verbosity_debug;
+ }
+ }
+
+ status = F_none;
+ }
+
+ if (main->parameters[fss_identify_parameter_help].result == f_console_result_found) {
+ fss_identify_print_help(main->output, main->context);
+
+ fss_identify_main_delete(main);
+
+ return F_none;
+ }
+
+ if (main->parameters[fss_identify_parameter_version].result == f_console_result_found) {
+ fll_program_print_version(main->output, fss_identify_version);
+
+ fss_identify_main_delete(main);
+
+ return F_none;
+ }
+
+ fss_identify_data_t data = fss_identify_data_t_initialize;
+
+ if (F_status_is_error_not(status)) {
+ if (main->parameters[fss_identify_parameter_line].result == f_console_result_found) {
+ f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error);
+ f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_line);
+ f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]);
+
+ status = F_status_set_error(F_parameter);
+ }
+ else if (main->parameters[fss_identify_parameter_line].result == f_console_result_additional) {
+ const f_array_length_t index = main->parameters[fss_identify_parameter_line].values.array[main->parameters[fss_identify_parameter_line].values.used - 1];
+ const f_string_range_t range = macro_f_string_range_t_initialize(strnlen(arguments.argv[index], f_console_parameter_size));
+
+ status = fl_conversion_string_to_number_unsigned(arguments.argv[index], range, &data.line);
+
+ if (F_status_is_error(status)) {
+ fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_identify_long_line, arguments.argv[index]);
+ }
+ }
+ }
+
+ if (F_status_is_error_not(status) && main->parameters[fss_identify_parameter_total].result == f_console_result_found) {
+ if (main->parameters[fss_identify_parameter_name].result == f_console_result_found) {
+ f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error);
+ f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_name);
+ f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '");
+ f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_total);
+ f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]);
+
+ status = F_status_set_error(F_parameter);
+ }
+ else if (main->parameters[fss_identify_parameter_type].result == f_console_result_found) {
+ f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error);
+ f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_type);
+ f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '");
+ f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_identify_long_total);
+ f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]);
+
+ status = F_status_set_error(F_parameter);
+ }
+ }
+
+ f_string_range_t range = f_string_range_t_initialize;
+ f_string_dynamic_t buffer = f_string_dynamic_t_initialize;
+ f_file_t file = f_file_t_initialize;
+
+ if (F_status_is_error_not(status) && main->process_pipe) {
+ file.id = f_type_descriptor_input;
+ file.stream = f_type_input;
+ file.size_read = 512;
+
+ status = fss_identify_load_line(*main, file, "-", &buffer, &range);
+
+ if (F_status_is_error_not(status)) {
+ status = fss_identify_process(*main, "-", buffer, &range, &data);
+ }
+ }
+
+ if (F_status_is_error_not(status)) {
+
+ for (f_array_length_t i = 0; i < main->remaining.used; ++i) {
+
+ if (main->parameters[fss_identify_parameter_line].result == f_console_result_additional) {
+ if (data.current > data.line) break;
+ }
+
+ macro_f_file_t_reset(file);
+
+ file.size_read = 512;
+
+ status = f_file_stream_open(arguments.argv[main->remaining.array[i]], 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[main->remaining.array[i]], "open", fll_error_file_type_file);
+ }
+ else {
+ status = fss_identify_load_line(*main, file, arguments.argv[main->remaining.array[i]], &buffer, &range);
+
+ if (F_status_is_error_not(status)) {
+ status = fss_identify_process(*main, arguments.argv[main->remaining.array[i]], buffer, &range, &data);
+ }
+ }
+
+ f_file_stream_close(F_true, &file);
+
+ if (F_status_is_error(status)) break;
+ } // for
+ }
+
+ f_string_dynamic_resize(0, &buffer);
+
+ if (F_status_is_error_not(status)) {
+ if (main->parameters[fss_identify_parameter_line].result == f_console_result_additional) {
+
+ if (data.current < data.line) {
+ if (main->parameters[fss_identify_parameter_total].result == f_console_result_found) {
+ fprintf(main->output.stream, "%c%c", f_string_ascii_0_s[0], f_string_eol_s[0]);
+ }
+ }
+ }
+ }
+
+ // ensure a newline is always put at the end of the program execution, unless in quiet mode.
+ if (main->error.verbosity != f_console_verbosity_quiet) {
+ if (F_status_is_error(status)) {
+ fprintf(main->error.to.stream, "%c", f_string_eol_s[0]);
+ }
+ }
+
+ fss_identify_main_delete(main);
+
+ return status;
+ }
+#endif // _di_fss_identify_main_
+
+#ifndef _di_fss_identify_main_delete_
+ f_status_t fss_identify_main_delete(fss_identify_main_t *main) {
+
+ for (f_array_length_t i = 0; i < fss_identify_total_parameters; 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_array_lengths_t_delete_simple(main->remaining);
+
+ macro_f_color_context_t_delete_simple(main->context);
+
+ return F_none;
+ }
+#endif // _di_fss_identify_main_delete_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS Identify
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * This is the program is intended to be used to identify an FSS file or FSS data.
+ *
+ * A valid FSS file or FSS data will have a header starting with the pound character '#'.
+ *
+ * This program utilizes the Featureless Linux Library.
+ */
+#ifndef _fss_identify_h
+
+// libc includes
+#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/directory.h>
+#include <fll/level_0/fss.h>
+#include <fll/level_0/file.h>
+#include <fll/level_0/pipe.h>
+#include <fll/level_0/print.h>
+
+// fll-1 includes
+#include <fll/level_1/console.h>
+#include <fll/level_1/conversion.h>
+#include <fll/level_1/fss.h>
+#include <fll/level_1/string.h>
+
+// fll-2 includes
+#include <fll/level_2/error.h>
+#include <fll/level_2/fss.h>
+#include <fll/level_2/program.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_identify_version_
+ #define fss_identify_major_version f_string_ascii_0
+ #define fss_identify_minor_version f_string_ascii_5
+ #define fss_identify_micro_version f_string_ascii_4
+ #define fss_identify_version fss_identify_major_version f_string_ascii_period fss_identify_minor_version f_string_ascii_period fss_identify_micro_version
+#endif // _di_fss_identify_version_
+
+#ifndef _di_fss_identify_name_
+ #define fss_identify_name "fss_identify"
+ #define fss_identify_name_long "FSS Identify"
+#endif // _di_fss_identify_name_
+
+#ifndef _di_fss_identify_defines_
+ #define fss_identify_short_line "l"
+ #define fss_identify_short_name "n"
+ #define fss_identify_short_total "T"
+ #define fss_identify_short_type "t"
+
+ #define fss_identify_long_line "line"
+ #define fss_identify_long_name "name"
+ #define fss_identify_long_total "total"
+ #define fss_identify_long_type "type"
+
+ enum {
+ fss_identify_parameter_help,
+ fss_identify_parameter_light,
+ fss_identify_parameter_dark,
+ fss_identify_parameter_no_color,
+ fss_identify_parameter_verbosity_quiet,
+ fss_identify_parameter_verbosity_normal,
+ fss_identify_parameter_verbosity_verbose,
+ fss_identify_parameter_verbosity_debug,
+ fss_identify_parameter_version,
+
+ fss_identify_parameter_line,
+ fss_identify_parameter_name,
+ fss_identify_parameter_total,
+ fss_identify_parameter_type,
+ };
+
+ #define fss_identify_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(fss_identify_short_line, fss_identify_long_line, 0, 1, f_console_type_normal), \
+ f_console_parameter_t_initialize(fss_identify_short_name, fss_identify_long_name, 0, 0, f_console_type_normal), \
+ f_console_parameter_t_initialize(fss_identify_short_total, fss_identify_long_total, 0, 0, f_console_type_normal), \
+ f_console_parameter_t_initialize(fss_identify_short_type, fss_identify_long_type, 0, 0, f_console_type_normal), \
+ }
+
+ #define fss_identify_total_parameters 13
+#endif // _di_fss_identify_defines_
+
+#ifndef _di_fss_identify_data_t_
+ typedef struct {
+ f_console_parameter_t parameters[fss_identify_total_parameters];
+
+ f_array_lengths_t remaining;
+ bool process_pipe;
+
+ f_file_t output;
+ fll_error_print_t error;
+ fll_error_print_t warning;
+
+ f_color_context_t context;
+ } fss_identify_main_t;
+
+ #define fss_identify_data_initialize \
+ { \
+ fss_identify_console_parameter_t_initialize, \
+ f_array_lengths_t_initialize, \
+ F_false, \
+ macro_f_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
+ fll_error_print_t_initialize, \
+ macro_fll_error_print_t_initialize_warning(), \
+ f_color_context_t_initialize, \
+ }
+#endif // _di_fss_identify_data_t_
+
+/**
+ * Print help.
+ *
+ * @param output
+ * The file to print to.
+ * @param context
+ * The color context settings.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_identify_print_help_
+ extern f_status_t fss_identify_print_help(const f_file_t output, const f_color_context_t context);
+#endif // _di_fss_identify_print_help_
+
+/**
+ * Execute main program.
+ *
+ * Be sure to call fss_identify_main_delete() after executing this.
+ *
+ * @param arguments
+ * The parameters passed to the process.
+ * @param main
+ * The program main.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see fss_identify_main_delete()
+ */
+#ifndef _di_fss_identify_main_
+ extern f_status_t fss_identify_main(const f_console_arguments_t arguments, fss_identify_main_t *main);
+#endif // _di_fss_identify_main_
+
+/**
+ * Deallocate main.
+ *
+ * Be sure to call this after executing fss_identify_main().
+ *
+ * @param main
+ * The program main.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see fss_identify_main()
+ */
+#ifndef _di_fss_identify_main_delete_
+ extern f_status_t fss_identify_main_delete(fss_identify_main_t *main);
+#endif // _di_fss_identify_main_delete_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_identify_h
--- /dev/null
+#include "fss_identify.h"
+
+int main(const int argc, const f_string_t *argv) {
+
+ const f_console_arguments_t arguments = { argc, argv };
+ fss_identify_main_t data = fss_identify_data_initialize;
+
+ if (f_pipe_input_exists()) {
+ data.process_pipe = F_true;
+ }
+
+ const f_status_t status = fss_identify_main(arguments, &data);
+
+ // flush output pipes before closing.
+ fflush(f_type_output);
+ fflush(f_type_error);
+
+ // close all open file descriptors.
+ close(f_type_descriptor_output);
+ close(f_type_descriptor_input);
+ close(f_type_descriptor_error);
+
+ if (F_status_is_error(status)) {
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+#include "fss_identify.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS Identify
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#ifndef _PRIVATE_common_h
+#define _PRIVATE_common_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The data structure for FSS Identify.
+ *
+ * current: The current position within the ids, used to determine when the line is matched.
+ * line: The line number to select.
+ */
+#ifndef _di_fss_identify_data_t_
+ typedef struct {
+ f_array_length_t current;
+ f_array_length_t line;
+ } fss_identify_data_t;
+
+ #define fss_identify_data_t_initialize \
+ { \
+ 0, \
+ 0, \
+ }
+#endif // _di_fss_identify_data_t_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_common_h
--- /dev/null
+#include "fss_identify.h"
+#include "private-common.h"
+#include "private-fss_identify.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_identify_load_line_
+ f_status_t fss_identify_load_line(const fss_identify_main_t main, const f_file_t file, const f_string_t name, f_string_static_t *buffer, f_string_range_t *range) {
+
+ f_status_t status = F_none;
+
+ buffer->used = 0;
+
+ range->start = 0;
+ range->stop = 0;
+
+ do {
+ if (buffer->used + file.size_read > buffer->size) {
+ status = f_string_dynamic_resize(buffer->size + file.size_read, buffer);
+
+ if (F_status_is_error(status)) {
+ fll_error_file_print(main.error, F_status_set_fine(status), "f_string_dynamic_resize", F_true, name ? name : "-", "read", name ? fll_error_file_type_file : fll_error_file_type_pipe);
+
+ return status;
+ }
+ }
+
+ status = f_file_stream_read_block(file, buffer);
+
+ if (F_status_is_error(status)) {
+ fll_error_file_print(main.error, F_status_set_fine(status), "f_file_stream_read_block", F_true, name ? name : "-", "read", name ? fll_error_file_type_file : fll_error_file_type_pipe);
+
+ return status;
+ }
+
+ for (; range->start < buffer->used; ++range->start) {
+ if (buffer->string[range->start] == f_string_eol_s[0]) break;
+ } // for
+
+ range->stop = range->start;
+
+ if (buffer->string[range->start] == f_string_eol_s[0]) break;
+
+ } while (F_status_is_error_not(status) && status != F_none_eof);
+
+ // reset the start point to prepare the buffer for processing.
+ range->start = 0;
+
+ return status;
+ }
+#endif // _di_fss_identify_load_line_
+
+#ifndef _di_fss_identify_print_
+ void fss_identify_print(const fss_identify_main_t main, f_fll_id_t id) {
+
+ if (main.parameters[fss_identify_parameter_name].result == f_console_result_found || main.parameters[fss_identify_parameter_type].result != f_console_result_found) {
+ f_string_static_t part = f_string_static_t_initialize;
+
+ part.string = id.name;
+ part.used = id.used;
+ part.size = part.used;
+
+ f_print_dynamic(main.output.stream, part);
+
+ if (main.parameters[fss_identify_parameter_name].result != f_console_result_found || main.parameters[fss_identify_parameter_type].result == f_console_result_found) {
+ fprintf(main.output.stream, "%c", f_fss_type_header_part5);
+ }
+ }
+
+ if (main.parameters[fss_identify_parameter_name].result != f_console_result_found || main.parameters[fss_identify_parameter_type].result == f_console_result_found) {
+ fprintf(main.output.stream, "%04x", id.type);
+ }
+
+ fprintf(main.output.stream, "%c", f_string_eol_s[0]);
+ }
+#endif // _di_fss_identify_print_
+
+#ifndef _di_fss_identify_process_
+ f_status_t fss_identify_process(const fss_identify_main_t main, const f_string_t name, const f_string_static_t buffer, f_string_range_t *range, fss_identify_data_t *data) {
+
+ f_status_t status = F_none;
+ f_fll_ids_t ids = f_fll_ids_t_initialize;
+
+ status = fll_fss_identify(buffer.string, range, &ids);
+
+ if (F_status_is_error(status)) {
+ fll_error_file_print(main.error, F_status_set_fine(status), "fll_fss_identify", F_true, name ? name : "-", "read", name ? fll_error_file_type_file : fll_error_file_type_pipe);
+
+ f_type_fll_ids_resize(0, &ids);
+
+ return status;
+ }
+
+ if (main.parameters[fss_identify_parameter_line].result == f_console_result_additional) {
+
+ for (f_array_length_t i = 0; i < ids.used; ++i, ++data->current) {
+
+ if (data->current == data->line) {
+ if (main.parameters[fss_identify_parameter_total].result == f_console_result_found) {
+ fprintf(main.output.stream, "%c%c", f_string_ascii_1_s[0], f_string_eol_s[0]);
+ }
+ else {
+ fss_identify_print(main, ids.array[i]);
+ }
+
+ ++data->current;
+
+ break;
+ }
+ } // for
+ }
+ else if (main.parameters[fss_identify_parameter_total].result == f_console_result_found) {
+ fprintf(main.output.stream, "%llu%c", ids.used, f_string_eol_s[0]);
+ }
+ else if (status == F_found || status == F_maybe) {
+
+ for (f_array_length_t i = 0; i < ids.used; ++i) {
+ fss_identify_print(main, ids.array[i]);
+ } // for
+ }
+
+ f_type_fll_ids_resize(0, &ids);
+
+ return F_none;
+ }
+#endif // _di_fss_identify_process_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS Identify
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#ifndef _PRIVATE_fss_identify_h
+#define _PRIVATE_fss_identify_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Load a pipe or a file 1 block at a time untul a newline is found.
+ *
+ * @param main
+ * The main data.
+ * @param file
+ * The file or pipe to load from.
+ * @param name
+ * The name of the file.
+ * Set to NULL to designate that this is a pipe.
+ * @param buffer
+ * The string representing the file to process.
+ * @param range
+ * The range representing the line in the buffer.
+ *
+ * @return
+ * Status from: f_file_stream_read_block().
+ *
+ * Errors (with error bit) from: f_file_stream_read_block().
+ * Errors (with error bit) from: f_string_dynamic_resize().
+ *
+ * @see f_file_stream_read_block()
+ * @see f_string_dynamic_resize()
+ */
+#ifndef _di_fss_identify_load_line_
+ extern f_status_t fss_identify_load_line(const fss_identify_main_t main, const f_file_t file, const f_string_t name, f_string_static_t *buffer, f_string_range_t *range) f_attribute_visibility_internal;
+#endif // _di_fss_identify_load_line_
+
+/**
+ * Print the given FLL Identifier.
+ *
+ * @param main
+ * The main data.
+ * @param id
+ * The Identifier to print.
+ */
+#ifndef _di_fss_identify_print_
+ extern void fss_identify_print(const fss_identify_main_t main, f_fll_id_t id) f_attribute_visibility_internal;
+#endif // _di_fss_identify_print_
+
+/**
+ * Process a given pipe or file.
+ *
+ * @param main
+ * The main data.
+ * @param name
+ * The name of the file.
+ * Set to NULL to designate that this is a pipe.
+ * @param buffer
+ * The string representing the file to process.
+ * @param range
+ * The range representing the line in the buffer.
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Errors (with error bit) from: fll_fss_identify().
+ *
+ * @see fll_fss_identify()
+ */
+#ifndef _di_fss_identify_process_
+ extern f_status_t fss_identify_process(const fss_identify_main_t main, const f_string_t name, const f_string_static_t buffer, f_string_range_t *range, fss_identify_data_t *data) f_attribute_visibility_internal;
+#endif // _di_fss_identify_process_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_fss_identify_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_fss
+f_pipe
+f_print
+fl_console
+fl_conversion
+fl_fss
+fll_error
+fll_fss
+fll_program
--- /dev/null
+# fss-0001
+
+project_name fss_identify
+
+version_major 0
+version_minor 5
+version_micro 4
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual level monolithic
+modes_default monolithic
+
+build_compiler gcc
+build_indexer ar
+build_language c
+build_libraries -lc
+build_libraries-individual -lfll_error -lfll_fss -lfll_program -lfl_console -lfl_conversion -lfl_fss -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf
+build_libraries-level -lfll_2 -lfll_1 -lfll_0
+build_libraries-monolithic -lfll
+build_sources_library fss_identify.c private-common.c private-fss_identify.c
+build_sources_program main.c
+build_sources_headers fss_identify.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static no
+
+path_headers program/fss_identify
+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_all
+defines_static
+defines_shared
+
+flags_all -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE