From dc4e99c83b3d29563f43e174ab9bf7ab5c702f9d Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 30 May 2021 23:29:19 -0500 Subject: [PATCH] Feature: Add FSS Identify program "fss_identify". 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. --- level_3/fss_identify/c/fss_identify.c | 285 ++++++++++++++++++++++++++ level_3/fss_identify/c/fss_identify.h | 194 ++++++++++++++++++ level_3/fss_identify/c/main.c | 28 +++ level_3/fss_identify/c/private-common.c | 10 + level_3/fss_identify/c/private-common.h | 38 ++++ level_3/fss_identify/c/private-fss_identify.c | 132 ++++++++++++ level_3/fss_identify/c/private-fss_identify.h | 85 ++++++++ level_3/fss_identify/data/build/defines | 2 + level_3/fss_identify/data/build/dependencies | 20 ++ level_3/fss_identify/data/build/settings | 57 ++++++ 10 files changed, 851 insertions(+) create mode 100644 level_3/fss_identify/c/fss_identify.c create mode 100644 level_3/fss_identify/c/fss_identify.h create mode 100644 level_3/fss_identify/c/main.c create mode 100644 level_3/fss_identify/c/private-common.c create mode 100644 level_3/fss_identify/c/private-common.h create mode 100644 level_3/fss_identify/c/private-fss_identify.c create mode 100644 level_3/fss_identify/c/private-fss_identify.h create mode 100644 level_3/fss_identify/data/build/defines create mode 100644 level_3/fss_identify/data/build/dependencies create mode 100644 level_3/fss_identify/data/build/settings diff --git a/level_3/fss_identify/c/fss_identify.c b/level_3/fss_identify/c/fss_identify.c new file mode 100644 index 0000000..c5e4a45 --- /dev/null +++ b/level_3/fss_identify/c/fss_identify.c @@ -0,0 +1,285 @@ +#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 diff --git a/level_3/fss_identify/c/fss_identify.h b/level_3/fss_identify/c/fss_identify.h new file mode 100644 index 0000000..582e213 --- /dev/null +++ b/level_3/fss_identify/c/fss_identify.h @@ -0,0 +1,194 @@ +/** + * 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 + +// fll-0 includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fll-1 includes +#include +#include +#include +#include + +// fll-2 includes +#include +#include +#include + +#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 diff --git a/level_3/fss_identify/c/main.c b/level_3/fss_identify/c/main.c new file mode 100644 index 0000000..066a04e --- /dev/null +++ b/level_3/fss_identify/c/main.c @@ -0,0 +1,28 @@ +#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; +} diff --git a/level_3/fss_identify/c/private-common.c b/level_3/fss_identify/c/private-common.c new file mode 100644 index 0000000..258cd3d --- /dev/null +++ b/level_3/fss_identify/c/private-common.c @@ -0,0 +1,10 @@ +#include "fss_identify.h" +#include "private-common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_identify/c/private-common.h b/level_3/fss_identify/c/private-common.h new file mode 100644 index 0000000..cfb1ad4 --- /dev/null +++ b/level_3/fss_identify/c/private-common.h @@ -0,0 +1,38 @@ +/** + * 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 diff --git a/level_3/fss_identify/c/private-fss_identify.c b/level_3/fss_identify/c/private-fss_identify.c new file mode 100644 index 0000000..f66ea97 --- /dev/null +++ b/level_3/fss_identify/c/private-fss_identify.c @@ -0,0 +1,132 @@ +#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 diff --git a/level_3/fss_identify/c/private-fss_identify.h b/level_3/fss_identify/c/private-fss_identify.h new file mode 100644 index 0000000..0f1c54e --- /dev/null +++ b/level_3/fss_identify/c/private-fss_identify.h @@ -0,0 +1,85 @@ +/** + * 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 diff --git a/level_3/fss_identify/data/build/defines b/level_3/fss_identify/data/build/defines new file mode 100644 index 0000000..c665317 --- /dev/null +++ b/level_3/fss_identify/data/build/defines @@ -0,0 +1,2 @@ +# fss-0000 + diff --git a/level_3/fss_identify/data/build/dependencies b/level_3/fss_identify/data/build/dependencies new file mode 100644 index 0000000..1d1f796 --- /dev/null +++ b/level_3/fss_identify/data/build/dependencies @@ -0,0 +1,20 @@ +# 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 diff --git a/level_3/fss_identify/data/build/settings b/level_3/fss_identify/data/build/settings new file mode 100644 index 0000000..57a6c0c --- /dev/null +++ b/level_3/fss_identify/data/build/settings @@ -0,0 +1,57 @@ +# 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 -- 1.8.3.1