From 657ac8416ea09b90396142901333abc465af533e Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 10 Mar 2012 18:29:32 -0600 Subject: [PATCH] Update: add support for accepting pipe values Data can now be piped to the fss_*_read functions. To make this practical, this adds and uses a hidden/internal functions. --- .../fss_basic_list_read/c/fss_basic_list_read.c | 422 ++++++++++++--------- .../fss_basic_list_read/c/fss_basic_list_read.h | 3 + level_3/fss_basic_list_read/c/main.c | 4 + level_3/fss_basic_list_read/data/build/settings | 4 +- level_3/fss_basic_read/c/fss_basic_read.c | 410 +++++++++++--------- level_3/fss_basic_read/c/fss_basic_read.h | 3 + level_3/fss_basic_read/c/main.c | 4 + level_3/fss_basic_read/data/build/settings | 2 +- level_3/fss_extended_read/c/fss_extended_read.c | 333 +++++++++------- level_3/fss_extended_read/c/fss_extended_read.h | 3 + level_3/fss_extended_read/c/main.c | 4 + level_3/fss_extended_read/data/build/settings | 2 +- 12 files changed, 686 insertions(+), 508 deletions(-) diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.c b/level_3/fss_basic_list_read/c/fss_basic_list_read.c index 90df939..db5d51f 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.c @@ -129,6 +129,8 @@ extern "C"{ #endif // _di_fss_basic_list_read_print_help_ #ifndef _di_fss_basic_list_read_main_ + f_return_status fss_basic_list_read_main_process_file(const f_array_length argc, const f_string argv[], fss_basic_list_read_data *data, const f_string filename, const f_string_length target) __attribute__((visibility ("internal"))); + f_return_status fss_basic_list_read_main(const f_array_length argc, const f_string argv[], fss_basic_list_read_data *data){ f_status status = f_status_initialize; f_status allocation_status = f_status_initialize; @@ -171,17 +173,51 @@ extern "C"{ fss_basic_list_read_print_help(*data); } else if (data->parameters[fss_basic_list_read_parameter_version].result == f_console_result_found){ fss_basic_list_read_print_version(*data); - } else if (data->remaining.used > 0){ + } else if (data->remaining.used > 0 || data->process_pipe){ f_string_length counter = f_string_length_initialize; - f_string_length current = f_string_length_initialize; f_string_length target = f_string_length_initialize; - f_string_length found = f_string_length_initialize; f_string_length original_size = data->file_position.total_elements; if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ target = (f_string_length) atoll(argv[data->parameters[fss_basic_list_read_parameter_count].additional]); } + if (data->process_pipe) { + f_file file = f_file_initialize; + + file.file = f_pipe; + + status = fl_file_read_fifo(file, &data->buffer); + + if (status != f_none){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()"); + } else if (status == f_file_not_found){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to find the file '%s'", "-"); + } else if (status == f_file_open_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to open the file '%s'", "-"); + } else if (status == f_file_descriptor_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: File descriptor error while trying to open the file '%s'", "-"); + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", status); + } + + fss_basic_list_read_delete_data(data); + return status; + } + + status = fss_basic_list_read_main_process_file(argc, argv, data, "-", target); + + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + return status; + } + + // clear buffers before continuing + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + } + for (; counter < data->remaining.used; counter++){ f_file file = f_file_initialize; @@ -246,50 +282,176 @@ extern "C"{ return status; } - { - f_string_location input = f_string_location_initialize; - - input.start = 0; - input.stop = data->buffer.used - 1; + status = fss_basic_list_read_main_process_file(argc, argv, data, argv[data->remaining.array[counter]], target); - status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents); + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + return status; } - if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content){ - if (status == f_invalid_parameter){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", argv[data->remaining.array[counter]]); + // clear buffers before repeating the loop + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + } // for + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files"); + } - fss_basic_list_read_delete_data(data); - return status; - } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop || status == f_no_data_on_eof){ - // not an error in this case - } else if (f_macro_test_for_allocation_errors(status)){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + fss_basic_list_read_delete_data(data); + return status; + } - fss_basic_list_read_delete_data(data); - return status; - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", status, argv[data->remaining.array[counter]]); - } + f_return_status fss_basic_list_read_main_process_file(const f_array_length argc, const f_string argv[], fss_basic_list_read_data *data, const f_string filename, const f_string_length target) { + f_status status = f_status_initialize; + f_status allocation_status = f_status_initialize; - // clear buffers, then attempt the next file - f_delete_fss_contents(allocation_status, data->contents); - f_delete_fss_objects(allocation_status, data->objects); - f_delete_dynamic_string(allocation_status, data->buffer); + f_string_length current = f_string_length_initialize; + f_string_length found = f_string_length_initialize; - continue; - } + { + f_string_location input = f_string_location_initialize; + + input.start = 0; + input.stop = data->buffer.used - 1; + + status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents); + } + + if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); + + fss_basic_list_read_delete_data(data); + return status; + } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop || status == f_no_data_on_eof){ + // not an error in this case + } else if (f_macro_test_for_allocation_errors(status)){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + + fss_basic_list_read_delete_data(data); + return status; + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", status, filename); + } + + // clear buffers, then attempt the next file + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + + return status; + } + + // now that all of the files have been read, process the objects and contents + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_none){ + fprintf(f_standard_output, "%u\n", (unsigned int) data->objects.used); + } else { + current = 0; + + if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_none){ + if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_none){ + for (; current < data->objects.used; current++){ + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ + + if (data->parameters[fss_basic_list_read_parameter_size].result == f_console_result_found){ + if (data->contents.array[current].used > 0){ + f_string_length counter = data->contents.array[current].array[0].start; + f_string_length size = 0; + + for (; counter <= data->contents.array[current].array[0].stop; counter++){ + if (data->buffer.string[counter] == f_eol) size++; + } // for + + // the last newline is never present + size++; + + fprintf(f_standard_output, "%u\n", (unsigned int) size); + } else { + fprintf(f_standard_output, "0\n"); + } + } else if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional){ + if (data->contents.array[current].used > 0){ + f_string_length counter = data->contents.array[current].array[0].start; + f_string_length position = 0; + f_string_length target = (f_string_length) atoll(argv[data->parameters[fss_basic_list_read_parameter_line].additional]); + f_string_location range = f_string_location_initialize; + + // use an invalid range to communicate range not found + range.start = 1; + range.stop = 0; + + for (; counter <= data->contents.array[current].array[0].stop; counter++){ + if (position == target){ + range.start = counter; + + // explicit use of < instead of <= is done here so that the range.stop will always be accurate + for (; counter < data->contents.array[current].array[0].stop; counter++){ + if (data->buffer.string[counter] == f_eol){ + break; + } + } // for + + range.stop = counter; + break; + } + + if (data->buffer.string[counter] == f_eol){ + position++; + } + } // for + + if (range.start <= range.stop){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, range); + } + } + } else { + if (data->contents.array[current].used > 0){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); + fprintf(f_standard_output, "\n"); + } + } + } - // now that all of the files have been read, process the objects and contents - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_name].result == f_console_result_none){ - fprintf(f_standard_output, "%u\n", (unsigned int) data->objects.used); + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } + } + } // for } else { - current = 0; + for (; current < data->objects.used; current++){ + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); + fprintf(f_standard_output, "\n"); + } + + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } + } + } // for + } + } else { + current = 0; + + f_string_length total = f_string_length_initialize; + f_string_length name_length = f_string_length_initialize; + f_string_length argv_length = f_string_length_initialize; - if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_none){ - if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_none){ - for (; current < data->objects.used; current++){ - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ + if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional){ + argv_length = strlen(argv[data->parameters[fss_basic_list_read_parameter_name].additional]); + + if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_none){ + for (; current < data->objects.used; current++){ + name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; + + if (name_length == argv_length){ + if (fl_compare_strings(data->buffer.string + data->objects.array[current].start, argv[data->parameters[fss_basic_list_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ if (data->parameters[fss_basic_list_read_parameter_size].result == f_console_result_found){ if (data->contents.array[current].used > 0){ @@ -343,173 +505,61 @@ extern "C"{ } } } else { - if (data->contents.array[current].used > 0){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); - fprintf(f_standard_output, "\n"); + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found){ + total++; + } else { + if (data->contents.array[current].used > 0){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); + fprintf(f_standard_output, "\n"); + } + } } } - } - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } } } - } // for - } else { - for (; current < data->objects.used; current++){ - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } + } + } // for - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } - } - } // for + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none){ + fprintf(f_standard_output, f_string_length_printf "\n", total); } } else { - current = 0; - - f_string_length total = f_string_length_initialize; - f_string_length name_length = f_string_length_initialize; - f_string_length argv_length = f_string_length_initialize; - - if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional){ - argv_length = strlen(argv[data->parameters[fss_basic_list_read_parameter_name].additional]); - - if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_none){ - for (; current < data->objects.used; current++){ - name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; - - if (name_length == argv_length){ - if (fl_compare_strings(data->buffer.string + data->objects.array[current].start, argv[data->parameters[fss_basic_list_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ - - if (data->parameters[fss_basic_list_read_parameter_size].result == f_console_result_found){ - if (data->contents.array[current].used > 0){ - f_string_length counter = data->contents.array[current].array[0].start; - f_string_length size = 0; - - for (; counter <= data->contents.array[current].array[0].stop; counter++){ - if (data->buffer.string[counter] == f_eol) size++; - } // for - - // the last newline is never present - size++; - - fprintf(f_standard_output, "%u\n", (unsigned int) size); - } else { - fprintf(f_standard_output, "0\n"); - } - } else if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional){ - if (data->contents.array[current].used > 0){ - f_string_length counter = data->contents.array[current].array[0].start; - f_string_length position = 0; - f_string_length target = (f_string_length) atoll(argv[data->parameters[fss_basic_list_read_parameter_line].additional]); - f_string_location range = f_string_location_initialize; - - // use an invalid range to communicate range not found - range.start = 1; - range.stop = 0; - - for (; counter <= data->contents.array[current].array[0].stop; counter++){ - if (position == target){ - range.start = counter; - - // explicit use of < instead of <= is done here so that the range.stop will always be accurate - for (; counter < data->contents.array[current].array[0].stop; counter++){ - if (data->buffer.string[counter] == f_eol){ - break; - } - } // for - - range.stop = counter; - break; - } - - if (data->buffer.string[counter] == f_eol){ - position++; - } - } // for + // when and because the object parameter is specified, the name parameter refers to the content instead of the object + // therefore, make the search on the content and display the object + for (; current < data->contents.used; current++){ + if (data->contents.array[current].used > 0){ + name_length = data->contents.array[current].array[0].stop - data->contents.array[current].array[0].start + 1; + + if (name_length == argv_length){ + if (fl_compare_strings(data->buffer.string + data->contents.array[current].array[0].start, argv[data->parameters[fss_basic_list_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); + fprintf(f_standard_output, "\n"); + } - if (range.start <= range.stop){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, range); - } - } + if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; } else { - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found){ - total++; - } else { - if (data->contents.array[current].used > 0){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); - fprintf(f_standard_output, "\n"); - } - } - } - } - - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } + found++; } } } - } // for - - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_count].result == f_console_result_none){ - fprintf(f_standard_output, f_string_length_printf "\n", total); } - } else { - // when and because the object parameter is specified, the name parameter refers to the content instead of the object - // therefore, make the search on the content and display the object - for (; current < data->contents.used; current++){ - if (data->contents.array[current].used > 0){ - name_length = data->contents.array[current].array[0].stop - data->contents.array[current].array[0].start + 1; - - if (name_length == argv_length){ - if (fl_compare_strings(data->buffer.string + data->contents.array[current].array[0].start, argv[data->parameters[fss_basic_list_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional && found == target)){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } - - if (data->parameters[fss_basic_list_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } - } - } - } - } - } // for } - } + } // for } } - - // clear buffers before repeating the loop - f_delete_fss_contents(allocation_status, data->contents); - f_delete_fss_objects(allocation_status, data->objects); - f_delete_dynamic_string(allocation_status, data->buffer); - } // for - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files"); + } } - - fss_basic_list_read_delete_data(data); - return status; } #endif // _di_fss_basic_list_read_main_ diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.h b/level_3/fss_basic_list_read/c/fss_basic_list_read.h index c28a787..60cc32e 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.h @@ -23,6 +23,7 @@ #include #include #include +#include // fll-1 includes #include @@ -107,6 +108,7 @@ extern "C"{ f_fss_contents contents; f_file_position file_position; f_string_lengths remaining; + f_bool process_pipe; fll_color_context context; } fss_basic_list_read_data; @@ -119,6 +121,7 @@ extern "C"{ f_fss_contents_initialize, \ f_file_position_initialize, \ f_string_lengths_initialize, \ + f_false, \ fll_color_context_initialize, \ } #endif // _di_fss_basic_list_read_data_ diff --git a/level_3/fss_basic_list_read/c/main.c b/level_3/fss_basic_list_read/c/main.c index ed8ba20..f0ae4a7 100644 --- a/level_3/fss_basic_list_read/c/main.c +++ b/level_3/fss_basic_list_read/c/main.c @@ -4,6 +4,10 @@ int main(const f_array_length argc, const f_string argv[]){ f_status status = f_status_initialize; fss_basic_list_read_data data = fss_basic_list_read_data_initialize; + if (f_pipe_exists()){ + data.process_pipe = f_true; + } + status = fss_basic_list_read_main(argc, argv, &data); if (status == f_none) return 0; diff --git a/level_3/fss_basic_list_read/data/build/settings b/level_3/fss_basic_list_read/data/build/settings index 92501ea..88f7c0d 100644 --- a/level_3/fss_basic_list_read/data/build/settings +++ b/level_3/fss_basic_list_read/data/build/settings @@ -1,6 +1,6 @@ # fss-0000 -project_name fss_basic_list_Read +project_name fss_basic_list_read project_level 3 version_major 0 @@ -8,7 +8,7 @@ version_minor 3 version_micro 0 build_compiler gcc -build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfl_execute -lfll_fss -lfll_colors +build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfl_execute -lfll_fss -lfll_colors -lf_pipe build_sources_library fss_basic_list_read.c build_sources_program main.c build_sources_headers fss_basic_list_read.h diff --git a/level_3/fss_basic_read/c/fss_basic_read.c b/level_3/fss_basic_read/c/fss_basic_read.c index 58aa8a9..c310f71 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -115,6 +115,8 @@ extern "C"{ #endif // _di_fss_basic_read_print_help_ #ifndef _di_fss_basic_read_main_ + f_return_status fss_basic_read_main_process_file(const f_array_length argc, const f_string argv[], fss_basic_read_data *data, const f_string filename, const f_string_length target) __attribute__((visibility("internal"))); + f_return_status fss_basic_read_main(const f_array_length argc, const f_string argv[], fss_basic_read_data *data){ f_status status = f_status_initialize; f_status allocation_status = f_status_initialize; @@ -157,244 +159,298 @@ extern "C"{ fss_basic_read_print_help(*data); } else if (data->parameters[fss_basic_read_parameter_version].result == f_console_result_found){ fss_basic_read_print_version(*data); - } else if (data->remaining.used > 0){ + } else if (data->remaining.used > 0 || data->process_pipe){ f_string_length counter = f_string_length_initialize; - f_string_length current = f_string_length_initialize; f_string_length target = f_string_length_initialize; - f_string_length found = f_string_length_initialize; f_string_length original_size = data->file_position.total_elements; if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ target = (f_string_length) atoll(argv[data->parameters[fss_basic_read_parameter_count].additional]); } - for (; counter < data->remaining.used; counter++){ + if (data->process_pipe) { f_file file = f_file_initialize; - status = f_file_open(&file, argv[data->remaining.array[counter]]); - - data->file_position.total_elements = original_size; - - if (status != f_none){ - if (status == f_invalid_parameter){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()"); - } else if (status == f_file_not_found){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to find the file '%s'", argv[data->remaining.array[counter]]); - } else if (status == f_file_open_error){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to open the file '%s'", argv[data->remaining.array[counter]]); - } else if (status == f_file_descriptor_error){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: File descriptor error while trying to open the file '%s'", argv[data->remaining.array[counter]]); - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", status); - } - - fss_basic_read_delete_data(data); - return status; - } - - // TODO: this file size set functionality might be turned into an fl_file (or f_file) function - if (data->file_position.total_elements == 0){ - fseek(file.file, 0, SEEK_END); - - data->file_position.total_elements = ftell(file.file); - - // skip past empty files - if (data->file_position.total_elements == 0){ - f_file_close(&file); - continue; - } - - fseek(file.file, 0, SEEK_SET); - } - - status = fl_file_read(file, data->file_position, &data->buffer); + file.file = f_pipe; - f_file_close(&file); + status = fl_file_read_fifo(file, &data->buffer); if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ if (status == f_invalid_parameter){ fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_file_read()"); } else if (status == f_overflow){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", argv[data->remaining.array[counter]]); + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", "-"); } else if (status == f_file_not_open){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: The file '%s' is no longer open", argv[data->remaining.array[counter]]); + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: The file '%s' is no longer open", "-"); } else if (status == f_file_seek_error){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A seek error occurred while accessing the file '%s'", argv[data->remaining.array[counter]]); + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A seek error occurred while accessing the file '%s'", "-"); } else if (status == f_file_read_error){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A read error occurred while accessing the file '%s'", argv[data->remaining.array[counter]]); + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A read error occurred while accessing the file '%s'", "-"); } else if (f_macro_test_for_allocation_errors(status)){ fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", status); + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", "-"); } fss_basic_read_delete_data(data); return status; } - { - f_string_location input = f_string_location_initialize; - - input.start = 0; - input.stop = data->buffer.used - 1; + status = fss_basic_read_main_process_file(argc, argv, data, "-", target); - status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents); + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + return status; } - if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content){ - if (status == f_invalid_parameter){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", argv[data->remaining.array[counter]]); + // clear buffers before continuing + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + } + + if (data->remaining.used > 0){ + for (; counter < data->remaining.used; counter++){ + f_file file = f_file_initialize; + + status = f_file_open(&file, argv[data->remaining.array[counter]]); + + data->file_position.total_elements = original_size; + + if (status != f_none){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()"); + } else if (status == f_file_not_found){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to find the file '%s'", argv[data->remaining.array[counter]]); + } else if (status == f_file_open_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to open the file '%s'", argv[data->remaining.array[counter]]); + } else if (status == f_file_descriptor_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: File descriptor error while trying to open the file '%s'", argv[data->remaining.array[counter]]); + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", status); + } fss_basic_read_delete_data(data); return status; - } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop || status == f_no_data_on_eof){ - // not an error in this case - } else if (f_macro_test_for_allocation_errors(status)){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + } + + // TODO: this file size set functionality might be turned into an fl_file (or f_file) function + if (data->file_position.total_elements == 0){ + fseek(file.file, 0, SEEK_END); + + data->file_position.total_elements = ftell(file.file); + + // skip past empty files + if (data->file_position.total_elements == 0){ + f_file_close(&file); + continue; + } + + fseek(file.file, 0, SEEK_SET); + } + + status = fl_file_read(file, data->file_position, &data->buffer); + + f_file_close(&file); + + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_file_read()"); + } else if (status == f_overflow){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", argv[data->remaining.array[counter]]); + } else if (status == f_file_not_open){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: The file '%s' is no longer open", argv[data->remaining.array[counter]]); + } else if (status == f_file_seek_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A seek error occurred while accessing the file '%s'", argv[data->remaining.array[counter]]); + } else if (status == f_file_read_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A read error occurred while accessing the file '%s'", argv[data->remaining.array[counter]]); + } else if (f_macro_test_for_allocation_errors(status)){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", argv[data->remaining.array[counter]]); + } fss_basic_read_delete_data(data); return status; - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", status, argv[data->remaining.array[counter]]); } - // clear buffers, then attempt the next file + status = fss_basic_read_main_process_file(argc, argv, data, argv[data->remaining.array[counter]], target); + + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + return status; + } + + // clear buffers before repeating the loop f_delete_fss_contents(allocation_status, data->contents); f_delete_fss_objects(allocation_status, data->objects); f_delete_dynamic_string(allocation_status, data->buffer); + } // for + } + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files"); + } - continue; - } + fss_basic_read_delete_data(data); + return status; + } + + f_return_status fss_basic_read_main_process_file(const f_array_length argc, const f_string argv[], fss_basic_read_data *data, const f_string filename, const f_string_length target){ + f_status status = f_status_initialize; + f_status allocation_status = f_status_initialize; + + f_string_length current = f_string_length_initialize; + f_string_length found = f_string_length_initialize; + + { + f_string_location input = f_string_location_initialize; + + input.start = 0; + input.stop = data->buffer.used - 1; + + status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents); + } + + if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); + + fss_basic_read_delete_data(data); + return status; + } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop || status == f_no_data_on_eof){ + // not an error in this case + } else if (f_macro_test_for_allocation_errors(status)){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + + fss_basic_read_delete_data(data); + return status; + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", status, filename); + } - // now that all of the files have been read, process the objects and contents - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_name].result == f_console_result_none){ - fprintf(f_standard_output, "%u\n", (unsigned int) data->objects.used); + // clear buffers, then attempt the next file + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + + return f_none; + } + + // now that the file has been read, process the objects and contents + if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_name].result == f_console_result_none){ + fprintf(f_standard_output, "%u\n", (unsigned int) data->objects.used); + } else { + current = 0; + + if (data->parameters[fss_basic_read_parameter_name].result == f_console_result_none){ + if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_none){ + for (; current < data->objects.used; current++){ + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ + if (data->contents.array[current].used > 0){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); + fprintf(f_standard_output, "\n"); + } else { + // for all objects with no data, print a newline + fprintf(f_standard_output, "\n"); + } + } + + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } + } + } // for } else { - current = 0; - - if (data->parameters[fss_basic_read_parameter_name].result == f_console_result_none){ - if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_none){ - for (; current < data->objects.used; current++){ - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ - if (data->contents.array[current].used > 0){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); - fprintf(f_standard_output, "\n"); - } else { - // for all objects with no data, print a newline - fprintf(f_standard_output, "\n"); - } - } + for (; current < data->objects.used; current++){ + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); + fprintf(f_standard_output, "\n"); + } - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } + } + } // for + } + } else { + current = 0; + + f_string_length total = f_string_length_initialize; + f_string_length name_length = f_string_length_initialize; + f_string_length argv_length = f_string_length_initialize; + + if (data->parameters[fss_basic_read_parameter_name].result == f_console_result_additional){ + argv_length = strlen(argv[data->parameters[fss_basic_read_parameter_name].additional]); + + if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_none){ + for (; current < data->objects.used; current++){ + name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; + + if (name_length == argv_length){ + if (fl_compare_strings(data->buffer.string + data->objects.array[current].start, argv[data->parameters[fss_basic_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ + + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ + if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found){ + total++; + } else { + if (data->contents.array[current].used > 0){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); + fprintf(f_standard_output, "\n"); + } else { + // for all objects with no data, print a newline + fprintf(f_standard_output, "\n"); + } + } } - } - } // for - } else { - for (; current < data->objects.used; current++){ - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } } } - } // for + } + } // for + + if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_count].result == f_console_result_none){ + fprintf(f_standard_output, f_string_length_printf "\n", total); } } else { - current = 0; - - f_string_length total = f_string_length_initialize; - f_string_length name_length = f_string_length_initialize; - f_string_length argv_length = f_string_length_initialize; - - if (data->parameters[fss_basic_read_parameter_name].result == f_console_result_additional){ - argv_length = strlen(argv[data->parameters[fss_basic_read_parameter_name].additional]); - - if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_none){ - for (; current < data->objects.used; current++){ - name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; - - if (name_length == argv_length){ - if (fl_compare_strings(data->buffer.string + data->objects.array[current].start, argv[data->parameters[fss_basic_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ - - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found){ - total++; - } else { - if (data->contents.array[current].used > 0){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[0]); - fprintf(f_standard_output, "\n"); - } else { - // for all objects with no data, print a newline - fprintf(f_standard_output, "\n"); - } - } - } - - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } - } + // when and because the object parameter is specified, the name parameter refers to the content instead of the object + // therefore, make the search on the content and display the object + for (; current < data->contents.used; current++){ + if (data->contents.array[current].used > 0){ + name_length = data->contents.array[current].array[0].stop - data->contents.array[current].array[0].start + 1; + + if (name_length == argv_length){ + if (fl_compare_strings(data->buffer.string + data->contents.array[current].array[0].start, argv[data->parameters[fss_basic_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); + fprintf(f_standard_output, "\n"); } - } - } // for - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_count].result == f_console_result_none){ - fprintf(f_standard_output, f_string_length_printf "\n", total); - } - } else { - // when and because the object parameter is specified, the name parameter refers to the content instead of the object - // therefore, make the search on the content and display the object - for (; current < data->contents.used; current++){ - if (data->contents.array[current].used > 0){ - name_length = data->contents.array[current].array[0].stop - data->contents.array[current].array[0].start + 1; - - if (name_length == argv_length){ - if (fl_compare_strings(data->buffer.string + data->contents.array[current].array[0].start, argv[data->parameters[fss_basic_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_none || (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional && found == target)){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } - - if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } - } + if (data->parameters[fss_basic_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; } } } - } // for + } } - } + } // for } } - - // clear buffers before repeating the loop - f_delete_fss_contents(allocation_status, data->contents); - f_delete_fss_objects(allocation_status, data->objects); - f_delete_dynamic_string(allocation_status, data->buffer); - } // for - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files"); + } } - - fss_basic_read_delete_data(data); - return status; } #endif // _di_fss_basic_read_main_ diff --git a/level_3/fss_basic_read/c/fss_basic_read.h b/level_3/fss_basic_read/c/fss_basic_read.h index 630caf8..5445071 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -23,6 +23,7 @@ #include #include #include +#include // fll-1 includes #include @@ -99,6 +100,7 @@ extern "C"{ f_fss_contents contents; f_file_position file_position; f_string_lengths remaining; + f_bool process_pipe; fll_color_context context; } fss_basic_read_data; @@ -111,6 +113,7 @@ extern "C"{ f_fss_contents_initialize, \ f_file_position_initialize, \ f_string_lengths_initialize, \ + f_false, \ fll_color_context_initialize, \ } #endif // _di_fss_basic_read_data_ diff --git a/level_3/fss_basic_read/c/main.c b/level_3/fss_basic_read/c/main.c index f1c8121..39ab095 100644 --- a/level_3/fss_basic_read/c/main.c +++ b/level_3/fss_basic_read/c/main.c @@ -4,6 +4,10 @@ int main(const f_array_length argc, const f_string argv[]){ f_status status = f_status_initialize; fss_basic_read_data data = fss_basic_read_data_initialize; + if (f_pipe_exists()){ + data.process_pipe = f_true; + } + status = fss_basic_read_main(argc, argv, &data); if (status == f_none) return 0; diff --git a/level_3/fss_basic_read/data/build/settings b/level_3/fss_basic_read/data/build/settings index 657dba8..4411ec1 100644 --- a/level_3/fss_basic_read/data/build/settings +++ b/level_3/fss_basic_read/data/build/settings @@ -8,7 +8,7 @@ version_minor 3 version_micro 0 build_compiler gcc -build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfl_execute -lfll_fss -lfll_colors +build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfl_execute -lfll_fss -lfll_colors -lf_pipe build_sources_library fss_basic_read.c build_sources_program main.c build_sources_headers fss_basic_read.h diff --git a/level_3/fss_extended_read/c/fss_extended_read.c b/level_3/fss_extended_read/c/fss_extended_read.c index a4be74e..48e0ec2 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.c +++ b/level_3/fss_extended_read/c/fss_extended_read.c @@ -122,6 +122,8 @@ extern "C"{ #endif // _di_fss_extended_read_print_help_ #ifndef _di_fss_extended_read_main_ + f_return_status fss_extended_read_main_process_file(const f_array_length argc, const f_string argv[], fss_extended_read_data *data, const f_string filename, const f_string_length target, const f_string_length select) __attribute__((visibility("internal"))); + f_return_status fss_extended_read_main(const f_array_length argc, const f_string argv[], fss_extended_read_data *data){ f_status status = f_status_initialize; f_status allocation_status = f_status_initialize; @@ -164,11 +166,9 @@ extern "C"{ fss_extended_read_print_help(*data); } else if (data->parameters[fss_extended_read_parameter_version].result == f_console_result_found){ fss_extended_read_print_version(*data); - } else if (data->remaining.used > 0){ + } else if (data->remaining.used > 0 || data->process_pipe){ f_string_length counter = f_string_length_initialize; - f_string_length current = f_string_length_initialize; f_string_length target = f_string_length_initialize; - f_string_length found = f_string_length_initialize; f_string_length select = f_string_length_initialize; f_string_length original_size = data->file_position.total_elements; @@ -180,6 +180,43 @@ extern "C"{ select = (f_string_length) atoll(argv[data->parameters[fss_extended_read_parameter_select].additional]); } + if (data->process_pipe) { + f_file file = f_file_initialize; + + file.file = f_pipe; + + status = fl_file_read_fifo(file, &data->buffer); + + if (status != f_none){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()"); + } else if (status == f_file_not_found){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to find the file '%s'", "-"); + } else if (status == f_file_open_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to open the file '%s'", "-"); + } else if (status == f_file_descriptor_error){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: File descriptor error while trying to open the file '%s'", "-"); + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", status); + } + + fss_extended_read_delete_data(data); + return status; + } + + status = fss_extended_read_main_process_file(argc, argv, data, "-", target, select); + + + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + return status; + } + + // clear buffers before continuing + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + } + for (; counter < data->remaining.used; counter++){ f_file file = f_file_initialize; @@ -244,169 +281,183 @@ extern "C"{ return status; } - { - f_string_location input = f_string_location_initialize; + status = fss_extended_read_main_process_file(argc, argv, data, argv[data->remaining.array[counter]], target, select); - input.start = 0; - input.stop = data->buffer.used - 1; - - status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents); + if (status != f_none && status != f_none_on_eof && status != f_none_on_eos){ + return status; } - if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content){ - if (status == f_invalid_parameter){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_read() for the file '%s'", argv[data->remaining.array[counter]]); + // clear buffers before repeating the loop + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + } // for + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files"); + } - fss_extended_read_delete_data(data); - return status; - } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop || status == f_no_data_on_eof){ - // not an error in this case - } else if (f_macro_test_for_allocation_errors(status)){ - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + fss_extended_read_delete_data(data); + return status; + } - fss_extended_read_delete_data(data); - return status; - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_read() for the file '%s'", status, argv[data->remaining.array[counter]]); - } + f_return_status fss_extended_read_main_process_file(const f_array_length argc, const f_string argv[], fss_extended_read_data *data, const f_string filename, const f_string_length target, const f_string_length select) { + f_status status = f_status_initialize; + f_status allocation_status = f_status_initialize; - // clear buffers, then attempt the next file - f_delete_fss_contents(allocation_status, data->contents); - f_delete_fss_objects(allocation_status, data->objects); - f_delete_dynamic_string(allocation_status, data->buffer); + f_string_length current = f_string_length_initialize; + f_string_length found = f_string_length_initialize; - continue; - } + { + f_string_location input = f_string_location_initialize; + + input.start = 0; + input.stop = data->buffer.used - 1; + + status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents); + } + + if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content){ + if (status == f_invalid_parameter){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_read() for the file '%s'", filename); - // now that all of the files have been read, process the objects and contents - if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_name].result == f_console_result_none){ - fprintf(f_standard_output, "%u\n", (unsigned int) data->objects.used); + fss_extended_read_delete_data(data); + return status; + } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop || status == f_no_data_on_eof){ + // not an error in this case + } else if (f_macro_test_for_allocation_errors(status)){ + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + + fss_extended_read_delete_data(data); + return status; + } else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_read() for the file '%s'", status, filename); + } + + // clear buffers, then attempt the next file + f_delete_fss_contents(allocation_status, data->contents); + f_delete_fss_objects(allocation_status, data->objects); + f_delete_dynamic_string(allocation_status, data->buffer); + + return status; + } + + // now that all of the files have been read, process the objects and contents + if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found && data->parameters[fss_extended_read_parameter_name].result == f_console_result_none){ + fprintf(f_standard_output, "%u\n", (unsigned int) data->objects.used); + } else { + current = 0; + + if (data->parameters[fss_extended_read_parameter_name].result == f_console_result_none){ + if (data->parameters[fss_extended_read_parameter_object].result == f_console_result_none){ + for (; current < data->objects.used; current++){ + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ + if (data->contents.array[current].used > select){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[select]); + fprintf(f_standard_output, "\n"); + } else { + // for all objects with no data, print a newline + fprintf(f_standard_output, "\n"); + } + } + + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } + } + } // for } else { - current = 0; - - if (data->parameters[fss_extended_read_parameter_name].result == f_console_result_none){ - if (data->parameters[fss_extended_read_parameter_object].result == f_console_result_none){ - for (; current < data->objects.used; current++){ - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ - if (data->contents.array[current].used > select){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[select]); - fprintf(f_standard_output, "\n"); - } else { - // for all objects with no data, print a newline - fprintf(f_standard_output, "\n"); - } - } + for (; current < data->objects.used; current++){ + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); + fprintf(f_standard_output, "\n"); + } - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } + } + } // for + } + } else { + current = 0; + + f_string_length total = f_string_length_initialize; + f_string_length name_length = f_string_length_initialize; + f_string_length argv_length = f_string_length_initialize; + + if (data->parameters[fss_extended_read_parameter_name].result == f_console_result_additional){ + argv_length = strlen(argv[data->parameters[fss_extended_read_parameter_name].additional]); + + if (data->parameters[fss_extended_read_parameter_object].result == f_console_result_none){ + for (; current < data->objects.used; current++){ + name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; + + if (name_length == argv_length){ + if (fl_compare_strings(data->buffer.string + data->objects.array[current].start, argv[data->parameters[fss_extended_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ + + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ + if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found){ + total++; + } else { + if (data->contents.array[current].used > select){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[select]); + fprintf(f_standard_output, "\n"); + } else { + // for all objects with no data, print a newline + fprintf(f_standard_output, "\n"); + } + } } - } - } // for - } else { - for (; current < data->objects.used; current++){ - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; + } } } - } // for + } + } // for + + if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found && data->parameters[fss_extended_read_parameter_count].result == f_console_result_none){ + fprintf(f_standard_output, f_string_length_printf "\n", total); } } else { - current = 0; - - f_string_length total = f_string_length_initialize; - f_string_length name_length = f_string_length_initialize; - f_string_length argv_length = f_string_length_initialize; - - if (data->parameters[fss_extended_read_parameter_name].result == f_console_result_additional){ - argv_length = strlen(argv[data->parameters[fss_extended_read_parameter_name].additional]); - - if (data->parameters[fss_extended_read_parameter_object].result == f_console_result_none){ - for (; current < data->objects.used; current++){ - name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; - - if (name_length == argv_length){ - if (fl_compare_strings(data->buffer.string + data->objects.array[current].start, argv[data->parameters[fss_extended_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ - - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found){ - total++; - } else { - if (data->contents.array[current].used > select){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->contents.array[current].array[select]); - fprintf(f_standard_output, "\n"); - } else { - // for all objects with no data, print a newline - fprintf(f_standard_output, "\n"); - } - } - } - - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } - } + // when and because the object parameter is specified, the name parameter refers to the content instead of the object + // therefore, make the search on the content and display the object + for (; current < data->contents.used; current++){ + if (data->contents.array[current].used > select){ + name_length = data->contents.array[current].array[select].stop - data->contents.array[current].array[select].start + 1; + + if (name_length == argv_length){ + if (fl_compare_strings(data->buffer.string + data->contents.array[current].array[select].start, argv[data->parameters[fss_extended_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ + f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); + fprintf(f_standard_output, "\n"); } - } - } // for - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_read_parameter_count].result == f_console_result_none){ - fprintf(f_standard_output, f_string_length_printf "\n", total); - } - } else { - // when and because the object parameter is specified, the name parameter refers to the content instead of the object - // therefore, make the search on the content and display the object - for (; current < data->contents.used; current++){ - if (data->contents.array[current].used > select){ - name_length = data->contents.array[current].array[select].stop - data->contents.array[current].array[select].start + 1; - - if (name_length == argv_length){ - if (fl_compare_strings(data->buffer.string + data->contents.array[current].array[select].start, argv[data->parameters[fss_extended_read_parameter_name].additional], name_length, argv_length) == f_equal_to){ - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional && found == target)){ - f_print_partial_dynamic_string(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } - - if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ - if (found == target){ - break; - } else { - found++; - } - } + if (data->parameters[fss_extended_read_parameter_count].result == f_console_result_additional){ + if (found == target){ + break; + } else { + found++; } } } - } // for + } } - } + } // for } } - - // clear buffers before repeating the loop - f_delete_fss_contents(allocation_status, data->contents); - f_delete_fss_objects(allocation_status, data->objects); - f_delete_dynamic_string(allocation_status, data->buffer); - } // for - } else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files"); + } } - - fss_extended_read_delete_data(data); - return status; } #endif // _di_fss_extended_read_main_ diff --git a/level_3/fss_extended_read/c/fss_extended_read.h b/level_3/fss_extended_read/c/fss_extended_read.h index c761299..d967ab2 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.h +++ b/level_3/fss_extended_read/c/fss_extended_read.h @@ -23,6 +23,7 @@ #include #include #include +#include // fll-1 includes #include @@ -103,6 +104,7 @@ extern "C"{ f_fss_contents contents; f_file_position file_position; f_string_lengths remaining; + f_bool process_pipe; fll_color_context context; } fss_extended_read_data; @@ -115,6 +117,7 @@ extern "C"{ f_fss_contents_initialize, \ f_file_position_initialize, \ f_string_lengths_initialize, \ + f_false, \ fll_color_context_initialize, \ } #endif // _di_fss_extended_read_data_ diff --git a/level_3/fss_extended_read/c/main.c b/level_3/fss_extended_read/c/main.c index c7e67a0..ea28fe7 100644 --- a/level_3/fss_extended_read/c/main.c +++ b/level_3/fss_extended_read/c/main.c @@ -4,6 +4,10 @@ int main(const f_array_length argc, const f_string argv[]){ f_status status = f_status_initialize; fss_extended_read_data data = fss_extended_read_data_initialize; + if (f_pipe_exists()){ + data.process_pipe = f_true; + } + status = fss_extended_read_main(argc, argv, &data); if (status == f_none) return 0; diff --git a/level_3/fss_extended_read/data/build/settings b/level_3/fss_extended_read/data/build/settings index fe3d125..ca33cd7 100644 --- a/level_3/fss_extended_read/data/build/settings +++ b/level_3/fss_extended_read/data/build/settings @@ -8,7 +8,7 @@ version_minor 3 version_micro 0 build_compiler gcc -build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfl_execute -lfll_fss -lfll_colors +build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfl_execute -lfll_fss -lfll_colors -lf_pipe build_sources_library fss_extended_read.c build_sources_program main.c build_sources_headers fss_extended_read.h -- 1.8.3.1