From c3c7004ba5942f697884a069a3a8e63663c5615c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 13 Oct 2020 17:55:04 -0500 Subject: [PATCH] Feature: add support for trimming FSS Object names for FSS write operations. I believe it is important for the command line tools to easily cleanup object names in case spaces aren't desired. This provides the functionality to ensure trimming of spaces before and after the object name. This further allows for preventing the cleanup behavior done in object writes, such as in FSS-0003 (Extended List) where it is cleaner to have a space between the object name and the brace '{'. If this is undesired, the function can then be configured to not do this. This further makes the FSS write functions more consistent with the FSS read functions where object name trimming is already supported. --- level_0/f_fss/c/fss-common.h | 21 ++- level_1/fl_fss/c/fss_basic.c | 19 ++- level_1/fl_fss/c/fss_basic.h | 4 +- level_1/fl_fss/c/fss_basic_list.c | 21 ++- level_1/fl_fss/c/fss_basic_list.h | 4 +- level_1/fl_fss/c/fss_extended.c | 23 ++- level_1/fl_fss/c/fss_extended.h | 4 +- level_1/fl_fss/c/fss_extended_list.c | 21 ++- level_1/fl_fss/c/fss_extended_list.h | 4 +- level_1/fl_fss/c/private-fss.c | 165 +++++++++++++++++++++ level_1/fl_fss/c/private-fss.h | 46 +++++- .../fss_basic_list_write/c/fss_basic_list_write.c | 1 + .../fss_basic_list_write/c/fss_basic_list_write.h | 6 +- .../c/private-fss_basic_list_write.c | 13 +- level_3/fss_basic_write/c/fss_basic_write.c | 1 + level_3/fss_basic_write/c/fss_basic_write.h | 6 +- .../fss_basic_write/c/private-fss_basic_write.c | 13 +- .../c/fss_extended_list_write.c | 1 + .../c/fss_extended_list_write.h | 6 +- .../c/private-fss_extended_list_write.c | 13 +- level_3/fss_extended_write/c/fss_extended_write.c | 1 + level_3/fss_extended_write/c/fss_extended_write.h | 6 +- .../c/private-fss_extended_write.c | 13 +- 23 files changed, 367 insertions(+), 45 deletions(-) diff --git a/level_0/f_fss/c/fss-common.h b/level_0/f_fss/c/fss-common.h index 89d5f0f..989224b 100644 --- a/level_0/f_fss/c/fss-common.h +++ b/level_0/f_fss/c/fss-common.h @@ -81,21 +81,28 @@ extern "C" { /** * Codes for FSS completeness. * + * The details on how these work are specific to individual specifications. + * The notes below provide the intended purpose but be sure to still read the individual function documentation. + * * Only "next" and "end" are only meaningful for a Content and will be treated as "none" for an Object. * - * none: disable completeness. - * partial: complete, but do not add terminating EOL, where applicable. - * full: complete and add terminating EOL, where applicable. - * next: complete as if this is a piece of a set (such as FSS-0001 where there are multiple space separated content). - * end: complete as if this is the final piece of a set, therefore adding an EOL. + * none: disable completeness. + * end: complete as if this is the final piece of a set (such as FSS-0001, adding terminating EOL). + * full: complete and add terminating EOL, where applicable. + * full_trim: complete and add terminating EOL but remove any leading or trailing whitespace, where applicable. + * next: complete as if this is a piece of a set (such as FSS-0001, adding a separating space). + * partial: complete, but do not add terminating EOL, where applicable. + * partial_trim: complete, but do not add terminating EOL and remove any leading or trailing whitespace, where applicable. */ #ifndef _di_f_fss_complete_ enum { f_fss_complete_none = 1, - f_fss_complete_partial, + f_fss_complete_end, f_fss_complete_full, + f_fss_complete_full_trim, f_fss_complete_next, - f_fss_complete_end, + f_fss_complete_partial, + f_fss_complete_partial_trim, }; #endif // _di_f_fss_complete_ diff --git a/level_1/fl_fss/c/fss_basic.c b/level_1/fl_fss/c/fss_basic.c index bae4c1e..b495437 100644 --- a/level_1/fl_fss/c/fss_basic.c +++ b/level_1/fl_fss/c/fss_basic.c @@ -98,6 +98,8 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ + const f_string_length_t used_start = destination->used; + 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) { @@ -110,10 +112,17 @@ extern "C" { destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; } - if (complete == f_fss_complete_partial || complete == f_fss_complete_full) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { if (status == F_none_stop || status == F_none_eos || status == F_data_not_stop || status == F_data_not_eos) { - const f_status_t status_allocation = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status_allocation)) return status_allocation; + f_status_t status2 = F_none; + + if (complete == f_fss_complete_full_trim) { + status2 = private_fl_fss_basic_write_object_trim(quote ? quote : f_fss_delimit_quote_double, used_start, destination); + if (F_status_is_error(status2)) return status2; + } + + status2 = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status2)) return status2; destination->string[destination->used++] = f_fss_basic_open; } @@ -137,7 +146,7 @@ extern "C" { if (range->start > range->stop || range->start >= content.used) { // content should be terminated, even if empty. - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { status = private_fl_fss_destination_increase(destination); if (F_status_is_error(status)) return status; @@ -171,7 +180,7 @@ extern "C" { destination->string[destination->used++] = content.string[range->start]; } // for - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { destination->string[destination->used++] = f_fss_basic_close; } diff --git a/level_1/fl_fss/c/fss_basic.h b/level_1/fl_fss/c/fss_basic.h index d474c87..702fa37 100644 --- a/level_1/fl_fss/c/fss_basic.h +++ b/level_1/fl_fss/c/fss_basic.h @@ -136,8 +136,10 @@ extern "C" { * Otherwise, this is the type of quote to wrap the object in when writing. * @param complete * If f_fss_complete_none, then only the object name is written. - * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. * If f_fss_complete_full, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_full_trim, this will write any appropriate open and close aspects of this object, but will omit whitespace before and after the object (inside the quotes). + * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_partial_tim, this will write any appropriate open and close aspects of this object, but will omit whitespace before and after the object (inside the quotes). * @param range * The start/stop location within the object string to write as an object. * @param destination diff --git a/level_1/fl_fss/c/fss_basic_list.c b/level_1/fl_fss/c/fss_basic_list.c index cf55220..b9a5e16 100644 --- a/level_1/fl_fss/c/fss_basic_list.c +++ b/level_1/fl_fss/c/fss_basic_list.c @@ -425,13 +425,13 @@ extern "C" { } if (status == F_data_not_stop || status == F_data_not_eos) { - if (complete == f_fss_complete_partial || complete == f_fss_complete_full) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { 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++] = f_fss_basic_list_open; - if (complete == f_fss_complete_full) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { destination->string[destination->used++] = f_fss_basic_list_open_end; } } @@ -563,7 +563,16 @@ extern "C" { return status; } - if (complete == f_fss_complete_partial || complete == f_fss_complete_full) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { + if (complete == f_fss_complete_full_trim) { + status = private_fl_fss_basic_list_write_object_trim(used_start, destination); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + } + status = private_fl_fss_destination_increase_by(2, destination); if (F_status_is_error(status)) { @@ -573,7 +582,7 @@ extern "C" { destination->string[destination->used++] = f_fss_basic_list_open; - if (complete == f_fss_complete_full) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { destination->string[destination->used++] = f_fss_basic_list_open_end; } } @@ -602,7 +611,7 @@ extern "C" { fl_macro_fss_skip_past_delimit_placeholders(content, (*range)); if (range->start > range->stop || range->start >= content.used) { - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { status = private_fl_fss_destination_increase(destination); if (F_status_is_error(status)) return status; @@ -815,7 +824,7 @@ extern "C" { return status; } - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { status = private_fl_fss_destination_increase(destination); if (F_status_is_error(status)) return status; diff --git a/level_1/fl_fss/c/fss_basic_list.h b/level_1/fl_fss/c/fss_basic_list.h index 02d3f96..440a3b0 100644 --- a/level_1/fl_fss/c/fss_basic_list.h +++ b/level_1/fl_fss/c/fss_basic_list.h @@ -131,8 +131,10 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param complete * If f_fss_complete_none, then only the object name is written. - * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. * If f_fss_complete_full, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_full_trim, this will write any appropriate open and close aspects of this object, but will omit whitespace before and after the object. + * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_partial_tim, this will write any appropriate open and close aspects of this object, but will omit whitespace before and after the object. * @param range * The start/stop location within the object string to write as an object. * @param destination diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index 6ce2e60..6063e62 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -163,6 +163,8 @@ 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_ + const f_string_length_t used_start = destination->used; + 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) { @@ -175,10 +177,17 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; } - if (complete == f_fss_complete_partial || complete == f_fss_complete_full) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { if (status == F_none_stop || status == F_none_eos || status == F_data_not_stop || status == F_data_not_eos) { - const f_status_t status_allocation = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status_allocation)) return status_allocation; + f_status_t status2 = F_none; + + if (complete == f_fss_complete_full_trim) { + status2 = private_fl_fss_basic_write_object_trim(quote ? quote : f_fss_delimit_quote_double, used_start, destination); + if (F_status_is_error(status2)) return status2; + } + + status2 = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status2)) return status2; destination->string[destination->used++] = f_fss_extended_open; } @@ -208,11 +217,11 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; // content should be terminated, even if empty. - if (complete == f_fss_complete_partial || complete == f_fss_complete_full || complete == f_fss_complete_next) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_next) { destination->string[destination->used++] = f_fss_extended_next; } - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { destination->string[destination->used++] = f_fss_extended_close; } @@ -227,11 +236,11 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con 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) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_next) { destination->string[destination->used++] = f_fss_extended_next; } - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { destination->string[destination->used++] = f_fss_extended_close; } } diff --git a/level_1/fl_fss/c/fss_extended.h b/level_1/fl_fss/c/fss_extended.h index 9d3dae1..f4f2868 100644 --- a/level_1/fl_fss/c/fss_extended.h +++ b/level_1/fl_fss/c/fss_extended.h @@ -139,8 +139,8 @@ extern "C" { * Otherwise, this is the type of quote to wrap the object in when writing. * @param complete * If f_fss_complete_none, then only the object name is written. - * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object, except for the final newline. - * If f_fss_complete_full, this will write any appropriate open and close aspects of this object, including the final newline. + * If f_fss_complete_full, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. * @param range * The start/stop location within the object string to write as an object. * @param destination diff --git a/level_1/fl_fss/c/fss_extended_list.c b/level_1/fl_fss/c/fss_extended_list.c index 9d7e233..a2b6b18 100644 --- a/level_1/fl_fss/c/fss_extended_list.c +++ b/level_1/fl_fss/c/fss_extended_list.c @@ -809,13 +809,13 @@ extern "C" { } if (status == F_data_not_stop || status == F_data_not_eos) { - if (complete == f_fss_complete_partial || complete == f_fss_complete_full) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { 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++] = f_fss_extended_list_open; - if (complete == f_fss_complete_full) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { destination->string[destination->used++] = f_fss_extended_list_open_end; } } @@ -955,7 +955,16 @@ extern "C" { return status; } - if (complete == f_fss_complete_partial || complete == f_fss_complete_full) { + if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { + if (complete == f_fss_complete_full_trim) { + status = private_fl_fss_basic_list_write_object_trim(used_start, destination); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + } + status = private_fl_fss_destination_increase_by(3, destination); if (F_status_is_error(status)) { @@ -969,7 +978,7 @@ extern "C" { destination->string[destination->used++] = f_fss_extended_list_open; - if (complete == f_fss_complete_full) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { destination->string[destination->used++] = f_fss_extended_list_open_end; } } @@ -998,7 +1007,7 @@ extern "C" { fl_macro_fss_skip_past_delimit_placeholders(content, (*range)); if (range->start > range->stop || range->start >= content.used) { - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { status = private_fl_fss_destination_increase_by(2, destination); if (F_status_is_error(status)) return status; @@ -1225,7 +1234,7 @@ extern "C" { return status; } - if (complete == f_fss_complete_full || complete == f_fss_complete_end) { + if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { status = private_fl_fss_destination_increase_by(3, destination); if (F_status_is_error(status)) return status; diff --git a/level_1/fl_fss/c/fss_extended_list.h b/level_1/fl_fss/c/fss_extended_list.h index e40cdfa..eadfe23 100644 --- a/level_1/fl_fss/c/fss_extended_list.h +++ b/level_1/fl_fss/c/fss_extended_list.h @@ -135,8 +135,10 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param complete * If f_fss_complete_none, then only the object name is written. - * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. * If f_fss_complete_full, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_full_trim, this will write any appropriate open and close aspects of this object, but will omit whitespace before and after the object. + * If f_fss_complete_partial, this will write any appropriate open and close aspects of this object. + * If f_fss_complete_partial_tim, this will write any appropriate open and close aspects of this object, but will omit whitespace before and after the object. * @param range * The start/stop location within the object string to write as an object. * @param destination diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index b3b1700..d4cd253 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -5,6 +5,171 @@ extern "C" { #endif +#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) + f_return_status private_fl_fss_basic_write_object_trim(const f_fss_quote_t quote, const f_string_length_t used_start, f_string_dynamic_t *destination) { + f_status_t status = F_none; + f_string_range_t destination_range = f_macro_string_range_t_initialize(destination->used); + f_string_length_t i = 0; + + uint8_t width = 0; + + // if there are any spaces, then this will be quoted so find the first non-placeholder character. + for (; destination_range.start < destination->used; destination_range.start++) { + if (destination->string[destination_range.start] != f_fss_delimit_placeholder) break; + } // for + + if (destination->string[destination_range.start] == quote) { + const f_string_length_t front = destination_range.start; + + for (destination_range.start++; destination_range.start < destination->used; destination_range.start++) { + + if (destination->string[destination_range.start] == f_fss_delimit_placeholder) { + continue; + } + + status = f_fss_is_space(*destination, destination_range); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + + if (status == F_false) break; + + width = f_macro_utf_byte_width(destination->string[destination_range.start]); + + for (i = 0; i < width; i++) { + destination->string[destination_range.start + i] = f_fss_delimit_placeholder; + } // for + } // for + + // find the last quote. + for (destination_range.start = destination->used - 1; destination_range.start > front; destination_range.start--) { + if (destination->string[destination_range.start] == quote) { + destination_range.start--; + break; + } + } // for + + const f_string_length_t rear = destination_range.start + 1; + + for (; destination_range.start > front; destination_range.start--) { + + if (destination->string[destination_range.start] == f_fss_delimit_placeholder) { + continue; + } + + status = f_fss_is_space(*destination, destination_range); + + // when going backwards, getting incomplete UTF-8 sequences is not an error. + if (F_status_set_fine(status) == F_incomplete_utf) continue; + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + + if (status == F_false) break; + + width = f_macro_utf_byte_width(destination->string[destination_range.start]); + + for (i = 0; i < width; i++) { + destination->string[destination_range.start + i] = f_fss_delimit_placeholder; + } // for + } // for + + // if there is no whitespace between the quotes, post-trimming, then remove the quotes. + for (destination_range.start = front; destination_range.start < rear; destination_range.start++) { + + status = f_fss_is_space(*destination, destination_range); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + + if (status == F_true) break; + } // for + + if (destination_range.start == rear) { + destination->string[front] = f_fss_delimit_placeholder; + destination->string[rear] = f_fss_delimit_placeholder; + } + } + + return F_none; + } +#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) + +#if !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_list_object_write_) + f_return_status private_fl_fss_basic_list_write_object_trim(const f_string_length_t used_start, f_string_dynamic_t *destination) { + f_status_t status = F_none; + f_string_range_t destination_range = f_macro_string_range_t_initialize(destination->used); + f_string_length_t i = 0; + + uint8_t width = 0; + + for (; destination_range.start < destination->used; destination_range.start++) { + + if (destination->string[destination_range.start] == f_fss_delimit_placeholder) { + continue; + } + + status = f_fss_is_space(*destination, destination_range); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + + if (status == F_false) break; + + width = f_macro_utf_byte_width(destination->string[destination_range.start]); + + for (i = 0; i < width; i++) { + destination->string[destination_range.start + i] = f_fss_delimit_placeholder; + } // for + } // for + + for (destination_range.start = destination->used - 1; destination_range.start > 0; destination_range.start--) { + + if (destination->string[destination_range.start] == f_fss_delimit_placeholder) { + destination->used--; + continue; + } + + status = f_fss_is_space(*destination, destination_range); + + // when going backwards, getting incomplete UTF-8 sequences is not an error. + if (F_status_set_fine(status) == F_incomplete_utf) continue; + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + + if (status == F_false) break; + + destination->used -= f_macro_utf_byte_width(destination->string[destination_range.start]); + } // for + + if (destination_range.start == 0) { + status = f_fss_is_space(*destination, destination_range); + + if (F_status_is_error(status)) { + destination->used = used_start; + return status; + } + + if (status == F_true) { + destination->used = 0; + } + } + + return F_none; + } +#endif // !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_list_object_write_) + #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_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; diff --git a/level_1/fl_fss/c/private-fss.h b/level_1/fl_fss/c/private-fss.h index 1b4fe2e..2c4973c 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -16,6 +16,49 @@ extern "C" { #endif /** + * Trim a given object used by the basic and extended object write functions. + * + * @param quote + * If 0, then double quotes are auto-inserted, when required. + * Otherwise, this is the type of quote to wrap the object in when writing. + * @param used_start + * The destination.used value before any operations were perfomed. + * @param destination + * The buffer where the object is written to. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_fss_is_space(). + * + * @see fl_fss_basic_object_write() + * @see fl_fss_extended_object_write() + */ +#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) + extern f_return_status private_fl_fss_basic_write_object_trim(const f_fss_quote_t quote, const f_string_length_t used_start, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) + +/** + * Trim a given object used by the basic list and extended list object write functions. + * + * @param used_start + * The destination.used value before any operations were perfomed. + * @param destination + * The buffer where the object is written to. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_fss_is_space(). + * + * @see fl_fss_basic_list_object_write() + * @see fl_fss_extended_list_object_write() + */ +#if !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_list_object_write_) + extern f_return_status private_fl_fss_basic_list_write_object_trim(const f_string_length_t used_start, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_list_object_write_) + +/** * Private implementation of fl_fss_basic_object_read(). * * Intended to be shared to each of the different implementation variations. @@ -67,6 +110,7 @@ extern "C" { * * @see fl_fss_basic_object_read() * @see fl_fss_extended_object_read() + * @see fl_fss_extended_content_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_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; @@ -169,7 +213,7 @@ extern "C" { #endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_basic_list_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_) || !defined(_di_fl_fss_extended_list_object_write_) || !defined(_di_fl_fss_extended_list_content_write_) /** - * Prepend the given string onto the destination buffer, allocating space as necessary + * Prepend the given string onto the destination buffer, allocating space as necessary. * * @param prepend * A string to prepend at the start of each line, such as spaces. diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.c b/level_3/fss_basic_list_write/c/fss_basic_list_write.c index babfe96..e407450 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.c @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_basic_list_write_short_partial, fss_basic_list_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_basic_list_write_short_prepend, fss_basic_list_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); fll_program_print_help_option(file, context, fss_basic_list_write_short_single, fss_basic_list_write_long_single, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use single quotes."); + fll_program_print_help_option(file, context, fss_basic_list_write_short_trim, fss_basic_list_write_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names."); fll_program_print_help_usage(file, context, fss_basic_list_write_name, ""); diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.h b/level_3/fss_basic_list_write/c/fss_basic_list_write.h index cbde9f7..7b719db 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.h +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.h @@ -64,6 +64,7 @@ extern "C" { #define fss_basic_list_write_short_partial "p" #define fss_basic_list_write_short_prepend "P" #define fss_basic_list_write_short_single "s" + #define fss_basic_list_write_short_trim "T" #define fss_basic_list_write_long_file "file" #define fss_basic_list_write_long_content "content" @@ -72,6 +73,7 @@ extern "C" { #define fss_basic_list_write_long_partial "partial" #define fss_basic_list_write_long_prepend "prepend" #define fss_basic_list_write_long_single "single" + #define fss_basic_list_write_long_trim "trim" enum { fss_basic_list_write_parameter_help, @@ -91,6 +93,7 @@ extern "C" { fss_basic_list_write_parameter_partial, fss_basic_list_write_parameter_prepend, fss_basic_list_write_parameter_single, + fss_basic_list_write_parameter_trim, }; #define fss_basic_list_write_console_parameter_t_initialize \ @@ -111,9 +114,10 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_list_write_short_partial, fss_basic_list_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_prepend, fss_basic_list_write_long_prepend, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_single, fss_basic_list_write_long_single, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_list_write_short_trim, fss_basic_list_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_list_write_total_parameters 16 + #define fss_basic_list_write_total_parameters 17 #endif // _di_fss_basic_list_write_defines_ #ifndef _di_fss_basic_list_write_data_t_ diff --git a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c index 4936980..089c108 100644 --- a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c @@ -58,6 +58,8 @@ extern "C" { f_string_range_t range = f_string_range_t_initialize; if (object) { + uint8_t complete = f_fss_complete_none; + if (object->used) { range.start = 0; range.stop = object->used - 1; @@ -67,7 +69,16 @@ extern "C" { range.stop = 0; } - status = fl_fss_basic_list_object_write(*object, content ? f_fss_complete_full : f_fss_complete_none, &range, buffer); + if (content) { + if (data.parameters[fss_basic_list_write_parameter_trim].result == f_console_result_found) { + complete = f_fss_complete_full_trim; + } + else { + complete = f_fss_complete_full; + } + } + + status = fl_fss_basic_list_object_write(*object, complete, &range, buffer); if (F_status_set_fine(status) == F_none_eol) { fss_basic_list_write_error_parameter_unsupported_eol_print(data); diff --git a/level_3/fss_basic_write/c/fss_basic_write.c b/level_3/fss_basic_write/c/fss_basic_write.c index 8e34bf5..172dfaa 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.c +++ b/level_3/fss_basic_write/c/fss_basic_write.c @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_basic_write_short_partial, fss_basic_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_basic_write_short_prepend, fss_basic_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); fll_program_print_help_option(file, context, fss_basic_write_short_single, fss_basic_write_long_single, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use single quotes."); + fll_program_print_help_option(file, context, fss_basic_write_short_trim, fss_basic_write_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names."); fll_program_print_help_usage(file, context, fss_basic_write_name, ""); diff --git a/level_3/fss_basic_write/c/fss_basic_write.h b/level_3/fss_basic_write/c/fss_basic_write.h index e56c7e5..a8f0664 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.h +++ b/level_3/fss_basic_write/c/fss_basic_write.h @@ -65,6 +65,7 @@ extern "C" { #define fss_basic_write_short_partial "p" #define fss_basic_write_short_prepend "P" #define fss_basic_write_short_single "s" + #define fss_basic_write_short_trim "T" #define fss_basic_write_long_file "file" #define fss_basic_write_long_content "content" @@ -73,6 +74,7 @@ extern "C" { #define fss_basic_write_long_partial "partial" #define fss_basic_write_long_prepend "prepend" #define fss_basic_write_long_single "single" + #define fss_basic_write_long_trim "trim" enum { fss_basic_write_parameter_help, @@ -92,6 +94,7 @@ extern "C" { fss_basic_write_parameter_partial, fss_basic_write_parameter_prepend, fss_basic_write_parameter_single, + fss_basic_write_parameter_trim, }; #define fss_basic_write_console_parameter_t_initialize \ @@ -112,9 +115,10 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_write_short_partial, fss_basic_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_prepend, fss_basic_write_long_prepend, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_single, fss_basic_write_long_single, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_write_short_trim, fss_basic_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_write_total_parameters 16 + #define fss_basic_write_total_parameters 17 #endif // _di_fss_basic_write_defines_ #ifndef _di_fss_basic_write_data_ diff --git a/level_3/fss_basic_write/c/private-fss_basic_write.c b/level_3/fss_basic_write/c/private-fss_basic_write.c index 06a3213..526dd2d 100644 --- a/level_3/fss_basic_write/c/private-fss_basic_write.c +++ b/level_3/fss_basic_write/c/private-fss_basic_write.c @@ -58,6 +58,8 @@ extern "C" { f_string_range_t range = f_string_range_t_initialize; if (object) { + uint8_t complete = f_fss_complete_none; + if (object->used) { range.start = 0; range.stop = object->used - 1; @@ -67,7 +69,16 @@ extern "C" { range.stop = 0; } - status = fl_fss_basic_object_write(*object, quote, content ? f_fss_complete_full : f_fss_complete_none, &range, buffer); + if (content) { + if (data.parameters[fss_basic_write_parameter_trim].result == f_console_result_found) { + complete = f_fss_complete_full_trim; + } + else { + complete = f_fss_complete_full; + } + } + + status = fl_fss_basic_object_write(*object, quote, complete, &range, buffer); if (F_status_set_fine(status) == F_none_eol) { fss_basic_write_error_parameter_unsupported_eol_print(data); diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.c b/level_3/fss_extended_list_write/c/fss_extended_list_write.c index f4fef5d..5225de3 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.c @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_extended_list_write_short_partial, fss_extended_list_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_extended_list_write_short_prepend, fss_extended_list_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); fll_program_print_help_option(file, context, fss_extended_list_write_short_single, fss_extended_list_write_long_single, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use single quotes."); + fll_program_print_help_option(file, context, fss_extended_list_write_short_trim, fss_extended_list_write_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names."); fll_program_print_help_usage(file, context, fss_extended_list_write_name, ""); diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.h b/level_3/fss_extended_list_write/c/fss_extended_list_write.h index e254405..f705074 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.h +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.h @@ -64,6 +64,7 @@ extern "C" { #define fss_extended_list_write_short_partial "p" #define fss_extended_list_write_short_prepend "P" #define fss_extended_list_write_short_single "s" + #define fss_extended_list_write_short_trim "T" #define fss_extended_list_write_long_file "file" #define fss_extended_list_write_long_content "content" @@ -72,6 +73,7 @@ extern "C" { #define fss_extended_list_write_long_partial "partial" #define fss_extended_list_write_long_prepend "prepend" #define fss_extended_list_write_long_single "single" + #define fss_extended_list_write_long_trim "trim" enum { fss_extended_list_write_parameter_help, @@ -91,6 +93,7 @@ extern "C" { fss_extended_list_write_parameter_partial, fss_extended_list_write_parameter_prepend, fss_extended_list_write_parameter_single, + fss_extended_list_write_parameter_trim, }; #define fss_extended_list_write_console_parameter_t_initialize \ @@ -111,9 +114,10 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_list_write_short_partial, fss_extended_list_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_prepend, fss_extended_list_write_long_prepend, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_single, fss_extended_list_write_long_single, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_list_write_short_trim, fss_extended_list_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_list_write_total_parameters 16 + #define fss_extended_list_write_total_parameters 17 #endif // _di_fss_extended_list_write_defines_ #ifndef _di_fss_extended_list_write_data_t_ diff --git a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c index 72fa0b0..cf7776a 100644 --- a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c @@ -58,6 +58,8 @@ extern "C" { f_string_range_t range = f_string_range_t_initialize; if (object) { + uint8_t complete = f_fss_complete_none; + if (object->used) { range.start = 0; range.stop = object->used - 1; @@ -67,7 +69,16 @@ extern "C" { range.stop = 0; } - status = fl_fss_extended_list_object_write(*object, content ? f_fss_complete_full : f_fss_complete_none, &range, buffer); + if (content) { + if (data.parameters[fss_extended_list_write_parameter_trim].result == f_console_result_found) { + complete = f_fss_complete_full_trim; + } + else { + complete = f_fss_complete_full; + } + } + + status = fl_fss_extended_list_object_write(*object, complete, &range, buffer); if (F_status_set_fine(status) == F_none_eol) { fss_extended_list_write_error_parameter_unsupported_eol_print(data); diff --git a/level_3/fss_extended_write/c/fss_extended_write.c b/level_3/fss_extended_write/c/fss_extended_write.c index 08845b5..6cb9453 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.c +++ b/level_3/fss_extended_write/c/fss_extended_write.c @@ -29,6 +29,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_extended_write_short_partial, fss_extended_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_extended_write_short_prepend, fss_extended_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); fll_program_print_help_option(file, context, fss_extended_write_short_single, fss_extended_write_long_single, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use single quotes."); + fll_program_print_help_option(file, context, fss_extended_write_short_trim, fss_extended_write_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names."); fll_program_print_help_usage(file, context, fss_extended_write_name, ""); diff --git a/level_3/fss_extended_write/c/fss_extended_write.h b/level_3/fss_extended_write/c/fss_extended_write.h index 8c5d4d2..0e9b235 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.h +++ b/level_3/fss_extended_write/c/fss_extended_write.h @@ -64,6 +64,7 @@ extern "C" { #define fss_extended_write_short_partial "p" #define fss_extended_write_short_prepend "P" #define fss_extended_write_short_single "s" + #define fss_extended_write_short_trim "T" #define fss_extended_write_long_file "file" #define fss_extended_write_long_content "content" @@ -72,6 +73,7 @@ extern "C" { #define fss_extended_write_long_partial "partial" #define fss_extended_write_long_prepend "prepend" #define fss_extended_write_long_single "single" + #define fss_extended_write_long_trim "trim" enum { fss_extended_write_parameter_help, @@ -91,6 +93,7 @@ extern "C" { fss_extended_write_parameter_partial, fss_extended_write_parameter_prepend, fss_extended_write_parameter_single, + fss_extended_write_parameter_trim, }; #define fss_extended_write_console_parameter_t_initialize \ @@ -111,9 +114,10 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_write_short_partial, fss_extended_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_prepend, fss_extended_write_long_prepend, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_single, fss_extended_write_long_single, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_write_short_trim, fss_extended_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_write_total_parameters 16 + #define fss_extended_write_total_parameters 17 #endif // _di_fss_extended_write_defines_ #ifndef _di_fss_extended_write_data_t_ diff --git a/level_3/fss_extended_write/c/private-fss_extended_write.c b/level_3/fss_extended_write/c/private-fss_extended_write.c index dcdf8ff..de2ad59 100644 --- a/level_3/fss_extended_write/c/private-fss_extended_write.c +++ b/level_3/fss_extended_write/c/private-fss_extended_write.c @@ -58,6 +58,8 @@ extern "C" { f_string_range_t range = f_string_range_t_initialize; if (object) { + uint8_t complete = f_fss_complete_none; + if (object->used) { range.start = 0; range.stop = object->used - 1; @@ -67,7 +69,16 @@ extern "C" { range.stop = 0; } - status = fl_fss_extended_object_write(*object, quote, contents && contents->used ? f_fss_complete_full : f_fss_complete_none, &range, buffer); + if (contents && contents->used) { + if (data.parameters[fss_extended_write_parameter_trim].result == f_console_result_found) { + complete = f_fss_complete_full_trim; + } + else { + complete = f_fss_complete_full; + } + } + + status = fl_fss_extended_object_write(*object, quote, complete, &range, buffer); if (F_status_set_fine(status) == F_none_eol) { fss_extended_write_error_parameter_unsupported_eol_print(data); -- 1.8.3.1