From ac5b4c7c32317ad99145442d6c4e4edb1f906a77 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 6 Oct 2020 23:11:16 -0500 Subject: [PATCH] Progress: continue working on FSS read/write programs and related. Get comment delimitation working in FSS read/write functions. - Comments are now escaped on read/write as appropriate. - Rename appropriate private fl_fss functions. - Add object_as boolean to designate whether or not this function is meant to read an object or content. - This ends up fixing a bug in the fl_fss_extended read function where a comment character before a content is incorrectly treated as an actual comment (this behavior is not allowed). - Add similar behavior to the write functions. - The basic list and especially the extended list may not be complete in this regard. Do some cleanup in the fss read programs that is related to the changes in this commit. - There is still room for cleanups but that is not my focus at this time. Add a -p/--pipe parameter to the FSS read functions to provide a way of returning data in the pipe-friendly format used by the FSS write programs. --- level_1/fl_fss/c/fss_basic.c | 4 +- level_1/fl_fss/c/fss_basic_list.c | 9 +- level_1/fl_fss/c/fss_extended.c | 28 ++--- level_1/fl_fss/c/private-fss.c | 133 ++++++++++++++------ level_1/fl_fss/c/private-fss.h | 16 ++- .../fss_basic_list_read/c/fss_basic_list_read.c | 138 ++++++++++----------- .../fss_basic_list_read/c/fss_basic_list_read.h | 9 +- .../c/private-fss_basic_list_read.c | 103 ++++++++------- .../c/private-fss_basic_list_read.h | 30 +++++ level_3/fss_basic_read/c/fss_basic_read.c | 137 ++++++++++---------- level_3/fss_basic_read/c/fss_basic_read.h | 9 +- level_3/fss_basic_read/c/private-fss_basic_read.c | 83 ++++++------- level_3/fss_basic_read/c/private-fss_basic_read.h | 20 +++ .../c/fss_extended_list_read.c | 131 +++++++++---------- .../c/fss_extended_list_read.h | 9 +- .../c/private-fss_extended_list_read.c | 103 ++++++++------- .../c/private-fss_extended_list_read.h | 30 +++++ level_3/fss_extended_read/c/fss_extended_read.c | 137 ++++++++++---------- level_3/fss_extended_read/c/fss_extended_read.h | 9 +- .../c/private-fss_extended_read.c | 119 +++++++++--------- .../c/private-fss_extended_read.h | 30 +++++ specifications/fss.txt | 2 +- 22 files changed, 742 insertions(+), 547 deletions(-) diff --git a/level_1/fl_fss/c/fss_basic.c b/level_1/fl_fss/c/fss_basic.c index 969cf3b..af633f8 100644 --- a/level_1/fl_fss/c/fss_basic.c +++ b/level_1/fl_fss/c/fss_basic.c @@ -19,7 +19,7 @@ extern "C" { f_status_t status = F_none; f_string_lengths_t delimits = f_string_lengths_t_initialize; - status = private_fl_fss_basic_object_read(buffer, range, found, quote, &delimits); + status = private_fl_fss_basic_read(F_true, buffer, range, found, quote, &delimits); if (F_status_is_error(status)) { f_macro_string_lengths_t_delete_simple(delimits); @@ -98,7 +98,7 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = private_fl_fss_basic_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination); + f_status_t status = private_fl_fss_basic_write(F_true, object, quote ? quote : f_fss_delimit_quote_double, range, destination); if (status == F_data_not_stop || status == F_data_not_eos) { diff --git a/level_1/fl_fss/c/fss_basic_list.c b/level_1/fl_fss/c/fss_basic_list.c index da57001..2573e85 100644 --- a/level_1/fl_fss/c/fss_basic_list.c +++ b/level_1/fl_fss/c/fss_basic_list.c @@ -441,9 +441,12 @@ extern "C" { while (range->start <= range->stop && range->start < object.used) { if (object.string[range->start] == f_fss_comment) { - // @todo the standard may be updated to allow escaping comments. - // comments are not allowed and this format has no way of "wrapping" a comment. - status = F_status_set_error(FL_fss_found_comment); + + // when a comment is found, escape it. + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + + destination->string[destination->used++] = f_fss_delimit_slash; break; } diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index f93a0f9..6ce2e60 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -19,7 +19,7 @@ extern "C" { f_status_t status = F_none; f_string_lengths_t delimits = f_string_lengths_t_initialize; - status = private_fl_fss_basic_object_read(buffer, range, found, quoted, &delimits); + status = private_fl_fss_basic_read(F_true, buffer, range, found, quoted, &delimits); if (F_status_is_error(status)) { f_macro_string_lengths_t_delete_simple(delimits); @@ -74,7 +74,7 @@ extern "C" { f_string_range_t content_partial = f_string_range_t_initialize; f_fss_quote_t quoted = 0; - status = private_fl_fss_basic_object_read(buffer, range, &content_partial, "ed, &delimits); + status = private_fl_fss_basic_read(F_false, buffer, range, &content_partial, "ed, &delimits); if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) { if (found->used == found->size) { @@ -163,12 +163,12 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = private_fl_fss_basic_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination); + f_status_t status = private_fl_fss_basic_write(F_true, object, quote ? quote : f_fss_delimit_quote_double, range, destination); if (status == F_data_not_stop || status == F_data_not_eos) { // Objects cannot be empty, so write a quoted empty string. - const f_status_t status_allocation = private_fl_fss_destination_increase_by(3, destination); + const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination); if (F_status_is_error(status_allocation)) return status_allocation; destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; @@ -196,13 +196,12 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con #endif // _di_level_1_parameter_checking_ // this operates exactly like an object, syntax-wise. - const f_status_t status = private_fl_fss_basic_object_write(content, quote ? quote : f_fss_delimit_quote_double, range, destination); + const f_status_t status = private_fl_fss_basic_write(F_false, content, quote ? quote : f_fss_delimit_quote_double, range, destination); if (status == F_data_not_stop || status == F_data_not_eos) { - f_status_t status_allocation = F_none; // content that is empty must be represented by a quoted empty string. - status_allocation = private_fl_fss_destination_increase_by(3, destination); + const f_status_t status_allocation = private_fl_fss_destination_increase_by(4, destination); if (F_status_is_error(status_allocation)) return status_allocation; destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; @@ -210,16 +209,10 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con // content should be terminated, even if empty. if (complete == f_fss_complete_partial || complete == f_fss_complete_full || complete == f_fss_complete_next) { - status_allocation = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status_allocation)) return status_allocation; - destination->string[destination->used++] = f_fss_extended_next; } if (complete == f_fss_complete_full || complete == f_fss_complete_end) { - status_allocation = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status_allocation)) return status_allocation; - destination->string[destination->used++] = f_fss_extended_close; } @@ -231,19 +224,14 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con } if (F_status_is_error_not(status)) { - f_status_t status_allocation = F_none; + const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination); + if (F_status_is_error(status_allocation)) return status_allocation; if (complete == f_fss_complete_partial || complete == f_fss_complete_full || complete == f_fss_complete_next) { - status_allocation = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status_allocation)) return status_allocation; - destination->string[destination->used++] = f_fss_extended_next; } if (complete == f_fss_complete_full || complete == f_fss_complete_end) { - status_allocation = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status_allocation)) return status_allocation; - destination->string[destination->used++] = f_fss_extended_close; } } diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index 94ba99e..6d8caf2 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -6,7 +6,7 @@ extern "C" { #endif #if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) - f_return_status private_fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) { + f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote, f_string_lengths_t *delimits) { f_status_t status = F_none; status = f_fss_skip_past_space(*buffer, range); @@ -28,7 +28,7 @@ extern "C" { found->start = range->start; // ignore all comment lines. - if (buffer->string[range->start] == f_fss_comment) { + if (object_as && buffer->string[range->start] == f_fss_comment) { while (buffer->string[range->start] != f_string_eol[0]) { range->start++; @@ -46,10 +46,10 @@ extern "C" { const f_string_length_t delimit_initial = delimits->used; // handle quoted support. - int8_t quote = 0; + int8_t quote_found = 0; - if (quoted) { - *quoted = 0; + if (quote) { + *quote = 0; } // identify where the object begins. @@ -112,7 +112,7 @@ extern "C" { return F_none_stop; } - if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double) { + if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double || (object_as && buffer->string[range->start] == f_fss_comment)) { // only the first slash before a quoted needs to be escaped (or not) as once there is a slash before a quoted, this cannot ever be a quote object. // this simplifies the number of slashes needed. @@ -139,7 +139,7 @@ extern "C" { } } else if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double) { - quote = buffer->string[range->start]; + quote_found = buffer->string[range->start]; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; @@ -148,7 +148,7 @@ extern "C" { } // identify where the object ends. - if (!quote) { + if (!quote_found) { status = F_none; while (range->start <= range->stop && range->start < buffer->used) { @@ -213,7 +213,7 @@ extern "C" { return F_unterminated_group_stop; } - if (buffer->string[range->start] == quote) { + if (buffer->string[range->start] == quote_found) { f_string_length_t location = range->start; // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted and delimits do not apply. @@ -239,12 +239,12 @@ extern "C" { } if (status == F_true) { - if (quoted) { - if (quote == f_fss_delimit_quote_single) { - *quoted = f_fss_quote_type_single; + if (quote) { + if (quote_found == f_fss_delimit_quote_single) { + *quote = f_fss_quote_type_single; } - else if (quote == f_fss_delimit_quote_double) { - *quoted = f_fss_quote_type_double; + else if (quote_found == f_fss_delimit_quote_double) { + *quote = f_fss_quote_type_double; } } @@ -355,7 +355,7 @@ extern "C" { } } } - else if (buffer->string[range->start] == quote) { + else if (buffer->string[range->start] == quote_found) { // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted. { f_string_length_t location = range->start; @@ -385,12 +385,12 @@ extern "C" { } if (status == F_true) { - if (quoted) { - if (quote == f_fss_delimit_quote_single) { - *quoted = f_fss_quote_type_single; + if (quote) { + if (quote_found == f_fss_delimit_quote_single) { + *quote = f_fss_quote_type_single; } - else if (quote == f_fss_delimit_quote_double) { - *quoted = f_fss_quote_type_double; + else if (quote_found == f_fss_delimit_quote_double) { + *quote = f_fss_quote_type_double; } } @@ -496,7 +496,7 @@ extern "C" { #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) #if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_) - f_return_status private_fl_fss_basic_object_write(const f_string_static_t object, const f_fss_quote_t quote, f_string_range_t *range, f_string_dynamic_t *destination) { + f_return_status private_fl_fss_basic_write(const bool object_as, const f_string_static_t object, const f_fss_quote_t quote, f_string_range_t *range, f_string_dynamic_t *destination) { f_status_t status = F_none; fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); @@ -517,6 +517,7 @@ extern "C" { const f_string_length_t used_start = destination->used; bool quoted = F_false; + bool commented = F_false; f_string_length_t item_first = 0; f_string_length_t item_total = 0; @@ -531,6 +532,9 @@ extern "C" { if (object.string[input_start] == quote) { quoted = F_true; } + else if (object_as && object.string[input_start] == f_fss_comment) { + commented = F_true; + } uint8_t width = 0; @@ -551,19 +555,30 @@ extern "C" { } // for if (range->start > range->stop || range->start >= object.used) { + + // slashes before the final quote must be escaped when quoted, add the delimit slashes. if (quoted) { - // slashes before the final quote must be escaped when quoted, add the delimit slashes. + // if this is the first quote, then only a single delimit slash is needed. if (item_first == input_start) { + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + destination->string[destination->used++] = f_fss_delimit_slash; } else { + status = private_fl_fss_destination_increase_by(item_total, destination); + if (F_status_is_error(status)) break; + for (i = 0; i < item_total; i++) { destination->string[destination->used++] = f_fss_delimit_slash; } // for } } + status = private_fl_fss_destination_increase_by(item_total, destination); + if (F_status_is_error(status)) break; + for (i = 0; i < item_total; i++) { destination->string[destination->used++] = f_fss_delimit_slash; } // for @@ -581,6 +596,9 @@ extern "C" { fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); if (range->start > range->stop || range->start >= object.used) { + status = private_fl_fss_destination_increase_by(item_total + 1, destination); + if (F_status_is_error(status)) break; + for (i = 0; i < item_total; i++) { destination->string[destination->used++] = f_fss_delimit_slash; } // for @@ -602,29 +620,53 @@ extern "C" { // add the slashes that delimit the slashes. if (item_first == input_start) { + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + destination->string[destination->used++] = f_fss_delimit_slash; } else { + status = private_fl_fss_destination_increase_by(item_total, destination); + if (F_status_is_error(status)) break; + for (i = 0; i < item_total; i++) { destination->string[destination->used++] = f_fss_delimit_slash; } // for } } + width = f_macro_utf_byte_width(object.string[range->start]); + + status = private_fl_fss_destination_increase_by(item_total + width + 1, destination); + if (F_status_is_error(status)) break; + for (i = 0; i < item_total; i++) { destination->string[destination->used++] = f_fss_delimit_slash; } // for destination->string[destination->used++] = quote; - width = f_macro_utf_byte_width(object.string[range->start]); + for (i = 0; i < width; i++) { + destination->string[destination->used++] = object.string[range->start + i]; + } // for + } + else if (object_as && object.string[range->start] == f_fss_comment) { - status = private_fl_fss_destination_increase_by(width, destination); + // only the first slash needs to be escaped for a comment, and then only if not quoted. + if (item_first == input_start) { + commented = F_true; + } + + status = private_fl_fss_destination_increase_by(item_total + 1, destination); if (F_status_is_error(status)) break; - for (i = 0; i < width; i++) { - destination->string[destination->used++] = object.string[range->start + i]; + for (i = 0; i < item_total; i++) { + destination->string[destination->used++] = f_fss_delimit_slash; } // for + + destination->string[destination->used++] = object.string[range->start]; + range->start++; + continue; } else { @@ -636,13 +678,16 @@ extern "C" { quoted = F_true; } + width = f_macro_utf_byte_width(object.string[range->start]); + + status = private_fl_fss_destination_increase_by(item_total + width, destination); + if (F_status_is_error(status)) break; + // there is nothing to delimit, so all slashes should be printed as is. for (i = 0; i < item_total; i++) { destination->string[destination->used++] = f_fss_delimit_slash; } // for - width = f_macro_utf_byte_width(object.string[range->start]); - status = private_fl_fss_destination_increase_by(width, destination); if (F_status_is_error(status)) break; @@ -656,17 +701,26 @@ extern "C" { // the very first quote, must be escaped, when quoting is disabled. if (item_first == input_start) { + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + destination->string[used_start + 1] = f_fss_delimit_slash; } fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); if (range->start > range->stop || range->start >= object.used) { + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + destination->string[destination->used++] = quote; break; } if (object.string[range->start] == quote) { + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + destination->string[destination->used++] = quote; // the next quote must also be checked, so do not increment. @@ -678,23 +732,23 @@ extern "C" { if (F_status_is_error(status)) break; if (status == F_true) { - status = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status)) break; - if (item_first != input_start) { + status = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status)) break; + destination->string[destination->used++] = f_fss_delimit_slash; } quoted = F_true; } - destination->string[destination->used++] = quote; - width = f_macro_utf_byte_width(object.string[range->start]); - status = private_fl_fss_destination_increase_by(width, destination); + status = private_fl_fss_destination_increase_by(1 + width, destination); if (F_status_is_error(status)) break; + destination->string[destination->used++] = quote; + for (i = 0; i < width; i++) { destination->string[destination->used++] = object.string[range->start + i]; } // for @@ -704,7 +758,6 @@ extern "C" { break; } else if (object.string[range->start] != f_fss_delimit_placeholder) { - if (!quoted) { status = f_fss_is_space(object, *range); if (F_status_is_error(status)) break; @@ -734,6 +787,13 @@ extern "C" { } if (quoted) { + status = private_fl_fss_destination_increase(destination); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + destination->string[used_start] = quote; destination->string[destination->used++] = quote; @@ -762,6 +822,9 @@ extern "C" { } } } + else if (commented) { + destination->string[used_start] = f_fss_delimit_slash; + } if (range->start > range->stop) { return F_none_stop; diff --git a/level_1/fl_fss/c/private-fss.h b/level_1/fl_fss/c/private-fss.h index 94a47c8..b42c3ca 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -20,6 +20,12 @@ extern "C" { * * Intended to be shared to each of the different implementation variations. * + * @param object_as + * If TRUE, then this operate as an Object. + * IF FALSE, then this operates as a Content. + * + * As Object, this checks if the first graph character is a comment character '#', or an escaped comment character '#'. + * As Content, this does nothing special in regards to a leading '#'. * @param buffer * The buffer to read from. * This will be updated with delimit placeholders as it is being processed. @@ -63,7 +69,7 @@ extern "C" { * @see fl_fss_extended_object_read() */ #if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) - extern f_return_status private_fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) f_gcc_attribute_visibility_internal; + extern f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) f_gcc_attribute_visibility_internal; #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) /** @@ -73,6 +79,12 @@ extern "C" { * * Note: this does not attempt to "complete" the object. * + * @param object_as + * If TRUE, then this operate as an Object. + * IF FALSE, then this operates as a Content. + * + * As Object, this checks if the first graph character is a comment character '#', or an escaped comment character '#'. + * As Content, this does nothing special in regards to a leading '#'. * @param object * The string to write as (does not stop at NULLS, they are ignored and not written). * @param quoted @@ -103,7 +115,7 @@ extern "C" { * @see fl_fss_extended_content_write() */ #if !defined(fl_fss_basic_object_write) || !defined(fl_fss_extended_object_write) || !defined(_di_fl_fss_extended_content_write_) - extern f_return_status private_fl_fss_basic_object_write(const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; + extern f_return_status private_fl_fss_basic_write(const bool object_as, const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; #endif // !defined(fl_fss_basic_object_write) || !defined(fl_fss_extended_object_write) || !defined(_di_fl_fss_extended_content_write_) /** 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 27a819a..4c1310c 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 @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_basic_list_read_short_line, fss_basic_list_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print only the content at the given line."); fll_program_print_help_option(file, context, fss_basic_list_read_short_name, fss_basic_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); fll_program_print_help_option(file, context, fss_basic_list_read_short_object, fss_basic_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(file, context, fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); fll_program_print_help_option(file, context, fss_basic_list_read_short_select, fss_basic_list_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); fll_program_print_help_option(file, context, fss_basic_list_read_short_total, fss_basic_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); fll_program_print_help_option(file, context, fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); @@ -209,71 +210,64 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) { - if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) { - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify both the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' and the '"); @@ -282,64 +276,68 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } } } if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); + } + } + + if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_pipe); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); } } fss_basic_list_read_depths_t depths = fss_basic_list_read_depths_t_initialize; - f_string_length_t counter = 0; f_string_length_t original_size = data->quantity.total; - status = fss_basic_list_read_main_preprocess_depth(arguments, *data, &depths); + if (F_status_is_error_not(status)) { + status = fss_basic_list_read_main_preprocess_depth(arguments, *data, &depths); - if (F_status_is_error(status)) { - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + if (F_status_is_error(status)) { + fll_error_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_preprocess_depth", F_true); + } } // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. - if (depths.array[0].depth > 0) { + if (F_status_is_error_not(status) && depths.array[0].depth > 0) { macro_fss_basic_list_read_depths_t_delete_simple(depths); if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); - - fss_basic_list_read_delete_data(data); - return F_none; } fss_basic_list_read_delete_data(data); return F_none; } - if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]); - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->process_pipe) { + if (F_status_is_error_not(status) && data->process_pipe) { f_file_t file = f_file_t_initialize; file.id = f_type_descriptor_input; @@ -347,19 +345,14 @@ extern "C" { status = f_file_read(file, &data->buffer); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file); - - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } + else { + status = fss_basic_list_read_main_process_file(arguments, data, "-", depths); - status = fss_basic_list_read_main_process_file(arguments, data, "-", depths); - - if (F_status_is_error(status)) { - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); + } } // Clear buffers before continuing. @@ -368,32 +361,27 @@ extern "C" { f_macro_string_dynamic_t_delete_simple(data->buffer); } - if (data->remaining.used > 0) { - for (; counter < data->remaining.used; counter++) { + if (F_status_is_error_not(status) && data->remaining.used > 0) { + for (f_array_length_t i = 0; i < data->remaining.used; i++) { f_file_t file = f_file_t_initialize; - status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file); + status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file); data->quantity.total = original_size; if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file); - - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file); + break; } if (!data->quantity.total) { status = f_file_size_by_id(file.id, &data->quantity.total); + if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); f_file_stream_close(F_true, &file); - - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + break; } // Skip past empty files. @@ -412,19 +400,15 @@ extern "C" { f_file_stream_close(F_true, &file); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); - - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } - status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths); + status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); if (F_status_is_error(status)) { - macro_fss_basic_list_read_depths_t_delete_simple(depths); - fss_basic_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } // Clear buffers before repeating the loop. @@ -432,6 +416,12 @@ extern "C" { f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); } // for + + if (F_status_is_error(status)) { + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + } } macro_fss_basic_list_read_depths_t_delete_simple(depths); 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 192db76..c284d4d 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 @@ -62,6 +62,9 @@ extern "C" { #endif // _di_fss_basic_list_read_name_ #ifndef _di_fss_basic_list_read_defines_ + #define fss_basic_list_read_pipe_content_start '\0' + #define fss_basic_list_read_pipe_content_end '\f' + #define fss_basic_list_read_short_at "a" #define fss_basic_list_read_short_content "c" #define fss_basic_list_read_short_depth "d" @@ -69,6 +72,7 @@ extern "C" { #define fss_basic_list_read_short_line "l" #define fss_basic_list_read_short_name "n" #define fss_basic_list_read_short_object "o" + #define fss_basic_list_read_short_pipe "p" #define fss_basic_list_read_short_select "s" #define fss_basic_list_read_short_total "t" #define fss_basic_list_read_short_trim "T" @@ -80,6 +84,7 @@ extern "C" { #define fss_basic_list_read_long_line "line" #define fss_basic_list_read_long_name "name" #define fss_basic_list_read_long_object "object" + #define fss_basic_list_read_long_pipe "pipe" #define fss_basic_list_read_long_select "select" #define fss_basic_list_read_long_total "total" #define fss_basic_list_read_long_trim "trim" @@ -102,6 +107,7 @@ extern "C" { fss_basic_list_read_parameter_line, fss_basic_list_read_parameter_name, fss_basic_list_read_parameter_object, + fss_basic_list_read_parameter_pipe, fss_basic_list_read_parameter_select, fss_basic_list_read_parameter_total, fss_basic_list_read_parameter_trim, @@ -125,12 +131,13 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_list_read_short_line, fss_basic_list_read_long_line, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_name, fss_basic_list_read_long_name, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_object, fss_basic_list_read_long_object, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_select, fss_basic_list_read_long_select, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_total, fss_basic_list_read_long_total, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_list_read_total_parameters 19 + #define fss_basic_list_read_total_parameters 20 #endif // _di_fss_basic_list_read_defines_ #ifndef _di_fss_basic_list_read_data_t_ diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c index 2d0d1a2..9f1e812 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c @@ -182,39 +182,10 @@ extern "C" { status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents); if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_parameter) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } - else if (status == F_memory_allocation || status == F_memory_reallocation) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]); - } - else if (status == F_incomplete_utf_stop) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else if (status == F_incomplete_utf_eos) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else { - fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status); - fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling "); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } + // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. + fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, filename, "process", fll_error_file_type_file); - return F_status_set_error(status); + return status; } else if (status == F_data_not_stop || status == F_data_not_eos) { if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { @@ -353,16 +324,14 @@ extern "C" { print_object(f_type_output, data->buffer, data->objects.array[i]); if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) { + fss_basic_list_read_print_object_end(*data); + if (data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_eol); f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); } - else { - fprintf(f_type_output, "%c", f_fss_eol); - } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_basic_list_read_print_set_end(*data); break; } @@ -379,16 +348,14 @@ extern "C" { print_object(f_type_output, data->buffer, data->objects.array[i]); if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) { + fss_basic_list_read_print_object_end(*data); + if (data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_eol); f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); } - else { - fprintf(f_type_output, "%c", f_fss_eol); - } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_basic_list_read_print_set_end(*data); } // for return F_none; @@ -433,7 +400,7 @@ extern "C" { if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { if (!data->contents.array[i].used) { if (include_empty && !line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_list_read_print_set_end(*data); } } else { @@ -485,9 +452,13 @@ extern "C" { if (data->contents.array[i].used > 0) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + + if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data->output.stream, "%c", fss_basic_list_read_pipe_content_end); + } } else if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_list_read_print_set_end(*data); } break; @@ -534,7 +505,7 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { if (line_current == line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_list_read_print_set_end(*data); break; } @@ -586,19 +557,59 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_list_read_print_set_end(*data); } continue; } f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + + if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data->output.stream, "%c", fss_basic_list_read_pipe_content_end); + } } // for return F_none; } #endif // _di_fss_basic_list_read_main_process_file_ +#ifndef _di_fss_basic_list_read_print_object_end_ + void fss_basic_list_read_print_object_end(const fss_basic_list_read_data_t data) { + + if (data.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_basic_list_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_basic_list_read_print_object_end_ + +#ifndef _di_fss_basic_list_read_print_content_end_ + void fss_basic_list_read_print_content_end(const fss_basic_list_read_data_t data) { + + if (data.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_basic_list_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_basic_list_read_print_content_end_ + +#ifndef _di_fss_basic_list_read_print_set_end_ + void fss_basic_list_read_print_set_end(const fss_basic_list_read_data_t data) { + + if (data.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_basic_list_read_pipe_content_end); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_basic_list_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h index 5316302..7981f93 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h @@ -199,6 +199,36 @@ extern "C" { extern f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t file_name, const fss_basic_list_read_depths_t depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_basic_list_read_main_process_file_ +/** + * Print the end of an object (which is essentially the start of a content). + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_basic_list_read_print_object_end_ + extern void fss_basic_list_read_print_object_end(const fss_basic_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_basic_list_read_print_object_end_ + +/** + * Print the end of an content. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_basic_list_read_print_content_end_ + extern void fss_basic_list_read_print_content_end(const fss_basic_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_basic_list_read_print_content_end_ + +/** + * Print the end of an object/content set. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_basic_list_read_print_set_end_ + extern void fss_basic_list_read_print_set_end(const fss_basic_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_basic_list_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif 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 c660853..a2c0511 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_basic_read_short_line, fss_basic_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print only the content at the given line."); fll_program_print_help_option(file, context, fss_basic_read_short_name, fss_basic_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); fll_program_print_help_option(file, context, fss_basic_read_short_object, fss_basic_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(file, context, fss_basic_read_short_pipe, fss_basic_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); fll_program_print_help_option(file, context, fss_basic_read_short_select, fss_basic_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); fll_program_print_help_option(file, context, fss_basic_read_short_total, fss_basic_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); fll_program_print_help_option(file, context, fss_basic_read_short_trim, fss_basic_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); @@ -209,71 +210,64 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_read_parameter_depth].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_depth].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_line].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_read_parameter_name].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_name].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_found) { - if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter."); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_read_parameter_select].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_select].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify both the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' and the '"); @@ -282,63 +276,69 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } } } if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { - if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); + } + } + + if (data->parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_pipe); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); } } fss_basic_read_depths_t depths = fss_basic_read_depths_t_initialize; - f_string_length_t counter = 0; f_string_length_t original_size = data->quantity.total; - status = fss_basic_read_main_preprocess_depth(arguments, *data, &depths); - if (F_status_is_error(status)) { - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + if (F_status_is_error_not(status)) { + status = fss_basic_read_main_preprocess_depth(arguments, *data, &depths); + + if (F_status_is_error(status)) { + fll_error_print(data->error, F_status_set_fine(status), "fss_basic_read_main_preprocess_depth", F_true); + } } // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. - if (depths.array[0].depth > 0) { + if (F_status_is_error_not(status) && depths.array[0].depth > 0) { macro_fss_basic_read_depths_t_delete_simple(depths); if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); - - fss_basic_read_delete_data(data); - return F_none; } fss_basic_read_delete_data(data); return F_none; } - if (data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]); macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->process_pipe) { + if (F_status_is_error_not(status) && data->process_pipe) { f_file_t file = f_file_t_initialize; file.id = f_type_descriptor_input; @@ -346,19 +346,14 @@ extern "C" { status = f_file_read(file, &data->buffer); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file); - - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } + else { + status = fss_basic_read_main_process_file(arguments, data, "-", depths); - status = fss_basic_read_main_process_file(arguments, data, "-", depths); - - if (F_status_is_error(status)) { - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); + } } // Clear buffers before continuing. @@ -367,33 +362,27 @@ extern "C" { f_macro_string_dynamic_t_delete_simple(data->buffer); } - if (data->remaining.used > 0) { - for (; counter < data->remaining.used; counter++) { + if (F_status_is_error_not(status) && data->remaining.used > 0) { + for (f_array_length_t i = 0; i < data->remaining.used; i++) { f_file_t file = f_file_t_initialize; - status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file); + status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file); data->quantity.total = original_size; if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file); - - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file); + break; } if (!data->quantity.total) { status = f_file_size_by_id(file.id, &data->quantity.total); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); f_file_stream_close(F_true, &file); - - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + break; } // Skip past empty files. @@ -412,19 +401,15 @@ extern "C" { f_file_stream_close(F_true, &file); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); - - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } - status = fss_basic_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths); + status = fss_basic_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); if (F_status_is_error(status)) { - macro_fss_basic_read_depths_t_delete_simple(depths); - fss_basic_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } // Clear buffers before repeating the loop. @@ -432,6 +417,12 @@ extern "C" { f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); } // for + + if (F_status_is_error(status)) { + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + } } macro_fss_basic_read_depths_t_delete_simple(depths); 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 1709fb5..ea35952 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -62,6 +62,9 @@ extern "C" { #endif // _di_fss_basic_read_name_ #ifndef _di_fss_basic_read_defines_ + #define fss_basic_read_pipe_content_start '\0' + #define fss_basic_read_pipe_content_end '\f' + #define fss_basic_read_short_at "a" #define fss_basic_read_short_content "c" #define fss_basic_read_short_depth "d" @@ -69,6 +72,7 @@ extern "C" { #define fss_basic_read_short_line "l" #define fss_basic_read_short_name "n" #define fss_basic_read_short_object "o" + #define fss_basic_read_short_pipe "p" #define fss_basic_read_short_select "s" #define fss_basic_read_short_total "t" #define fss_basic_read_short_trim "T" @@ -80,6 +84,7 @@ extern "C" { #define fss_basic_read_long_line "line" #define fss_basic_read_long_name "name" #define fss_basic_read_long_object "object" + #define fss_basic_read_long_pipe "pipe" #define fss_basic_read_long_select "select" #define fss_basic_read_long_total "total" #define fss_basic_read_long_trim "trim" @@ -102,6 +107,7 @@ extern "C" { fss_basic_read_parameter_line, fss_basic_read_parameter_name, fss_basic_read_parameter_object, + fss_basic_read_parameter_pipe, fss_basic_read_parameter_select, fss_basic_read_parameter_total, fss_basic_read_parameter_trim, @@ -125,12 +131,13 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_read_short_line, fss_basic_read_long_line, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_name, fss_basic_read_long_name, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_object, fss_basic_read_long_object, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_read_short_pipe, fss_basic_read_long_pipe, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_select, fss_basic_read_long_select, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_total, fss_basic_read_long_total, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_trim, fss_basic_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_read_total_parameters 19 + #define fss_basic_read_total_parameters 20 #endif // _di_fss_basic_read_defines_ #ifndef _di_fss_basic_read_data_t_ diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-fss_basic_read.c index cb6b9cf..477fad4 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.c +++ b/level_3/fss_basic_read/c/private-fss_basic_read.c @@ -182,39 +182,10 @@ extern "C" { status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0); if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_parameter) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } - else if (status == F_memory_allocation || status == F_memory_reallocation) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]); - } - else if (status == F_incomplete_utf_stop) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else if (status == F_incomplete_utf_eos) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else { - fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status); - fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling "); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } + // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. + fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_read", F_true, filename, "process", fll_error_file_type_file); - return F_status_set_error(status); + return status; } else if (status == F_data_not_stop || status == F_data_not_eos) { if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { @@ -353,12 +324,12 @@ extern "C" { if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_space); + fss_basic_read_print_object_end(*data); f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_basic_read_print_set_end(*data); break; } @@ -376,12 +347,12 @@ extern "C" { if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_space); + fss_basic_read_print_object_end(*data); f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_basic_read_print_set_end(*data); } // for return F_none; @@ -419,19 +390,19 @@ extern "C" { else if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { if (data->contents.array[i].used > 0) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); } else if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); } } else { if (data->contents.array[i].used > 0) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); } else if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); } } @@ -471,7 +442,7 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { if (line_current == line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); break; } @@ -483,7 +454,7 @@ extern "C" { if (line_current == line) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); break; } @@ -499,20 +470,44 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); } continue; } f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_basic_read_print_set_end(*data); } // for return F_none; } #endif // _di_fss_basic_read_main_process_file_ +#ifndef _di_fss_basic_read_print_object_end_ + void fss_basic_read_print_object_end(const fss_basic_read_data_t data) { + + if (data.parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_basic_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_space); + } + } +#endif // _di_fss_basic_read_print_object_end_ + +#ifndef _di_fss_basic_read_print_set_end_ + void fss_basic_read_print_set_end(const fss_basic_read_data_t data) { + + if (data.parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_basic_read_pipe_content_end); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_basic_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.h b/level_3/fss_basic_read/c/private-fss_basic_read.h index dd6d371..7cd0138 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.h +++ b/level_3/fss_basic_read/c/private-fss_basic_read.h @@ -195,6 +195,26 @@ extern "C" { extern f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t file_name, const fss_basic_read_depths_t depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_basic_read_main_process_file_ +/** + * Print the end of an object (which is essentially the start of a content). + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_basic_read_print_object_end_ + extern void fss_basic_read_print_object_end(const fss_basic_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_basic_read_print_object_end_ + +/** + * Print the end of an object/content set. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_basic_read_print_set_end_ + extern void fss_basic_read_print_set_end(const fss_basic_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_basic_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.c b/level_3/fss_extended_list_read/c/fss_extended_list_read.c index 500a89b..85b4268 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.c @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_extended_list_read_short_line, fss_extended_list_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print only the content at the given line."); fll_program_print_help_option(file, context, fss_extended_list_read_short_name, fss_extended_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); fll_program_print_help_option(file, context, fss_extended_list_read_short_object, fss_extended_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(file, context, fss_extended_list_read_short_pipe, fss_extended_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); fll_program_print_help_option(file, context, fss_extended_list_read_short_select, fss_extended_list_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); fll_program_print_help_option(file, context, fss_extended_list_read_short_total, fss_extended_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); fll_program_print_help_option(file, context, fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); @@ -209,71 +210,64 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_found) { - if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) { - if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify both the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' and the '"); @@ -282,49 +276,56 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } } } if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { - if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); + } + } + + if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_pipe); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); } } fss_extended_list_read_depths_t depths = fss_extended_list_read_depths_t_initialize; - f_string_length_t counter = 0; f_string_length_t original_size = data->quantity.total; - status = fss_extended_list_read_main_preprocess_depth(arguments, *data, &depths); + if (F_status_is_error_not(status)) { + status = fss_extended_list_read_main_preprocess_depth(arguments, *data, &depths); - if (F_status_is_error(status)) { - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + if (F_status_is_error(status)) { + fll_error_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_preprocess_depth", F_true); + } } - if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]); - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->process_pipe) { + if (F_status_is_error_not(status) && data->process_pipe) { f_file_t file = f_file_t_initialize; file.id = f_type_descriptor_input; @@ -332,19 +333,14 @@ extern "C" { status = f_file_read(file, &data->buffer); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file); - - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } + else { + status = fss_extended_list_read_main_process_file(arguments, data, "-", depths); - status = fss_extended_list_read_main_process_file(arguments, data, "-", depths); - - if (F_status_is_error(status)) { - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); + } } // Clear buffers before continuing. @@ -352,32 +348,26 @@ extern "C" { f_macro_string_dynamic_t_delete_simple(data->buffer); } - if (data->remaining.used > 0) { - for (; counter < data->remaining.used; counter++) { + if (F_status_is_error_not(status) && data->remaining.used > 0) { + for (f_array_length_t i = 0; i < data->remaining.used; i++) { f_file_t file = f_file_t_initialize; - status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file); + status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file); data->quantity.total = original_size; if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file); - - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file); + break; } if (!data->quantity.total) { status = f_file_size_by_id(file.id, &data->quantity.total); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); f_file_stream_close(F_true, &file); - - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + break; } // Skip past empty files. @@ -396,25 +386,26 @@ extern "C" { f_file_stream_close(F_true, &file); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); - - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } - status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths); + status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); if (F_status_is_error(status)) { - macro_fss_extended_list_read_depths_t_delete_simple(depths); - fss_extended_list_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } // Clear buffers before repeating the loop. f_macro_fss_nest_t_delete_simple(data->nest); f_macro_string_dynamic_t_delete_simple(data->buffer); } // for + + if (F_status_is_error(status)) { + f_macro_fss_nest_t_delete_simple(data->nest); + f_macro_string_dynamic_t_delete_simple(data->buffer); + } } macro_fss_extended_list_read_depths_t_delete_simple(depths); diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.h b/level_3/fss_extended_list_read/c/fss_extended_list_read.h index 516b305..57942c3 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.h @@ -62,6 +62,9 @@ extern "C" { #endif // _di_fss_extended_list_read_name_ #ifndef _di_fss_extended_list_read_defines_ + #define fss_extended_list_read_pipe_content_start '\0' + #define fss_extended_list_read_pipe_content_end '\f' + #define fss_extended_list_read_short_at "a" #define fss_extended_list_read_short_content "c" #define fss_extended_list_read_short_depth "d" @@ -69,6 +72,7 @@ extern "C" { #define fss_extended_list_read_short_line "l" #define fss_extended_list_read_short_name "n" #define fss_extended_list_read_short_object "o" + #define fss_extended_list_read_short_pipe "p" #define fss_extended_list_read_short_select "s" #define fss_extended_list_read_short_total "t" #define fss_extended_list_read_short_trim "T" @@ -80,6 +84,7 @@ extern "C" { #define fss_extended_list_read_long_line "line" #define fss_extended_list_read_long_name "name" #define fss_extended_list_read_long_object "object" + #define fss_extended_list_read_long_pipe "pipe" #define fss_extended_list_read_long_select "select" #define fss_extended_list_read_long_total "total" #define fss_extended_list_read_long_trim "trim" @@ -102,6 +107,7 @@ extern "C" { fss_extended_list_read_parameter_line, fss_extended_list_read_parameter_name, fss_extended_list_read_parameter_object, + fss_extended_list_read_parameter_pipe, fss_extended_list_read_parameter_select, fss_extended_list_read_parameter_total, fss_extended_list_read_parameter_trim, @@ -125,12 +131,13 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_list_read_short_line, fss_extended_list_read_long_line, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_name, fss_extended_list_read_long_name, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_object, fss_extended_list_read_long_object, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_list_read_short_pipe, fss_extended_list_read_long_pipe, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_select, fss_extended_list_read_long_select, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_total, fss_extended_list_read_long_total, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_list_read_total_parameters 19 + #define fss_extended_list_read_total_parameters 20 #endif // _di_fss_extended_list_read_defines_ #ifndef _di_fss_extended_list_read_data_t_ diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index 9f29a95..bd82353 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -182,39 +182,10 @@ extern "C" { status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest); if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_parameter) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_list_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } - else if (status == F_memory_allocation || status == F_memory_reallocation) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]); - } - else if (status == F_incomplete_utf_stop) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else if (status == F_incomplete_utf_eos) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else { - fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status); - fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling "); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_list_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } + // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. + fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_list_read", F_true, filename, "process", fll_error_file_type_file); - return F_status_set_error(status); + return status; } else if (status == F_data_not_stop || status == F_data_not_eos) { if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { @@ -369,16 +340,14 @@ extern "C" { print_object(f_type_output, data->buffer, items->array[depth_setting.value_at].object); if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) { + fss_extended_list_read_print_object_end(*data); + if (items->array[depth_setting.value_at].content.used) { - fprintf(f_type_output, "%c", f_fss_eol); f_print_dynamic_partial(f_type_output, data->buffer, items->array[depth_setting.value_at].content.array[0]); } - else { - fprintf(f_type_output, "%c", f_fss_eol); - } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_extended_list_read_print_set_end(*data); } return F_none; @@ -390,16 +359,14 @@ extern "C" { print_object(f_type_output, data->buffer, items->array[i].object); if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) { + fss_extended_list_read_print_object_end(*data); + if (items->array[i].content.used) { - fprintf(f_type_output, "%c", f_fss_eol); f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]); } - else { - fprintf(f_type_output, "%c", f_fss_eol); - } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_extended_list_read_print_set_end(*data); } } // for @@ -445,7 +412,7 @@ extern "C" { if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { if (!items->array[i].content.used) { if (include_empty && !line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_list_read_print_set_end(*data); } } else { @@ -498,9 +465,13 @@ extern "C" { if (items->array[i].content.used > 0) { f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]); + + if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data->output.stream, "%c", fss_extended_list_read_pipe_content_end); + } } else if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_list_read_print_set_end(*data); } break; @@ -549,7 +520,7 @@ extern "C" { if (!items->array[i].content.used) { if (include_empty) { if (line_current == line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_list_read_print_set_end(*data); break; } @@ -600,19 +571,59 @@ extern "C" { if (!items->array[i].content.used) { if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_list_read_print_set_end(*data); } continue; } f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]); + + if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data->output.stream, "%c", fss_extended_list_read_pipe_content_end); + } } // for return F_none; } #endif // _di_fss_extended_list_read_main_process_for_depth_ +#ifndef _di_fss_extended_list_read_print_object_end_ + void fss_extended_list_read_print_object_end(const fss_extended_list_read_data_t data) { + + if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_extended_list_read_print_object_end_ + +#ifndef _di_fss_extended_list_read_print_content_end_ + void fss_extended_list_read_print_content_end(const fss_extended_list_read_data_t data) { + + if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_extended_list_read_print_content_end_ + +#ifndef _di_fss_extended_list_read_print_set_end_ + void fss_extended_list_read_print_set_end(const fss_extended_list_read_data_t data) { + + if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_end); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_extended_list_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h index f592c68..fb1d31f 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h @@ -219,6 +219,36 @@ extern "C" { extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_process_for_depth_ +/** + * Print the end of an object (which is essentially the start of a content). + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_list_read_print_object_end_ + extern void fss_extended_list_read_print_object_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_print_object_end_ + +/** + * Print the end of an content. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_list_read_print_content_end_ + extern void fss_extended_list_read_print_content_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_print_content_end_ + +/** + * Print the end of an object/content set. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_list_read_print_set_end_ + extern void fss_extended_list_read_print_set_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif 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 429c34b..db54be0 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.c +++ b/level_3/fss_extended_read/c/fss_extended_read.c @@ -23,12 +23,13 @@ extern "C" { printf("%c", f_string_eol[0]); fll_program_print_help_option(file, context, fss_extended_read_short_at, fss_extended_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); - fll_program_print_help_option(file, context, fss_extended_read_short_content, fss_extended_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); + fll_program_print_help_option(file, context, fss_extended_read_short_content, fss_extended_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); fll_program_print_help_option(file, context, fss_extended_read_short_depth, fss_extended_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); fll_program_print_help_option(file, context, fss_extended_read_short_empty, fss_extended_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); fll_program_print_help_option(file, context, fss_extended_read_short_line, fss_extended_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print only the content at the given line."); fll_program_print_help_option(file, context, fss_extended_read_short_name, fss_extended_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); fll_program_print_help_option(file, context, fss_extended_read_short_object, fss_extended_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(file, context, fss_extended_read_short_pipe, fss_extended_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); fll_program_print_help_option(file, context, fss_extended_read_short_select, fss_extended_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); fll_program_print_help_option(file, context, fss_extended_read_short_total, fss_extended_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); fll_program_print_help_option(file, context, fss_extended_read_short_trim, fss_extended_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); @@ -209,71 +210,64 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_read_parameter_depth].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_depth].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_read_parameter_line].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_line].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_read_parameter_name].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_name].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_extended_read_parameter_object].result == f_console_result_found) { - if (data->parameters[fss_extended_read_parameter_line].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_line].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) { - if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify both the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' and the '"); @@ -282,31 +276,46 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } } } if (data->parameters[fss_extended_read_parameter_line].result == f_console_result_additional) { - if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); + } + } + + if (data->parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_pipe); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total); + fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); } } fss_extended_read_depths_t depths = fss_extended_read_depths_t_initialize; - f_string_length_t counter = 0; f_string_length_t original_size = data->quantity.total; - status = fss_extended_read_main_preprocess_depth(arguments, *data, &depths); + if (F_status_is_error_not(status)) { + status = fss_extended_read_main_preprocess_depth(arguments, *data, &depths); + + if (F_status_is_error(status)) { + fll_error_print(data->error, F_status_set_fine(status), "fss_extended_read_main_preprocess_depth", F_true); + } + } if (F_status_is_error(status)) { macro_fss_extended_read_depths_t_delete_simple(depths); @@ -315,31 +324,26 @@ extern "C" { } // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. - if (depths.array[0].depth > 0) { + if (F_status_is_error_not(status) && depths.array[0].depth > 0) { macro_fss_extended_read_depths_t_delete_simple(depths); if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); - - fss_extended_read_delete_data(data); - return F_none; } fss_extended_read_delete_data(data); return F_none; } - if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]); - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->process_pipe) { + if (F_status_is_error_not(status) && data->process_pipe) { f_file_t file = f_file_t_initialize; file.id = f_type_descriptor_input; @@ -347,19 +351,14 @@ extern "C" { status = f_file_read(file, &data->buffer); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file); - - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } + else { + status = fss_extended_read_main_process_file(arguments, data, "-", depths); - status = fss_extended_read_main_process_file(arguments, data, "-", depths); - - if (F_status_is_error(status)) { - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); + } } // Clear buffers before continuing. @@ -368,33 +367,27 @@ extern "C" { f_macro_string_dynamic_t_delete_simple(data->buffer); } - if (data->remaining.used > 0) { - for (; counter < data->remaining.used; counter++) { + if (F_status_is_error_not(status) && data->remaining.used > 0) { + for (f_array_length_t i = 0; i < data->remaining.used; i++) { f_file_t file = f_file_t_initialize; - status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file); + status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file); data->quantity.total = original_size; if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file); - - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file); + break; } if (!data->quantity.total) { status = f_file_size_by_id(file.id, &data->quantity.total); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); f_file_stream_close(F_true, &file); - - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; + break; } // Skip past empty files. @@ -413,19 +406,15 @@ extern "C" { f_file_stream_close(F_true, &file); if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file); - - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } - status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths); + status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); if (F_status_is_error(status)) { - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; + fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); + break; } // Clear buffers before repeating the loop. @@ -433,6 +422,12 @@ extern "C" { f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); } // for + + if (F_status_is_error(status)) { + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + } } macro_fss_extended_read_depths_t_delete_simple(depths); 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 e3e7b83..71d4ae0 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.h +++ b/level_3/fss_extended_read/c/fss_extended_read.h @@ -62,6 +62,9 @@ extern "C" { #endif // _di_fss_extended_read_name_ #ifndef _di_fss_extended_read_defines_ + #define fss_extended_read_pipe_content_start '\0' + #define fss_extended_read_pipe_content_end '\f' + #define fss_extended_read_short_at "a" #define fss_extended_read_short_content "c" #define fss_extended_read_short_depth "d" @@ -69,6 +72,7 @@ extern "C" { #define fss_extended_read_short_line "l" #define fss_extended_read_short_name "n" #define fss_extended_read_short_object "o" + #define fss_extended_read_short_pipe "p" #define fss_extended_read_short_select "s" #define fss_extended_read_short_total "t" #define fss_extended_read_short_trim "T" @@ -80,6 +84,7 @@ extern "C" { #define fss_extended_read_long_line "line" #define fss_extended_read_long_name "name" #define fss_extended_read_long_object "object" + #define fss_extended_read_long_pipe "pipe" #define fss_extended_read_long_select "select" #define fss_extended_read_long_total "total" #define fss_extended_read_long_trim "trim" @@ -102,6 +107,7 @@ extern "C" { fss_extended_read_parameter_line, fss_extended_read_parameter_name, fss_extended_read_parameter_object, + fss_extended_read_parameter_pipe, fss_extended_read_parameter_select, fss_extended_read_parameter_total, fss_extended_read_parameter_trim, @@ -125,12 +131,13 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_read_short_line, fss_extended_read_long_line, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_name, fss_extended_read_long_name, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_object, fss_extended_read_long_object, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_read_short_pipe, fss_extended_read_long_pipe, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_select, fss_extended_read_long_select, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_total, fss_extended_read_long_total, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_trim, fss_extended_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_read_total_parameters 19 + #define fss_extended_read_total_parameters 20 #endif // _di_fss_extended_read_defines_ #ifndef _di_fss_extended_read_data_t_ diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-fss_extended_read.c index de8cda2..559c742 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.c +++ b/level_3/fss_extended_read/c/private-fss_extended_read.c @@ -182,39 +182,10 @@ extern "C" { status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0); if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_parameter) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } - else if (status == F_memory_allocation || status == F_memory_reallocation) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]); - } - else if (status == F_incomplete_utf_stop) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else if (status == F_incomplete_utf_eos) { - fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start); - fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]); - } - else { - fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error); - fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status); - fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling "); - fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_read()"); - fl_color_print(data->error.to.stream, data->context.set.error, " for the file '"); - fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename); - fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]); - } + // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. + fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, filename, "process", fll_error_file_type_file); - return F_status_set_error(status); + return status; } else if (status == F_data_not_stop || status == F_data_not_eos) { if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { @@ -349,20 +320,20 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_space); + fss_extended_read_print_object_end(*data); for (j = 0; j < data->contents.array[i].used; j++) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); if (j + 1 < data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_space); + fss_extended_read_print_content_end(*data); } } // for } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_extended_read_print_set_end(*data); break; } @@ -380,20 +351,20 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_space); + fss_extended_read_print_object_end(*data); for (j = 0; j < data->contents.array[i].used; j++) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); if (j + 1 < data->contents.array[i].used) { - fprintf(f_type_output, "%c", f_fss_space); + fss_extended_read_print_content_end(*data); } } // for } } - fprintf(f_type_output, "%c", f_fss_eol); + fss_extended_read_print_set_end(*data); } // for return F_none; @@ -433,7 +404,7 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else { @@ -441,21 +412,21 @@ extern "C" { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); if (j + 1 < data->contents.array[i].used) { - printf(" "); + fss_extended_read_print_content_end(*data); } } // for - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else if (include_empty) { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (!select) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } } @@ -469,7 +440,7 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else { @@ -477,21 +448,21 @@ extern "C" { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); if (j + 1 < data->contents.array[i].used) { - printf(" "); + fss_extended_read_print_content_end(*data); } } // for - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else if (include_empty) { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (!select) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } @@ -533,7 +504,7 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { if (line_current == line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); break; } @@ -547,7 +518,7 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else { @@ -555,11 +526,11 @@ extern "C" { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); if (j + 1 < data->contents.array[i].used) { - printf(" "); + fss_extended_read_print_content_end(*data); } } // for - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } break; @@ -576,7 +547,7 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty && !select) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } continue; @@ -585,7 +556,7 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } else { @@ -593,11 +564,11 @@ extern "C" { f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); if (j + 1 < data->contents.array[i].used) { - printf(" "); + fss_extended_read_print_content_end(*data); } } // for - fprintf(f_type_output, "%c", f_string_eol[0]); + fss_extended_read_print_set_end(*data); } } // for @@ -605,6 +576,42 @@ extern "C" { } #endif // _di_fss_extended_read_main_process_file_ +#ifndef _di_fss_extended_read_print_object_end_ + void fss_extended_read_print_object_end(const fss_extended_read_data_t data) { + + if (data.parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_space); + } + } +#endif // _di_fss_extended_read_print_object_end_ + +#ifndef _di_fss_extended_read_print_content_end_ + void fss_extended_read_print_content_end(const fss_extended_read_data_t data) { + + if (data.parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_read_pipe_content_start); + } + else { + fprintf(data.output.stream, "%c", f_fss_space); + } + } +#endif // _di_fss_extended_read_print_content_end_ + +#ifndef _di_fss_extended_read_print_set_end_ + void fss_extended_read_print_set_end(const fss_extended_read_data_t data) { + + if (data.parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_read_pipe_content_end); + } + else { + fprintf(data.output.stream, "%c", f_fss_eol); + } + } +#endif // _di_fss_extended_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.h b/level_3/fss_extended_read/c/private-fss_extended_read.h index 7b89827..06bb8e8 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.h +++ b/level_3/fss_extended_read/c/private-fss_extended_read.h @@ -195,6 +195,36 @@ extern "C" { extern f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t file_name, const fss_extended_read_depths_t depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_read_main_process_file_ +/** + * Print the end of an object (which is essentially the start of a content). + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_read_print_object_end_ + extern void fss_extended_read_print_object_end(const fss_extended_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_read_print_object_end_ + +/** + * Print the end of an content. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_read_print_content_end_ + extern void fss_extended_read_print_content_end(const fss_extended_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_read_print_content_end_ + +/** + * Print the end of an object/content set. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_read_print_set_end_ + extern void fss_extended_read_print_set_end(const fss_extended_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_read_print_set_end_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/specifications/fss.txt b/specifications/fss.txt index 71fa531..e624007 100644 --- a/specifications/fss.txt +++ b/specifications/fss.txt @@ -93,7 +93,7 @@ Featureless Settings Specifications: Unless otherwise specified, comments are designated by the pound symbol '#' but only if only whitespace is to the left of the pound or the pound '#' is at the start of the line. There is no support for inline comments. - Unless explicitly defined, the start comment may be delimited by '\' in the same manner as Objects and Contents are. + Unless otherwise specified, the start comment may be delimited by '\' in the same manner as Objects and Contents are. This delimit only applies to the start of a comment (the pound '#' character) as there is no terminating character for a comment (other than a newline '\n'). Unless otherwise specified, all designation characters MUST represent ASCII codes. -- 1.8.3.1