The previous implementation is weak in that there is no good way to just delimit Object or just delimit Content.
Redesign to allow for specifying the delimit parameter multiple times and therefore allow for customizing what to specify.
Rename "depth" to "content" in the delimit enum to better communicate that this is for "content" delimiting.
Examples:
- "fss_basic_read --delimit object": Results in delimited Objects but not Content.
- "fss_basic_read --delimit 0+": Results in delimited Content (position 0 and greater) but not Objects.
- "fss_basic_read --delimit object --delimit 1-": Results in delimited Objects and delimit Content (position 1 or less).
For this standard, there is no delimit support in Content so the use of the numeric range is superfluous.
Having this functionality, however, makes it consistent with the rest of the FSS Read programs.
fprintf(output.stream, ": Do not apply delimits.%c", f_string_eol_s[0]);
fprintf(output.stream, " - ");
f_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_all);
- fprintf(output.stream, ": (default) apply all delimits.%c", f_string_eol_s[0]);
- fprintf(output.stream, " - a number, 0 or greater: apply delimits for the specified depth.%c", f_string_eol_s[0]);
- fprintf(output.stream, " - a number, 0 or greater, followed by a ");
+ fprintf(output.stream, ": (default) Apply all delimits.%c", f_string_eol_s[0]);
+ fprintf(output.stream, " - ");
+ f_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_object);
+ fprintf(output.stream, ": Apply delimits for Objects.%c", f_string_eol_s[0]);
+ fprintf(output.stream, " - A number, 0 or greater: apply delimits for Content at the specified depth.%c", f_string_eol_s[0]);
+ fprintf(output.stream, " - A number, 0 or greater, followed by a ");
f_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_greater);
- fprintf(output.stream, ": (such as '1+') apply delimits for the specified depth and any greater depth (numerically).%c", f_string_eol_s[0]);
- fprintf(output.stream, " - a number, 0 or greater, followed by a ");
+ fprintf(output.stream, ": (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%c", f_string_eol_s[0]);
+ fprintf(output.stream, " - A number, 0 or greater, followed by a ");
f_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_lesser);
- fprintf(output.stream, ": (such as '1-') apply delimits for the specified depth and any lesser depth (numerically).%c", f_string_eol_s[0]);
+ fprintf(output.stream, ": (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, " The ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_delimit);
+ fprintf(output.stream, " parameter may be specified multiple times to customize the delimit behavior.%c", f_string_eol_s[0]);
+
+ fprintf(output.stream, " The ");
+ f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_delimit);
+ fprintf(output.stream, " values ");
+ f_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_none);
+ fprintf(output.stream, " and ");
+ f_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_all);
+ fprintf(output.stream, ", overrule all other delimit values.%c", f_string_eol_s[0]);
fprintf(output.stream, "%c", f_string_eol_s[0]);
if (F_status_is_error(status)) {
fss_basic_read_main_delete(main);
+
return F_status_set_error(status);
}
}
if (F_status_is_error(status)) {
fss_basic_read_main_delete(main);
+
return status;
}
}
if (F_status_is_error_not(status) && main->parameters[fss_basic_read_parameter_delimit].result == f_console_result_additional) {
- const f_array_length_t location = main->parameters[fss_basic_read_parameter_delimit].values.array[0];
- f_array_length_t length = strnlen(arguments->argv[location], f_console_parameter_size);
+ f_array_length_t location = 0;
+ f_array_length_t length = 0;
- if (length == 0) {
- f_color_print(main->error.to.stream, main->context.set.error, "%sThe value for the parameter '", fll_error_print_error);
- f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_delimit);
- f_color_print(main->error.to.stream, main->context.set.error, "' must not be empty.%c", f_string_eol_s[0]);
+ // Set the value to 0 to allow for detecting mode based on what is provided.
+ data.delimit_mode = 0;
- status = F_status_set_error(F_parameter);
- }
- else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_none, length, fss_basic_read_delimit_mode_name_none_length) == F_equal_to) {
- data.delimit_mode = fss_basic_read_delimit_mode_none;
- }
- else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_all, length, fss_basic_read_delimit_mode_name_all_length) == F_equal_to) {
- data.delimit_mode = fss_basic_read_delimit_mode_all;
- }
- else {
- data.delimit_mode = fss_basic_read_delimit_mode_depth;
+ for (f_array_length_t i = 0; i < main->parameters[fss_basic_read_parameter_delimit].values.used; ++i) {
- if (arguments->argv[location][length - 1] == fss_basic_read_delimit_mode_name_greater[0]) {
- data.delimit_mode = fss_basic_read_delimit_mode_depth_greater;
+ location = main->parameters[fss_basic_read_parameter_delimit].values.array[i];
+ length = strnlen(arguments->argv[location], f_console_parameter_size);
- // shorten the length to better convert the remainder to a number.
- --length;
- }
- else if (arguments->argv[location][length - 1] == fss_basic_read_delimit_mode_name_lesser[0]) {
- data.delimit_mode = fss_basic_read_delimit_mode_depth_lesser;
+ if (!length) {
+ f_color_print(main->error.to.stream, main->context.set.error, "%sThe value for the parameter '", fll_error_print_error);
+ f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_delimit);
+ f_color_print(main->error.to.stream, main->context.set.error, "' must not be empty.%c", f_string_eol_s[0]);
- // shorten the length to better convert the remainder to a number.
- --length;
+ status = F_status_set_error(F_parameter);
+ break;
+ }
+ else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_none, length, fss_basic_read_delimit_mode_name_none_length) == F_equal_to) {
+ data.delimit_mode = fss_basic_read_delimit_mode_none;
+ }
+ else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_all, length, fss_basic_read_delimit_mode_name_all_length) == F_equal_to) {
+ data.delimit_mode = fss_basic_read_delimit_mode_all;
}
+ else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_object, length, fss_basic_read_delimit_mode_name_object_length) == F_equal_to) {
+ switch (data.delimit_mode) {
+ case 0:
+ data.delimit_mode = fss_basic_read_delimit_mode_object;
+ break;
+
+ case fss_basic_read_delimit_mode_none:
+ case fss_basic_read_delimit_mode_all:
+ case fss_basic_read_delimit_mode_content_greater_object:
+ case fss_basic_read_delimit_mode_content_lesser_object:
+ case fss_basic_read_delimit_mode_object:
+ break;
+
+ case fss_basic_read_delimit_mode_content:
+ data.delimit_mode = fss_basic_read_delimit_mode_content_object;
+ break;
+
+ case fss_basic_read_delimit_mode_content_greater:
+ data.delimit_mode = fss_basic_read_delimit_mode_content_greater_object;
+ break;
+
+ case fss_basic_read_delimit_mode_content_lesser:
+ data.delimit_mode = fss_basic_read_delimit_mode_content_lesser_object;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else {
+ if (!data.delimit_mode) {
+ data.delimit_mode = fss_basic_read_delimit_mode_content;
+ }
+ else if (data.delimit_mode == fss_basic_read_delimit_mode_object) {
+ data.delimit_mode = fss_basic_read_delimit_mode_content_object;
+ }
- f_string_range_t range = macro_f_string_range_t_initialize(length);
+ if (arguments->argv[location][length - 1] == fss_basic_read_delimit_mode_name_greater[0]) {
+ if (!(data.delimit_mode == fss_basic_read_delimit_mode_none || data.delimit_mode == fss_basic_read_delimit_mode_all)) {
+ if (data.delimit_mode == fss_basic_read_delimit_mode_content_object) {
+ data.delimit_mode = fss_basic_read_delimit_mode_content_greater_object;
+ }
+ else {
+ data.delimit_mode = fss_basic_read_delimit_mode_content_greater;
+ }
+ }
- // ignore leading plus sign.
- if (arguments->argv[location][0] == '+') {
- ++range.start;
- }
+ // shorten the length to better convert the remainder to a number.
+ --length;
+ }
+ else if (arguments->argv[location][length - 1] == fss_basic_read_delimit_mode_name_lesser[0]) {
+ if (!(data.delimit_mode == fss_basic_read_delimit_mode_none || data.delimit_mode == fss_basic_read_delimit_mode_all)) {
+ if (data.delimit_mode == fss_basic_read_delimit_mode_content_object) {
+ data.delimit_mode = fss_basic_read_delimit_mode_content_lesser_object;
+ }
+ else {
+ data.delimit_mode = fss_basic_read_delimit_mode_content_lesser;
+ }
+ }
- status = fl_conversion_string_to_number_unsigned(arguments->argv[location], range, &data.delimit_depth);
+ // shorten the length to better convert the remainder to a number.
+ --length;
+ }
- if (F_status_is_error(status)) {
- fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_delimit, arguments->argv[location]);
+ f_string_range_t range = macro_f_string_range_t_initialize(length);
+
+ // ignore leading plus sign.
+ if (arguments->argv[location][0] == '+') {
+ ++range.start;
+ }
+
+ status = fl_conversion_string_to_number_unsigned(arguments->argv[location], range, &data.delimit_depth);
+
+ if (F_status_is_error(status)) {
+ fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_delimit, arguments->argv[location]);
+ break;
+ }
}
+ } // for
+
+ // Guarantee the default value is "all".
+ if (!data.delimit_mode) {
+ data.delimit_mode = fss_basic_read_delimit_mode_all;
}
}
// This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file.
if (F_status_is_error_not(status) && data.depths.array[0].depth > 0) {
if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
- fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
+ fss_basic_read_print_zero(main);
}
fss_basic_read_data_delete_simple(&data);
} // for
macro_f_array_lengths_t_delete_simple(main->remaining);
-
macro_f_color_context_t_delete_simple(main->context);
return F_none;
f_console_parameter_t_initialize(f_console_standard_short_help_s, f_console_standard_long_help_s, 0, 0, f_console_type_normal), \
f_console_parameter_t_initialize(f_console_standard_short_light_s, f_console_standard_long_light_s, 0, 0, f_console_type_inverse), \
f_console_parameter_t_initialize(f_console_standard_short_dark_s, f_console_standard_long_dark_s, 0, 0, f_console_type_inverse), \
- f_console_parameter_t_initialize(f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, 0, F_false, f_console_type_inverse), \
+ f_console_parameter_t_initialize(f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, 0, 0, f_console_type_inverse), \
f_console_parameter_t_initialize(f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, 0, 0, f_console_type_inverse), \
f_console_parameter_t_initialize(f_console_standard_short_normal_s, f_console_standard_long_normal_s, 0, 0, f_console_type_inverse), \
f_console_parameter_t_initialize(f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, 0, 0, f_console_type_inverse), \
#define fss_basic_read_total_parameters 21
#endif // _di_fss_basic_read_defines_
+/**
+ *
+ *
+ */
#ifndef _di_fss_basic_read_delimit_mode_
#define fss_basic_read_delimit_mode_name_none "none"
#define fss_basic_read_delimit_mode_name_all "all"
+ #define fss_basic_read_delimit_mode_name_object "object"
#define fss_basic_read_delimit_mode_name_greater "+"
#define fss_basic_read_delimit_mode_name_lesser "-"
#define fss_basic_read_delimit_mode_name_none_length 4
#define fss_basic_read_delimit_mode_name_all_length 3
+ #define fss_basic_read_delimit_mode_name_object_length 6
#define fss_basic_read_delimit_mode_name_greater_length 1
#define fss_basic_read_delimit_mode_name_lesser_length 1
enum {
fss_basic_read_delimit_mode_none = 1,
fss_basic_read_delimit_mode_all,
- fss_basic_read_delimit_mode_depth,
- fss_basic_read_delimit_mode_depth_greater,
- fss_basic_read_delimit_mode_depth_lesser,
+ fss_basic_read_delimit_mode_content,
+ fss_basic_read_delimit_mode_content_greater,
+ fss_basic_read_delimit_mode_content_greater_object,
+ fss_basic_read_delimit_mode_content_lesser,
+ fss_basic_read_delimit_mode_content_lesser_object,
+ fss_basic_read_delimit_mode_content_object,
+ fss_basic_read_delimit_mode_object,
};
#endif // _di_fss_basic_read_delimit_modes_
// data->files is expected to be statically loaded and cannot be deallocated.
fss_basic_read_depths_resize(0, &data->depths);
- macro_f_fss_delimits_t_delete_simple(data->delimits);
+ macro_f_string_dynamic_t_delete_simple(data->buffer);
macro_f_fss_contents_t_delete_simple(data->contents);
macro_f_fss_objects_t_delete_simple(data->objects);
- macro_f_string_dynamic_t_delete_simple(data->buffer);
+ macro_f_fss_delimits_t_delete_simple(data->delimits);
}
#endif // _di_fss_basic_read_data_delete_simple_
* fss_basic_read_data_option_*:
* - at: The object at the given position is being selected (Think of this as select a row for some Object).
* - content: The Content is to be printed.
- * - delimit: The Content delimits will be applied on print.
* - empty: Empty Content will be printed (Objects that have no Content will have their empty Content printed).
* - line: A specific Content at a given line is to be selected (Think of this as select a row for some Content).
* - name: A specific Object name has been requested.
#define fss_basic_read_data_option_at 0x1
#define fss_basic_read_data_option_content 0x2
- #define fss_basic_read_data_option_delimit 0x4
- #define fss_basic_read_data_option_empty 0x8
- #define fss_basic_read_data_option_line 0x10
- #define fss_basic_read_data_option_name 0x20
- #define fss_basic_read_data_option_object 0x40
- #define fss_basic_read_data_option_select 0x80
- #define fss_basic_read_data_option_total 0x100
- #define fss_basic_read_data_option_trim 0x200
+ #define fss_basic_read_data_option_empty 0x4
+ #define fss_basic_read_data_option_line 0x8
+ #define fss_basic_read_data_option_name 0x10
+ #define fss_basic_read_data_option_object 0x20
+ #define fss_basic_read_data_option_select 0x40
+ #define fss_basic_read_data_option_total 0x80
+ #define fss_basic_read_data_option_trim 0x100
typedef struct {
uint16_t option;
extern "C" {
#endif
+#ifndef _di_fss_basic_read_delimit_object_is_
+ f_status_t fss_basic_read_delimit_object_is(const f_array_length_t depth, fss_basic_read_data_t * const data) {
+
+ switch (data->delimit_mode) {
+ case fss_basic_read_delimit_mode_none:
+ case fss_basic_read_delimit_mode_content:
+ case fss_basic_read_delimit_mode_content_greater:
+ case fss_basic_read_delimit_mode_content_lesser:
+ return F_false;
+
+ case fss_basic_read_delimit_mode_all:
+ case fss_basic_read_delimit_mode_content_object:
+ case fss_basic_read_delimit_mode_content_greater_object:
+ case fss_basic_read_delimit_mode_content_lesser_object:
+ case fss_basic_read_delimit_mode_object:
+ return F_true;
+
+ default:
+ break;
+ }
+
+ return depth == data->delimit_depth || data->delimit_mode == fss_basic_read_delimit_mode_content_lesser;
+ }
+#endif // _di_fss_basic_read_delimit_object_is_
+
#ifndef _di_fss_basic_read_depth_process_
f_status_t fss_basic_read_depth_process(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) {
#endif // _di_fss_basic_read_load_number_
#ifndef _di_fss_basic_read_print_at_
- void fss_basic_read_print_at(fss_basic_read_main_t * const main, fss_basic_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits) {
+ void fss_basic_read_print_at(fss_basic_read_main_t * const main, fss_basic_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content) {
if (at >= data->contents.used) {
return;
}
if (data->option & fss_basic_read_data_option_object) {
- print_object(main->output.stream, data->buffer, data->objects.array[at], delimits);
+ print_object(main->output.stream, data->buffer, data->objects.array[at], delimits_object);
if (data->option & fss_basic_read_data_option_content) {
fss_basic_read_print_object_end(main);
}
if ((data->option & fss_basic_read_data_option_content) && data->contents.array[at].used) {
- f_print_except_dynamic_partial(main->output.stream, data->buffer, data->contents.array[at].array[0], delimits);
+ f_print_except_dynamic_partial(main->output.stream, data->buffer, data->contents.array[at].array[0], delimits_content);
}
if ((data->option & fss_basic_read_data_option_object) || (data->option & fss_basic_read_data_option_content) && (data->contents.array[at].used || (data->option & fss_basic_read_data_option_empty))) {
}
f_array_lengths_t except_none = f_array_lengths_t_initialize;
- f_array_lengths_t *delimits = (data->option & fss_basic_read_data_option_delimit) ? &data->delimits : &except_none;
+ f_array_lengths_t *delimits = fss_basic_read_delimit_object_is(0, data) ? &data->delimits : &except_none;
for (f_array_length_t i = 0; i < data->contents.used; ++i) {
if (!names[i]) continue;
- fss_basic_read_print_at(main, data, i, *delimits);
+ fss_basic_read_print_at(main, data, i, *delimits, except_none);
} // for
return F_none;
}
f_array_lengths_t except_none = f_array_lengths_t_initialize;
- f_array_lengths_t *delimits = (data->option & fss_basic_read_data_option_delimit) ? &data->delimits : &except_none;
+ f_array_lengths_t *delimits = fss_basic_read_delimit_object_is(0, data) ? &data->delimits : &except_none;
f_array_length_t at = 0;
}
}
else if (!data->line) {
- fss_basic_read_print_at(main, data, i, *delimits);
+ fss_basic_read_print_at(main, data, i, *delimits, except_none);
}
}
else if (data->option & fss_basic_read_data_option_total) {
}
}
else {
- fss_basic_read_print_at(main, data, i, *delimits);
+ fss_basic_read_print_at(main, data, i, *delimits, except_none);
}
break;
f_status_t fss_basic_read_process_line(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) {
f_array_lengths_t except_none = f_array_lengths_t_initialize;
- f_array_lengths_t *delimits = (data->option & fss_basic_read_data_option_delimit) ? &data->delimits : &except_none;
+ f_array_lengths_t *delimits = fss_basic_read_delimit_object_is(0, data) ? &data->delimits : &except_none;
f_array_length_t line_current = 0;
}
if (line_current == data->line) {
- fss_basic_read_print_at(main, data, i, *delimits);
+ fss_basic_read_print_at(main, data, i, *delimits, except_none);
break;
}
data->option |= fss_basic_read_data_option_content;
}
- if (!(data->delimit_mode == fss_basic_read_delimit_mode_none || (data->delimit_depth && (data->delimit_mode == fss_basic_read_delimit_mode_depth || data->delimit_mode == fss_basic_read_delimit_mode_depth_greater)))) {
- data->option |= fss_basic_read_data_option_delimit;
- }
-
if (main->parameters[fss_basic_read_parameter_empty].result == f_console_result_found) {
data->option |= fss_basic_read_data_option_empty;
}
#endif
/**
+ * Determine if the given depth is to be delimited or not for an Object.
+ *
+ * @param depth
+ * The depth to check.
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_true if to apply delimits.
+ * F_false if to not apply delimits.
+ */
+#ifndef _di_fss_basic_read_delimit_object_is_
+ extern f_status_t fss_basic_read_delimit_object_is(const f_array_length_t depth, fss_basic_read_data_t * const data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_read_delimit_object_is_
+
+/**
* Process the parameters, parsing out and handling the depth and depth related parameters.
*
* Will handle depth-sensitive parameter conflicts, such as --name being used with --at (which is not allowed).
* The program data.
* @param at
* The index in the Objects and Contents to print.
- * @param delimits
- * The delimits in the objects and contents.
- *
- * This is a temporary parameter to be used until other structural changes are made and completed.
+ * @param delimits_object
+ * The delimits to be applied to an Object.
+ * @param delimits_content
+ * The delimits to be applied to Content.
*/
#ifndef _di_fss_basic_read_print_at_
- extern void fss_basic_read_print_at(fss_basic_read_main_t * const main, fss_basic_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits) f_attribute_visibility_internal;
+ extern void fss_basic_read_print_at(fss_basic_read_main_t * const main, fss_basic_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content) f_attribute_visibility_internal;
#endif // _di_fss_basic_read_print_at_
/**
- * Print the end of an object (which is essentially the start of a content).
+ * Print the end of an Object (which is essentially the start of a Content).
*
* @param main
* The program specific main.
#endif // _di_fss_basic_read_print_one_
/**
- * Print the end of an object/content set.
+ * Print the end of an Object/Content set.
*
* @param main
* The program specific main.