I reviewed, fixed, and cleaned up the write functions.
I have only partially gotten to the basic list and have not so much as glanced at the extended list.
These two I will start working on later.
Several bugs and problems have been identified and resolved.
Add back the UTF-8 processing.
- This time check the width and add each 8-byte sequence until width is reached to correctly process the UTF-8 character.
if (!destination) return F_status_set_error(F_parameter);
#endif // _di_level_1_parameter_checking_
- const 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_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination);
if (status == F_data_not_stop || status == F_data_not_eos) {
destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
-
- if (status == F_data_not_stop) {
- return F_none_stop;
- }
-
- return F_none_eos;
}
if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
- if (status == F_none_stop || status == F_none_eos) {
+ 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;
for (; range->start <= range->stop && range->start < content.used; range->start++) {
- if (content.string[range->start] == f_string_eol[0]) {
+ if (content.string[range->start] == f_fss_eol) {
destination->used = used_start;
return F_status_set_error(F_none_eol);
}
* F_none_stop on success after reaching the range stop.
* F_data_not_stop no data to write due start location being greater than stop location.
* F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
* F_memory_reallocation (with error bit) on reallocation error.
* F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
* F_parameter (with error bit) if a parameter is invalid.
* F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ * F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
*
* Errors (with error bit) from: f_fss_is_space().
+ * Errors (with error bit) from: f_utf_buffer_increment().
*/
#ifndef _di_fl_fss_basic_object_write_
extern f_return_status fl_fss_basic_object_write(const f_string_static_t object, const f_fss_quote_t quote, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
#endif // _di_fl_fss_basic_list_content_read_
#ifndef _di_fl_fss_basic_list_object_write_
- f_return_status fl_fss_basic_list_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_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination) {
#ifndef _di_level_1_parameter_checking_
if (!destination) return F_status_set_error(F_parameter);
#endif // _di_level_1_parameter_checking_
f_status_t status = F_none;
- f_string_range_t buffer_position = f_string_range_t_initialize;
- f_string_length_t start_position = f_string_t_initialize;
- f_string_length_t start_buffer = 0;
-
fl_macro_fss_skip_past_delimit_placeholders(object, (*range))
- if (range->start > range->stop) return F_data_not_stop;
- else if (range->start >= object.used) return F_data_not_eos;
+ if (range->start > range->stop) {
+ status = F_data_not_stop;
+ }
+ else if (range->start >= object.used) {
+ status = F_data_not_eos;
+ }
- start_position = range->start;
+ if (status == F_data_not_stop || status == F_data_not_eos) {
+ if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
+ const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination);
+ if (F_status_is_error(status_allocation)) return status_allocation;
- // ensure that there is room for the start and stop quotes or a slash delimit and the object open character.
- f_string_length_t size_allocate = destination->used + (range->stop - range->start) + 3 + f_fss_default_allocation_step;
+ destination->string[destination->used++] = f_fss_basic_list_open;
- if (size_allocate > destination->size) {
- f_macro_string_dynamic_t_resize(status, (*destination), size_allocate);
- if (F_status_is_error(status)) return status;
+ if (complete == f_fss_complete_full) {
+ destination->string[destination->used++] = f_fss_eol;
+ }
+ }
+
+ return status;
}
- buffer_position.start = destination->used;
- buffer_position.stop = destination->used;
+ // ensure that there is room for a slash delimit, the object open character, and the end of line character.
+ status = private_fl_fss_destination_increase_by(destination->used + (range->stop - range->start) + 3, destination);
+ if (F_status_is_error(status)) return status;
- bool quote = quoted ? F_true : F_false;
+ const f_string_length_t input_start = range->start;
+ const f_string_length_t used_start = destination->used;
- if (quoted) {
- if (quoted == f_fss_quote_type_single) {
- destination->string[destination->used] = f_fss_delimit_quote_single;
- }
- else {
- destination->string[destination->used] = f_fss_delimit_quote_double;
- }
+ f_string_length_t i = 0;
- destination->used++;
- }
+ uint8_t width = 0;
+ // find the first graph character.
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.
- return F_status_set_error(FL_fss_found_comment);
- }
- else if ((status = f_fss_is_graph(object, *range)) == F_true) {
+ status = F_status_set_error(FL_fss_found_comment);
break;
}
- else if (F_status_is_error(status)) {
- return status;
- }
+
+ status = f_fss_is_graph(object, *range);
+ if (F_status_is_error(status)) break;
+
+ if (status == F_true) break;
if (object.string[range->start] != f_fss_delimit_placeholder) {
- destination->string[buffer_position.stop] = object.string[range->start];
- buffer_position.stop++;
+ 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;
+
+ for (i = 0; i < width; i++) {
+ destination->string[destination->used++] = object.string[range->start + i];
+ } // for
}
status = f_utf_buffer_increment(object, range, 1);
- if (F_status_is_error(status)) return status;
+ if (F_status_is_error(status)) break;
} // while
+ if (F_status_is_error(status)) {
+ destination->used = used_start;
+ return status;
+ }
+
while (range->start <= range->stop && range->start < object.used) {
if (object.string[range->start] == f_fss_delimit_slash) {
f_string_length_t slash_count = 1;
- destination->string[buffer_position.stop] = object.string[range->start];
- buffer_position.stop++;
-
- status = f_utf_buffer_increment(object, range, 1);
- if (F_status_is_error(status)) return status;
+ destination->string[destination->used++] = object.string[range->start];
+ range->start++;
while (range->start <= range->stop && range->start < object.used) {
if (object.string[range->start] == f_fss_delimit_placeholder) {
- status = f_utf_buffer_increment(object, range, 1);
- if (F_status_is_error(status)) return status;
-
+ range->start++;
continue;
} else if (object.string[range->start] != f_fss_delimit_slash) {
break;
}
- destination->string[buffer_position.stop] = object.string[range->start];
- buffer_position.stop++;
-
- status = f_utf_buffer_increment(object, range, 1);
- if (F_status_is_error(status)) return status;
+ destination->string[destination->used++] = object.string[range->start];
+ range->start++;
slash_count++;
} // while
- if (range->start > range->stop || range->start >= object.used) {
- size_allocate += slash_count;
+ if (F_status_is_error(status)) break;
- if (size_allocate > destination->size) {
- f_macro_string_dynamic_t_resize(status, (*destination), size_allocate + f_fss_default_allocation_step);
- if (F_status_is_error(status)) return status;
- }
+ if (range->start > range->stop || range->start >= object.used) {
+ status = private_fl_fss_destination_increase_by(slash_count, destination);
+ if (F_status_is_error(status)) break;
while (slash_count > 0) {
- destination->string[buffer_position.stop] = f_fss_delimit_slash;
- buffer_position.stop++;
+ destination->string[destination->used++] = f_fss_delimit_slash;
slash_count--;
} // while
break;
}
}
- else if (object.string[range->start] == f_string_eol[0]) {
- if (buffer_position.stop == buffer_position.start) {
+ else if (object.string[range->start] == f_fss_eol) {
+ if (destination->used == used_start) {
return F_data_not_eol;
}
- break;
+ return F_none_eol;
}
if (object.string[range->start] != f_fss_delimit_placeholder) {
- destination->string[buffer_position.stop] = object.string[range->start];
- buffer_position.stop++;
+ 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;
+
+ for (i = 0; i < width; i++) {
+ destination->string[destination->used++] = object.string[range->start + i];
+ } // for
}
status = f_utf_buffer_increment(object, range, 1);
- if (F_status_is_error(status)) return status;
+ if (F_status_is_error(status)) break;
} // while
- destination->string[buffer_position.stop] = f_fss_basic_list_open;
- destination->string[buffer_position.stop + 1] = f_string_eol[0];
- destination->used = buffer_position.stop + 2;
+ if (F_status_is_error(status)) {
+ destination->used = used_start;
+ return status;
+ }
- if (range->start > range->stop) return F_none_stop;
- else if (range->start >= object.used) return F_none_eos;
+ if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
+ destination->string[destination->used++] = f_fss_basic_list_open;
+ destination->string[destination->used++] = f_fss_eol;
+ }
+
+ if (range->start > range->stop) {
+ return F_none_stop;
+ }
+
+ if (range->start >= object.used) {
+ return F_none_eos;
+ }
return F_none;
}
#ifndef _di_fl_fss_basic_list_content_write_
f_return_status fl_fss_basic_list_content_write(const f_string_static_t content, f_string_range_t *range, f_string_dynamic_t *destination) {
#ifndef _di_level_1_parameter_checking_
+ if (!range) return F_status_set_error(F_parameter);
if (!destination) return F_status_set_error(F_parameter);
#endif // _di_level_1_parameter_checking_
*
* @param object
* The string to write as (does not stop at NULLS, they are ignored and not written).
- * @param quoted
- * 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 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.
* @param range
* The start/stop location within the object string to write as an object.
* @param destination
* Errors (with error bit) from: f_utf_buffer_increment().
*/
#ifndef _di_fl_fss_basic_list_object_write_
- extern f_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination);
+ extern f_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
#endif // _di_fl_fss_basic_list_object_write_
/**
*
* @return
* F_none on success.
+ * F_none_eol on success after reaching the end of the line.
* F_none_eos on success after reaching the end of the buffer.
* F_data_not_stop no data to write due start location being greater than stop location.
* F_data_not_eos no data to write due start location being greater than or equal to buffer size.
if (!destination) return F_status_set_error(F_parameter);
#endif // _di_level_1_parameter_checking_
- const 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_object_write(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(2, destination);
+ const f_status_t status_allocation = private_fl_fss_destination_increase_by(3, destination);
if (F_status_is_error(status_allocation)) return status_allocation;
destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
-
- if (status == F_data_not_stop) {
- return F_none_stop;
- }
-
- return F_none_eos;
}
if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
- if (status == F_none_stop || status == F_none_eos) {
+ 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;
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);
+ if (F_status_is_error(status_allocation)) return status_allocation;
+
+ destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
+ 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) {
status_allocation = private_fl_fss_destination_increase(destination);
* F_none_stop on success after reaching the range stop.
* F_data_not_stop no data to write due start location being greater than stop location.
* F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
* F_memory_reallocation (with error bit) on reallocation error.
* F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
* F_parameter (with error bit) if a parameter is invalid.
* F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ * F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
*
* Errors (with error bit) from: f_fss_is_space().
+ * Errors (with error bit) from: f_utf_buffer_increment().
*/
#ifndef _di_fl_fss_extended_object_write_
extern f_return_status fl_fss_extended_object_write(const f_string_static_t object, const f_fss_quote_t quote, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
* F_none_stop on success after reaching the range stop.
* F_data_not_stop no data to write due start location being greater than stop location.
* F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
* F_memory_reallocation (with error bit) on reallocation error.
* F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
* F_parameter (with error bit) if a parameter is invalid.
* F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ * F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
*
* Errors (with error bit) from: f_fss_is_space().
+ * Errors (with error bit) from: f_utf_buffer_increment().
*/
#ifndef _di_fl_fss_extended_content_write_
extern f_return_status fl_fss_extended_content_write(const f_string_static_t content, const f_fss_quote_t quote, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
#ifndef _di_fl_macro_fss_skip_past_delimit_placeholders_
#define fl_macro_fss_skip_past_delimit_placeholders(buffer, range) \
- while (buffer.string[range.start] == f_fss_delimit_placeholder) { \
- range.start++;\
- \
- if (range.start >= buffer.used) break; \
- if (range.start > range.stop) break; \
- } // while
+ if (buffer.used) { \
+ while (buffer.string[range.start] == f_fss_delimit_placeholder) { \
+ range.start++;\
+ \
+ if (range.start >= buffer.used) break; \
+ if (range.start > range.stop) break; \
+ } \
+ }
#endif // _di_fl_macro_fss_skip_past_delimit_placeholders_
#ifndef _di_fl_macro_fss_object_return_on_overflow_
quoted = F_true;
}
- for (; range->start <= range->stop && range->start < object.used; range->start++) {
+ uint8_t width = 0;
+
+ for (; range->start <= range->stop && range->start < object.used; ) {
if (object.string[range->start] == f_fss_delimit_slash) {
item_first = range->start++;
} // for
destination->string[destination->used++] = quote;
- destination->string[destination->used++] = object.string[range->start];
+
+ 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;
+
+ for (i = 0; i < width; i++) {
+ destination->string[destination->used++] = object.string[range->start + i];
+ } // for
}
else {
destination->string[destination->used++] = f_fss_delimit_slash;
} // for
- destination->string[destination->used++] = object.string[range->start];
+ 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;
+
+ for (i = 0; i < width; i++) {
+ destination->string[destination->used++] = object.string[range->start + i];
+ } // for
}
}
else if (object.string[range->start] == quote) {
if (object.string[range->start] == quote) {
destination->string[destination->used++] = quote;
- // the next quote must also be checked.
- range->start--;
+ // the next quote must also be checked, so do not increment.
continue;
}
}
destination->string[destination->used++] = quote;
- destination->string[destination->used++] = object.string[range->start];
+
+ 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;
+
+ for (i = 0; i < width; i++) {
+ destination->string[destination->used++] = object.string[range->start + i];
+ } // for
}
else if (object.string[range->start] == f_fss_eol) {
status = F_status_set_error(F_none_eol);
}
}
- destination->string[destination->used++] = object.string[range->start];
+ 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;
+
+ for (i = 0; i < width; i++) {
+ destination->string[destination->used++] = object.string[range->start + i];
+ } // for
}
+
+ status = f_utf_buffer_increment(object, range, 1);
+ if (F_status_is_error(status)) break;
} // for
if (F_status_is_error(status)) {
}
#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
f_return_status private_fl_fss_destination_increase(f_string_dynamic_t *destination) {
f_status_t status = F_none;
return status;
}
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
f_return_status private_fl_fss_destination_increase_by(const f_string_length_t amount, f_string_dynamic_t *destination) {
f_status_t status = F_none;
return status;
}
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
#ifdef __cplusplus
} // extern "C"
* F_none_stop on success after reaching the range stop.
* F_data_not_stop no data to write due start location being greater than stop location.
* F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
* F_memory_reallocation (with error bit) on reallocation error.
* F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
* F_parameter (with error bit) if a parameter is invalid.
* F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ * F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ *
+ * Errors (with error bit) from: f_utf_buffer_increment().
*
* @see fl_fss_basic_object_write()
* @see fl_fss_extended_object_write()
*
* @see fl_fss_basic_object_write()
* @see fl_fss_basic_content_write()
+ * @see fl_fss_basic_list_object_write()
* @see fl_fss_extended_object_write()
* @see fl_fss_extended_content_write()
*/
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
extern f_return_status private_fl_fss_destination_increase(f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
/**
* Increase the size of destination buffer by the given amount, but only if necessary.
*
* @see fl_fss_basic_object_write()
* @see fl_fss_basic_content_write()
+ * @see fl_fss_basic_list_object_write()
* @see fl_fss_extended_object_write()
* @see fl_fss_extended_content_write()
*/
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
f_return_status private_fl_fss_destination_increase_by(const f_string_length_t amount, f_string_dynamic_t *destination);
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#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_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
#ifdef __cplusplus
} // extern "C"
}
}
- return F_none;
+ return status;
}
#endif // _di_fll_fss_basic_write_
#endif // _di_fll_fss_basic_list_read_
#ifndef _di_fll_fss_basic_list_write_
- f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, const f_fss_quote_t quoted, f_string_dynamic_t *buffer) {
+ f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, f_string_dynamic_t *destination) {
#ifndef _di_level_2_parameter_checking_
- if (!buffer) return F_status_set_error(F_parameter);
- if (contents.used > contents.size) return F_status_set_error(F_parameter);
+ if (!destination) return F_status_set_error(F_parameter);
#endif // _di_level_2_parameter_checking_
f_status_t status = 0;
- f_array_length_t current = 0;
- f_string_range_t range = f_string_range_t_initialize;
-
- range.start = 0;
- range.stop = object.used - 1;
+ f_string_range_t range = f_macro_string_range_t_initialize(object.used);
- status = fl_fss_basic_list_object_write(object, quoted, &range, buffer);
+ status = fl_fss_basic_list_object_write(object, f_fss_complete_full, &range, destination);
if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) {
return status;
}
if (status == F_none || status == F_none_stop || status == F_none_eos || status == F_none_eol) {
- if (contents.used > 0) {
+ if (contents.used && contents.array[0].used) {
range.start = 0;
range.stop = contents.array[0].used - 1;
- status = fl_fss_basic_list_content_write(contents.array[0], &range, buffer);
-
- if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) {
- return status;
- }
- }
- else {
- if (buffer->used == buffer->size) {
- status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, buffer);
- if (F_status_is_error(status)) return status;
- }
-
- buffer->string[buffer->used] = f_string_eol[0];
- buffer->used++;
+ status = fl_fss_basic_list_content_write(contents.array[0], &range, destination);
}
}
- return F_none;
+ return status;
}
#endif // _di_fll_fss_basic_list_write_
* A string representing the object.
* @param contents
* An array of strings representing multiple content to write.
- * @param quoted
- * 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 buffer
* The buffer to write to.
*
* Errors (with error bit) from: fl_string_dynamic_size_increase().
*/
#ifndef _di_fll_fss_basic_list_write_
- extern f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, const f_fss_quote_t quoted, f_string_dynamic_t *buffer);
+ extern f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, f_string_dynamic_t *buffer);
#endif // _di_fll_fss_basic_list_write_
#ifdef __cplusplus
complete = f_fss_complete_end;
}
- range.start = 0;
- range.stop = contents.array[i].used - 1;
+ if (contents.array[i].used) {
+ range.start = 0;
+ range.stop = contents.array[i].used - 1;
+ }
+ else {
+ range.start = 1;
+ range.stop = 0;
+ }
status = fl_fss_extended_content_write(contents.array[i], quote, complete, &range, destination);
} // for
}
- return F_none;
+ return status;
}
#endif // _di_fll_fss_extended_write_
fll_program_print_help_usage(file, context, fss_basic_list_write_name, "");
+ printf(" The pipe uses the NULL character '");
+ fl_color_print(f_type_output, context.set.notable, "\\0");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+0000");
+ printf(") to designate the start of a Content and uses the Form Feed character '");
+ fl_color_print(f_type_output, context.set.notable, "\\f");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+000C");
+ printf(") to designate the end of the last Content.%c", f_string_eol[0]);
+ printf(" For the pipe, an Object is terminated by either a NULL character '");
+ fl_color_print(f_type_output, context.set.notable, "\\0");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+0000");
+ printf(") or a Form Feed character '");
+ fl_color_print(f_type_output, context.set.notable, "\\f");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+000C");
+ printf(").%c", f_string_eol[0]);
+ printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
return F_none;
}
#endif // _di_fss_basic_list_write_print_help_
if (data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_additional) {
if (data->parameters[fss_basic_list_write_parameter_file].additional.used > 1) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_file);
fl_color_print(data->error.to.stream, data->context.set.error, "' may only be specified once.%c", f_string_eol[0]);
else if (data->parameters[fss_basic_list_write_parameter_content].locations.used && data->parameters[fss_basic_list_write_parameter_partial].locations.used) {
if (data->parameters[fss_basic_list_write_parameter_content].result == f_console_result_additional) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_partial);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter only allows either the '");
location_sub_content = data->parameters[fss_basic_list_write_parameter_content].locations_sub.array[i];
if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", 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_write_long_object);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_content);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", 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_write_long_object);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_content);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ }
status = F_status_set_error(F_parameter);
break;
}
else if (!data->process_pipe) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
fl_color_print(data->error.to.stream, data->context.set.error, "%sThis requires either piped data or the use of 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_write_long_object);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
if (F_status_is_error_not(status) && data->process_pipe) {
if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_partial);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
status = fss_basic_list_write_process_pipe(*data, output, quote, &buffer);
if (F_status_is_error(status)) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
- fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+ fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ }
}
}
}
if (F_status_is_error(status)) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
- fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+ fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ }
}
else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_none) {
// ensure there is always a newline at the end, unless in quiet mode.
return;
}
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
fl_color_print(data.error.to.stream, data.context.set.error, "%sMust 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_write_long_object);
fl_color_print(data.error.to.stream, data.context.set.error, "' parameter and the '");
return;
}
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
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", symbol, parameter);
fl_color_print(data.error.to.stream, data.context.set.error, "' was specified, but no value was given.%c", f_string_eol[0]);
range.stop = 0;
}
- status = fl_fss_basic_list_object_write(*object, quote, &range, buffer);
+ status = fl_fss_basic_list_object_write(*object, content ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
- if (status == F_data_not_stop || status == F_data_not_eos) {
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
- return F_status_set_error(status);
- }
- else if (F_status_is_error(status)) {
+ if (F_status_is_error(status)) {
fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
return status;
}
}
- if (content) {
- if (content->used) {
- range.start = 0;
- range.stop = content->used - 1;
- }
- else {
- range.start = 1;
- range.stop = 0;
- }
+ if (content && content->used) {
+ range.start = 0;
+ range.stop = content->used - 1;
status = fl_fss_basic_list_content_write(*content, &range, buffer);
break;
}
+ if (!block.used) break;
+
range.start = 0;
range.stop = block.used - 1;
}
break;
}
+ if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
+ state = 0x3;
+ range.start++;
+ break;
+ }
+
object.string[object.used++] = block.string[range.start];
} // for
if (F_status_is_error(status)) break;
// if the start of content was not found, then fetch the next block.
- if (state != 0x2) continue;
+ if (state == 0x1) continue;
// if the end of the current block is reached, fetch the next block.
if (range.start > range.stop) continue;
}
if (state == 0x2) {
- if (block.used && range.start <= range.stop) {
+ if (range.start <= range.stop) {
total = (range.stop - range.start) + 1;
}
else {
for (; range.start <= range.stop; range.start++) {
if (block.string[range.start] == fss_basic_list_write_pipe_content_start) {
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+ if (data.error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+ }
status = F_status_set_error(F_unsupported);
break;
}
- else if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
+
+ if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
state = 0x3;
range.start++;
break;
} // for
// if the pipe ended before finishing, then attempt to wrap up.
- if (status_pipe == F_none_eof && state) {
+ if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) {
status = fss_basic_list_write_process(data, output, quote, &object, &content, buffer);
}
fll_program_print_help_usage(file, context, fss_basic_write_name, "");
+ printf(" The pipe uses the NULL character '");
+ fl_color_print(f_type_output, context.set.notable, "\\0");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+0000");
+ printf(") to designate the start of a Content and uses the Form Feed character '");
+ fl_color_print(f_type_output, context.set.notable, "\\f");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+000C");
+ printf(") to designate the end of the last Content.%c", f_string_eol[0]);
+ printf(" For the pipe, an Object is terminated by either a NULL character '");
+ fl_color_print(f_type_output, context.set.notable, "\\0");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+0000");
+ printf(") or a Form Feed character '");
+ fl_color_print(f_type_output, context.set.notable, "\\f");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+000C");
+ printf(").%c", f_string_eol[0]);
+ printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
return F_none;
}
#endif // _di_fss_basic_write_print_help_
if (data->parameters[fss_basic_write_parameter_file].result == f_console_result_additional) {
if (data->parameters[fss_basic_write_parameter_file].additional.used > 1) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_file);
fl_color_print(data->error.to.stream, data->context.set.error, "' may only be specified once.%c", f_string_eol[0]);
else if (data->parameters[fss_basic_write_parameter_content].locations.used && data->parameters[fss_basic_write_parameter_partial].locations.used) {
if (data->parameters[fss_basic_write_parameter_content].result == f_console_result_additional) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_partial);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter only allows either the '");
location_sub_content = data->parameters[fss_basic_write_parameter_content].locations_sub.array[i];
if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_content);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_content);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ }
status = F_status_set_error(F_parameter);
break;
}
else if (!data->process_pipe) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
fl_color_print(data->error.to.stream, data->context.set.error, "%sThis requires either piped data or the use of 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_write_long_object);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
if (F_status_is_error_not(status) && data->process_pipe) {
if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_partial);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
status = fss_basic_write_process_pipe(*data, output, quote, &buffer);
if (F_status_is_error(status)) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
- fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+ fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ }
}
}
}
if (F_status_is_error(status)) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
- fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+ fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ }
}
else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_write_parameter_file].result == f_console_result_none) {
// ensure there is always a newline at the end, unless in quiet mode.
return;
}
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
fl_color_print(data.error.to.stream, data.context.set.error, "%sMust 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_write_long_object);
fl_color_print(data.error.to.stream, data.context.set.error, "' parameter and the '");
return;
}
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
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", symbol, parameter);
fl_color_print(data.error.to.stream, data.context.set.error, "' was specified, but no value was given.%c", f_string_eol[0]);
}
#endif // _di_fss_basic_write_error_parameter_value_missing_print_
+#ifndef _di_fss_basic_write_error_parameter_unsupported_eol_print_
+ void fss_basic_write_error_parameter_unsupported_eol_print(const fss_basic_write_data_t data) {
+
+ if (data.error.verbosity == f_console_verbosity_quiet) {
+ return;
+ }
+
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
+ fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
+ fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
+ }
+#endif // _di_fss_basic_write_error_parameter_unsupported_eol_print_
+
#ifndef _di_fss_basic_write_process_
f_return_status fss_basic_write_process(const fss_basic_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) {
f_status_t status = F_none;
status = fl_fss_basic_object_write(*object, quote, content ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
if (F_status_set_fine(status) == F_none_eol) {
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
- fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
- fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
+ fss_basic_write_error_parameter_unsupported_eol_print(data);
return F_status_set_error(F_unsupported);
}
- if (status == F_data_not_stop || status == F_data_not_eos) {
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
- return F_status_set_error(status);
- }
- else if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_object_write", F_true);
return status;
}
}
status = fl_fss_basic_content_write(*content, object ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
+ if (F_status_set_fine(status) == F_none_eol) {
+ fss_basic_write_error_parameter_unsupported_eol_print(data);
+
+ return F_status_set_error(F_unsupported);
+ }
+
if (F_status_is_error(status)) {
fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
return status;
status = fl_string_append(f_string_eol, 1, buffer);
if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true);
return status;
}
}
break;
}
+ if (!block.used) break;
+
range.start = 0;
range.stop = block.used - 1;
}
break;
}
+ if (block.string[range.start] == fss_basic_write_pipe_content_end) {
+ state = 0x3;
+ range.start++;
+ break;
+ }
+
object.string[object.used++] = block.string[range.start];
} // for
if (F_status_is_error(status)) break;
// if the start of content was not found, then fetch the next block.
- if (state != 0x2) continue;
+ if (state == 0x1) continue;
// if the end of the current block is reached, fetch the next block.
if (range.start > range.stop) continue;
}
if (state == 0x2) {
- if (block.used && range.start <= range.stop) {
+ if (range.start <= range.stop) {
total = (range.stop - range.start) + 1;
}
else {
for (; range.start <= range.stop; range.start++) {
if (block.string[range.start] == fss_basic_write_pipe_content_start) {
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+ if (data.error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+ }
status = F_status_set_error(F_unsupported);
break;
range.start++;
break;
}
+ else if (F_status_set_fine(status) == F_none_eol) {
+ fss_basic_write_error_parameter_unsupported_eol_print(data);
+
+ status = F_status_set_error(F_unsupported);
+ break;
+ }
content.string[content.used++] = block.string[range.start];
} // for
} // for
// if the pipe ended before finishing, then attempt to wrap up.
- if (status_pipe == F_none_eof && state) {
+ if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) {
status = fss_basic_write_process(data, output, quote, &object, &content, buffer);
}
#endif // _di_fss_basic_write_error_parameter_value_missing_print_
/**
+ * Print an message about a parameter EOL being unsupported.
+ *
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ * F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_basic_write_error_parameter_unsupported_eol_print_
+ void fss_basic_write_error_parameter_unsupported_eol_print(const fss_basic_write_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_write_error_parameter_unsupported_eol_print_
+
+/**
* Process a given object and content, printing the FSS if valid or an error if invalid.
*
* @param data
fll_program_print_help_usage(file, context, fss_extended_write_name, "");
+ printf(" The pipe uses the NULL character '");
+ fl_color_print(f_type_output, context.set.notable, "\\0");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+0000");
+ printf(") to designate the start of a Content and uses the Form Feed character '");
+ fl_color_print(f_type_output, context.set.notable, "\\f");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+000C");
+ printf(") to designate the end of the last Content.%c", f_string_eol[0]);
+ printf(" For the pipe, an Object is terminated by either a NULL character '");
+ fl_color_print(f_type_output, context.set.notable, "\\0");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+0000");
+ printf(") or a Form Feed character '");
+ fl_color_print(f_type_output, context.set.notable, "\\f");
+ printf("' (");
+ fl_color_print(f_type_output, context.set.notable, "U+000C");
+ printf(").%c", f_string_eol[0]);
+ printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
return F_none;
}
#endif // _di_fss_extended_write_print_help_
if (data->parameters[fss_extended_write_parameter_file].result == f_console_result_additional) {
if (data->parameters[fss_extended_write_parameter_file].additional.used > 1) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_file);
fl_color_print(data->error.to.stream, data->context.set.error, "' may only be specified once.%c", f_string_eol[0]);
else if (data->parameters[fss_extended_write_parameter_content].locations.used && data->parameters[fss_extended_write_parameter_partial].locations.used) {
if (data->parameters[fss_extended_write_parameter_content].result == f_console_result_additional) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_partial);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter only allows either the '");
f_array_length_t location_sub_content = data->parameters[fss_extended_write_parameter_content].locations_sub.array[0];
if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ }
status = F_status_set_error(F_parameter);
}
location_sub_content = data->parameters[fss_extended_write_parameter_content].locations_sub.array[data->parameters[fss_extended_write_parameter_content].locations_sub.used - 1];
if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must have at least one '");
- fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
- fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must have at least one '");
+ fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
+ fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+ }
status = F_status_set_error(F_parameter);
}
}
else if (!data->process_pipe) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
fl_color_print(data->error.to.stream, data->context.set.error, "%sThis requires either piped data or the use of 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_write_long_object);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
if (F_status_is_error_not(status) && data->process_pipe) {
if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) {
if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
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_write_long_partial);
fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
status = fss_extended_write_process_pipe(*data, output, quote, &buffer);
if (F_status_is_error(status)) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
- fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+ fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ }
}
}
}
if (F_status_is_error(status)) {
- fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
- fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
- fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+ fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+ fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+ }
}
else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_extended_write_parameter_file].result == f_console_result_none) {
// ensure there is always a newline at the end, unless in quiet mode.
return;
}
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
fl_color_print(data.error.to.stream, data.context.set.error, "%sMust 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_write_long_object);
fl_color_print(data.error.to.stream, data.context.set.error, "' parameter at least once and the '");
return;
}
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
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", symbol, parameter);
fl_color_print(data.error.to.stream, data.context.set.error, "' was specified, but no value was given.%c", f_string_eol[0]);
}
#endif // _di_fss_extended_write_error_parameter_value_missing_print_
+#ifndef _di_fss_extended_write_error_parameter_unsupported_eol_print_
+ void fss_extended_write_error_parameter_unsupported_eol_print(const fss_extended_write_data_t data) {
+
+ if (data.error.verbosity == f_console_verbosity_quiet) {
+ return;
+ }
+
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
+ fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
+ fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
+ }
+#endif // _di_fss_extended_write_error_parameter_unsupported_eol_print_
+
#ifndef _di_fss_extended_write_process_
f_return_status fss_extended_write_process(const fss_extended_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_statics_t *contents, f_string_dynamic_t *buffer) {
f_status_t status = F_none;
range.stop = 0;
}
- status = fl_fss_extended_object_write(*object, quote, contents ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
+ status = fl_fss_extended_object_write(*object, quote, contents && contents->used ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
- if (status == F_data_not_stop || status == F_data_not_eos) {
- fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
- return F_status_set_error(status);
+ if (F_status_set_fine(status) == F_none_eol) {
+ fss_extended_write_error_parameter_unsupported_eol_print(data);
+
+ return F_status_set_error(F_unsupported);
}
- else if (F_status_is_error(status)) {
+
+ if (F_status_is_error(status)) {
fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_object_write", F_true);
return F_status_set_error(status);
}
}
if (contents) {
- for (f_array_length_t i = 0; i < contents->used; i++) {
+ if (contents->used) {
+ for (f_array_length_t i = 0; i < contents->used; i++) {
- if (contents->used) {
- range.start = 0;
- range.stop = contents->array[i].used - 1;
- }
- else {
- range.start = 1;
- range.stop = 0;
- }
+ if (contents->array[i].used) {
+ range.start = 0;
+ range.stop = contents->array[i].used - 1;
+ }
+ else {
+ range.start = 1;
+ range.stop = 0;
+ }
+
+ status = fl_fss_extended_content_write(contents->array[i], quote, i + 1 < contents->used ? f_fss_complete_next : f_fss_complete_end, &range, buffer);
+
+ if (F_status_set_fine(status) == F_none_eol) {
+ fss_extended_write_error_parameter_unsupported_eol_print(data);
+
+ return F_status_set_error(F_unsupported);
+ }
- status = fl_fss_extended_content_write(contents->array[i], quote, i + 1 < contents->used ? f_fss_complete_next : f_fss_complete_end, &range, buffer);
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_content_write", F_true);
+ return F_status_set_error(status);
+ }
+ } // for
+ }
+ else {
+ // objects in this standard do not have EOL, so add an EOL for printing purposes when there is no desired content.
+ status = fl_string_append(f_string_eol, 1, buffer);
if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_content_write", F_true);
- return F_status_set_error(status);
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true);
+ return status;
}
- } // for
+ }
}
f_print_dynamic(output.stream, *buffer);
input.id = f_type_descriptor_input;
input.size_read = 2048;
+ f_array_length_t i = 0;
+
f_string_length_t total = 0;
f_string_length_t previous = 0;
f_string_range_t range = f_string_range_t_initialize;
f_string_dynamic_t object = f_string_dynamic_t_initialize;
f_string_dynamics_t contents = f_string_dynamics_t_initialize;
- // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = processing content, 0x3 = end object/content set.
+ // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = new individual content, 0x3 = processing content, 0x4 = end object/content set.
uint8_t state = 0;
for (;;) {
break;
}
+ if (!block.used) break;
+
range.start = 0;
range.stop = block.used - 1;
}
if (!state || state == 0x1) {
if (!state) {
+ if (contents.used) {
+ for (i = 0; i < contents.used; i++) {
+ contents.array[i].used = 0;
+ } // for
+ }
+
object.used = 0;
contents.used = 0;
break;
}
+ if (block.string[range.start] == fss_extended_write_pipe_content_end) {
+ state = 0x4;
+ range.start++;
+ break;
+ }
+
object.string[object.used++] = block.string[range.start];
} // for
if (F_status_is_error(status)) break;
// if the start of content was not found, then fetch the next block.
- if (state != 0x2) continue;
+ if (state == 0x1) continue;
// if the end of the current block is reached, fetch the next block.
if (range.start > range.stop) continue;
}
if (state == 0x2) {
- if (block.used && range.start <= range.stop) {
+ if (contents.used + 1 > contents.size) {
+ status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
+ break;
+ }
+ }
+
+ state = 0x3;
+ contents.used++;
+ }
+
+ if (state == 0x3) {
+ if (range.start <= range.stop) {
total = (range.stop - range.start) + 1;
}
else {
for (; range.start <= range.stop; range.start++) {
if (block.string[range.start] == fss_extended_write_pipe_content_start) {
- contents.used++;
+ if (contents.used + 1 > contents.size) {
+ status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
- if (contents.used < contents.size && contents.array[contents.used].used) {
- contents.array[contents.used].used = 0;
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
+ break;
+ }
}
+ contents.used++;
continue;
}
else if (block.string[range.start] == fss_extended_write_pipe_content_end) {
- state = 0x3;
+ state = 0x4;
range.start++;
break;
}
+ else if (F_status_set_fine(status) == F_none_eol) {
+ fss_extended_write_error_parameter_unsupported_eol_print(data);
- if (contents.used + 1 > contents.size) {
- status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
-
- if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
- break;
- }
+ status = F_status_set_error(F_unsupported);
+ break;
}
- if (contents.array[contents.used].used + 1 > contents.array[contents.used].size) {
- status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, &contents.array[contents.used]);
+ if (contents.array[contents.used - 1].used + 1 > contents.array[contents.used - 1].size) {
+ status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, &contents.array[contents.used - 1]);
if (F_status_is_error(status)) {
fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
}
}
- contents.array[contents.used].string[contents.array[contents.used].used++] = block.string[range.start];
+ contents.array[contents.used - 1].string[contents.array[contents.used - 1].used++] = block.string[range.start];
} // for
if (F_status_is_error(status)) break;
}
else {
- state = 0x3;
+ state = 0x4;
}
}
- if (state == 0x3) {
+ if (state == 0x4) {
status = fss_extended_write_process(data, output, quote, &object, &contents, buffer);
if (F_status_is_error(status)) break;
} // for
// if the pipe ended before finishing, then attempt to wrap up.
- if (status_pipe == F_none_eof && state) {
+ if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) {
status = fss_extended_write_process(data, output, quote, &object, &contents, buffer);
}
#endif // _di_fss_extended_write_error_parameter_value_missing_print_
/**
+ * Print an message about a parameter EOL being unsupported.
+ *
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ * F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_extended_write_error_parameter_unsupported_eol_print_
+ void fss_extended_write_error_parameter_unsupported_eol_print(const fss_extended_write_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_write_error_parameter_unsupported_eol_print_
+
+/**
* Process a given object and content, printing the FSS if valid or an error if invalid.
*
* @param data