]> Kevux Git Server - fll/commitdiff
Update: Get FSS Basic List Read in sync with FSS Basic Read changes.
authorKevin Day <thekevinday@gmail.com>
Wed, 5 May 2021 05:22:23 +0000 (00:22 -0500)
committerKevin Day <thekevinday@gmail.com>
Wed, 5 May 2021 05:24:01 +0000 (00:24 -0500)
Apply all changes recently performed on FSS Basic Read as appropriate.

level_3/fss_basic_list_read/c/fss_basic_list_read.c
level_3/fss_basic_list_read/c/fss_basic_list_read.h
level_3/fss_basic_list_read/c/main.c
level_3/fss_basic_list_read/c/private-common.c
level_3/fss_basic_list_read/c/private-common.h
level_3/fss_basic_list_read/c/private-fss_basic_list_read.c
level_3/fss_basic_list_read/c/private-fss_basic_list_read.h

index 8bad606a0899e472dd04949982f0e6a9167a1a24..5bf946b70373f12f1ef82d154c829c4f3eaf9d0f 100644 (file)
@@ -23,18 +23,18 @@ extern "C" {
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_at, fss_basic_list_read_long_at, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "      Select object at this numeric index.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_content, fss_basic_list_read_long_content, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the content (default).");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_at, fss_basic_list_read_long_at, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "      Select Object at this numeric index.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_content, fss_basic_list_read_long_content, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
     fll_program_print_help_option(output, context, fss_basic_list_read_short_delimit, fss_basic_list_read_long_delimit, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_depth, fss_basic_list_read_long_depth, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "   Select object at this numeric depth.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_empty, fss_basic_list_read_long_empty, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "   Include empty content when processing.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_line, fss_basic_list_read_long_line, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Print only the content at the given line.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_name, fss_basic_list_read_long_name, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Select object with this name.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_object, fss_basic_list_read_long_object, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "  Print the object.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_depth, fss_basic_list_read_long_depth, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "   Select Object at this numeric depth.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_empty, fss_basic_list_read_long_empty, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "   Include empty Content when processing.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_line, fss_basic_list_read_long_line, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Print only the Content at the given line.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_name, fss_basic_list_read_long_name, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Select Object with this name.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_object, fss_basic_list_read_long_object, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "  Print the Object.");
     fll_program_print_help_option(output, context, fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Print using the special pipe format.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_select, fss_basic_list_read_long_select, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "  Select sub-content at this index.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_select, fss_basic_list_read_long_select, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "  Select sub-Content at this index.");
     fll_program_print_help_option(output, context, fss_basic_list_read_short_total, fss_basic_list_read_long_total, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "   Print the total number of lines.");
-    fll_program_print_help_option(output, context, fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Trim object names on select or print.");
+    fll_program_print_help_option(output, context, fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "    Trim Object names on select or print.");
 
     fll_program_print_help_usage(output, context, fss_basic_list_read_name, "filename(s)");
 
@@ -42,7 +42,12 @@ extern "C" {
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
-    fprintf(output.stream, "  This program will print the content associated with the given object and content main based on the FSS-0002 Basic List standard.%c", f_string_eol_s[0]);
+    fprintf(output.stream, "  This program will print the Content associated with the given Object and Content main based on the FSS-0002 Basic List standard.%c", f_string_eol_s[0]);
+
+    fprintf(output.stream, "%c", f_string_eol_s[0]);
+
+    fprintf(output.stream, "  All numeric positions (indexes) start at 0 instead of 1.%c", f_string_eol_s[0]);
+    fprintf(output.stream, "  For example, a file of 17 lines would range from 0 to 16.%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
@@ -54,7 +59,7 @@ extern "C" {
 
     fprintf(output.stream, "    ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_at);
-    fprintf(output.stream, ": An object index at the specified depth.%c", f_string_eol_s[0]);
+    fprintf(output.stream, ": An Object index at the specified depth.%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "    ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_depth);
@@ -62,7 +67,7 @@ extern "C" {
 
     fprintf(output.stream, "    ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_name);
-    fprintf(output.stream, ": An object name at the specified depth.%c", f_string_eol_s[0]);
+    fprintf(output.stream, ": An Object name at the specified depth.%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
@@ -76,8 +81,8 @@ extern "C" {
 
     fprintf(output.stream, "  The parameter ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_select);
-    fprintf(output.stream, " selects a content index at a given depth.%c", f_string_eol_s[0]);
-    fprintf(output.stream, "    (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol_s[0]);
+    fprintf(output.stream, " selects a Content index at a given depth.%c", f_string_eol_s[0]);
+    fprintf(output.stream, "    (This parameter is not synonymous with the depth parameter and does not relate to nested Content).%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
@@ -112,11 +117,11 @@ extern "C" {
 
     fprintf(output.stream, "  For parameters like ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_depth);
-    fprintf(output.stream, ", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol_s[0]);
+    fprintf(output.stream, ", if the standard doesn't support nested Content, then only a depth of 0 would be valid.%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "  For parameters like ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_select);
-    fprintf(output.stream, ", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol_s[0]);
+    fprintf(output.stream, ", if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
@@ -130,9 +135,9 @@ extern "C" {
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_object);
     fprintf(output.stream, " parameter and the ");
     f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_content);
-    fprintf(output.stream, " parameter, the entire object and content are printed, including the formatting.%c", f_string_eol_s[0]);
-    fprintf(output.stream, "  Both the object and content printed are already escaped.%c", f_string_eol_s[0]);
-    fprintf(output.stream, "  Both the object and content are separated by an EOL.%c", f_string_eol_s[0]);
+    fprintf(output.stream, " parameter, the entire Object and Content are printed, including the formatting.%c", f_string_eol_s[0]);
+    fprintf(output.stream, "  Both the Object and Content printed are already escaped.%c", f_string_eol_s[0]);
+    fprintf(output.stream, "  Both the Object and Content are separated by an EOL.%c", f_string_eol_s[0]);
 
     fprintf(output.stream, "%c", f_string_eol_s[0]);
 
@@ -144,14 +149,31 @@ extern "C" {
     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_list_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_list_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_list_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_list_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_list_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_list_read_long_delimit);
+    fprintf(output.stream, " values ");
+    f_color_print(output.stream, context.set.notable, "%s", fss_basic_list_read_delimit_mode_name_none);
+    fprintf(output.stream, " and ");
+    f_color_print(output.stream, context.set.notable, "%s", fss_basic_list_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]);
 
@@ -160,7 +182,8 @@ extern "C" {
 #endif // _di_fss_basic_list_read_print_help_
 
 #ifndef _di_fss_basic_list_read_main_
-  f_status_t fss_basic_list_read_main(const f_console_arguments_t arguments, fss_basic_list_read_main_t *main) {
+  f_status_t fss_basic_list_read_main(f_console_arguments_t * const arguments, fss_basic_list_read_main_t *main) {
+
     f_status_t status = F_none;
 
     {
@@ -170,7 +193,7 @@ extern "C" {
         f_console_parameter_id_t ids[3] = { fss_basic_list_read_parameter_no_color, fss_basic_list_read_parameter_light, fss_basic_list_read_parameter_dark };
         const f_console_parameter_ids_t choices = { ids, 3 };
 
-        status = fll_program_parameter_process(arguments, parameters, choices, F_true, &main->remaining, &main->context);
+        status = fll_program_parameter_process(*arguments, parameters, choices, F_true, &main->remaining, &main->context);
 
         if (main->context.set.error.before) {
           main->error.context = main->context.set.error;
@@ -184,6 +207,7 @@ extern "C" {
 
         if (F_status_is_error(status)) {
           fss_basic_list_read_main_delete(main);
+
           return F_status_set_error(status);
         }
       }
@@ -198,6 +222,7 @@ extern "C" {
 
         if (F_status_is_error(status)) {
           fss_basic_list_read_main_delete(main);
+
           return status;
         }
 
@@ -232,154 +257,207 @@ extern "C" {
       return status;
     }
 
-    if (main->remaining.used > 0 || main->process_pipe) {
-      if (main->parameters[fss_basic_list_read_parameter_at].result == f_console_result_found) {
-        f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_at);
-        f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]);
-
-        status = F_status_set_error(F_parameter);
-      }
-
-      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_found) {
-        f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_depth);
-        f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]);
-
-        status = F_status_set_error(F_parameter);
-      }
-
-      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) {
-        f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_line);
-        f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]);
+    // Provide a range designating where within the buffer a particular file exists, using a statically allocated array.
+    fss_basic_list_read_file_t files_array[main->remaining.used + 1];
+    fss_basic_list_read_data_t data = fss_basic_list_read_data_t_initialize;
 
-        status = F_status_set_error(F_parameter);
-      }
-
-      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) {
-        f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_name);
-        f_color_print(main->error.to.stream, main->context.set.error, "' requires a string.%c", f_string_eol_s[0]);
-
-        status = F_status_set_error(F_parameter);
-      }
+    data.files.array = files_array;
+    data.files.used = 1;
+    data.files.size = main->remaining.used + 1;
 
-      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) {
-        f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_select);
-        f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]);
+    if (main->remaining.used || main->process_pipe) {
+      {
+        const f_array_length_t parameter_code[] = {
+          fss_basic_list_read_parameter_at,
+          fss_basic_list_read_parameter_depth,
+          fss_basic_list_read_parameter_line,
+          fss_basic_list_read_parameter_select,
+          fss_basic_list_read_parameter_name,
+          fss_basic_list_read_parameter_delimit,
+        };
+
+        const f_string_t parameter_name[] = {
+          fss_basic_list_read_long_at,
+          fss_basic_list_read_long_depth,
+          fss_basic_list_read_long_line,
+          fss_basic_list_read_long_select,
+          fss_basic_list_read_long_name,
+          fss_basic_list_read_long_delimit,
+        };
+
+        const f_string_t message_positive_number = "positive number";
+        const f_string_t message_string = "string";
+        const f_string_t message_value = "value";
+
+        const f_string_t parameter_message[] = {
+          message_positive_number,
+          message_positive_number,
+          message_positive_number,
+          message_positive_number,
+          message_string,
+          message_value,
+        };
+
+        for (f_array_length_t i = 0; i < 6; ++i) {
+
+          if (main->parameters[parameter_code[i]].result == f_console_result_found) {
+            f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error);
+            f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, parameter_name[i]);
+            f_color_print(main->error.to.stream, main->context.set.error, "' requires a %s.%c", parameter_message[i], f_string_eol_s[0]);
 
-        status = F_status_set_error(F_parameter);
+            status = F_status_set_error(F_parameter);
+            break;
+          }
+        } // for
       }
 
-      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
+      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
         if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
           f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", 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_list_read_long_line);
+          f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_pipe);
           f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '");
           f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_total);
           f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]);
 
           status = F_status_set_error(F_parameter);
         }
-      }
-
-      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
-        if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
+        else if (main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) {
           f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", 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_list_read_long_pipe);
           f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '");
-          f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_total);
+          f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_line);
           f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]);
 
           status = F_status_set_error(F_parameter);
         }
       }
 
-      if (F_status_is_error_not(status)) {
-        if (main->parameters[fss_basic_list_read_parameter_delimit].result == f_console_result_found) {
-          f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_delimit);
-          f_color_print(main->error.to.stream, main->context.set.error, "' requires a value.%c", f_string_eol_s[0]);
+      if (F_status_is_error_not(status) && main->parameters[fss_basic_list_read_parameter_delimit].result == f_console_result_additional) {
+        f_array_length_t location = 0;
+        f_array_length_t length = 0;
 
-          status = F_status_set_error(F_parameter);
-        }
-        else if (main->parameters[fss_basic_list_read_parameter_delimit].result == f_console_result_additional) {
-          const f_array_length_t location = main->parameters[fss_basic_list_read_parameter_delimit].values.array[0];
-          f_array_length_t length = strnlen(arguments.argv[location], f_console_parameter_size);
+        // Set the value to 0 to allow for detecting mode based on what is provided.
+        data.delimit_mode = 0;
+
+        for (f_array_length_t i = 0; i < main->parameters[fss_basic_list_read_parameter_delimit].values.used; ++i) {
 
-          if (length == 0) {
+          location = main->parameters[fss_basic_list_read_parameter_delimit].values.array[i];
+          length = strnlen(arguments->argv[location], f_console_parameter_size);
+
+          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_list_read_long_delimit);
             f_color_print(main->error.to.stream, main->context.set.error, "' must not be empty.%c", f_string_eol_s[0]);
 
             status = F_status_set_error(F_parameter);
+            break;
           }
-          else if (fl_string_compare(arguments.argv[location], fss_basic_list_read_delimit_mode_name_none, length, fss_basic_list_read_delimit_mode_name_none_length) == F_equal_to) {
-            main->delimit_mode = fss_basic_list_read_delimit_mode_none;
+          else if (fl_string_compare(arguments->argv[location], fss_basic_list_read_delimit_mode_name_none, length, fss_basic_list_read_delimit_mode_name_none_length) == F_equal_to) {
+            data.delimit_mode = fss_basic_list_read_delimit_mode_none;
           }
-          else if (fl_string_compare(arguments.argv[location], fss_basic_list_read_delimit_mode_name_all, length, fss_basic_list_read_delimit_mode_name_all_length) == F_equal_to) {
-            main->delimit_mode = fss_basic_list_read_delimit_mode_all;
+          else if (fl_string_compare(arguments->argv[location], fss_basic_list_read_delimit_mode_name_all, length, fss_basic_list_read_delimit_mode_name_all_length) == F_equal_to) {
+            data.delimit_mode = fss_basic_list_read_delimit_mode_all;
+          }
+          else if (fl_string_compare(arguments->argv[location], fss_basic_list_read_delimit_mode_name_object, length, fss_basic_list_read_delimit_mode_name_object_length) == F_equal_to) {
+            switch (data.delimit_mode) {
+              case 0:
+                data.delimit_mode = fss_basic_list_read_delimit_mode_object;
+                break;
+
+              case fss_basic_list_read_delimit_mode_none:
+              case fss_basic_list_read_delimit_mode_all:
+              case fss_basic_list_read_delimit_mode_content_greater_object:
+              case fss_basic_list_read_delimit_mode_content_lesser_object:
+              case fss_basic_list_read_delimit_mode_object:
+                break;
+
+              case fss_basic_list_read_delimit_mode_content:
+                data.delimit_mode = fss_basic_list_read_delimit_mode_content_object;
+                break;
+
+              case fss_basic_list_read_delimit_mode_content_greater:
+                data.delimit_mode = fss_basic_list_read_delimit_mode_content_greater_object;
+                break;
+
+              case fss_basic_list_read_delimit_mode_content_lesser:
+                data.delimit_mode = fss_basic_list_read_delimit_mode_content_lesser_object;
+                break;
+
+              default:
+                break;
+            }
           }
           else {
-            main->delimit_mode = fss_basic_list_read_delimit_mode_depth;
+            if (!data.delimit_mode) {
+              data.delimit_mode = fss_basic_list_read_delimit_mode_content;
+            }
+            else if (data.delimit_mode == fss_basic_list_read_delimit_mode_object) {
+              data.delimit_mode = fss_basic_list_read_delimit_mode_content_object;
+            }
 
-            if (arguments.argv[location][length - 1] == fss_basic_list_read_delimit_mode_name_greater[0]) {
-              main->delimit_mode = fss_basic_list_read_delimit_mode_depth_greater;
+            if (arguments->argv[location][length - 1] == fss_basic_list_read_delimit_mode_name_greater[0]) {
+              if (!(data.delimit_mode == fss_basic_list_read_delimit_mode_none || data.delimit_mode == fss_basic_list_read_delimit_mode_all)) {
+                if (data.delimit_mode == fss_basic_list_read_delimit_mode_content_object) {
+                  data.delimit_mode = fss_basic_list_read_delimit_mode_content_greater_object;
+                }
+                else {
+                  data.delimit_mode = fss_basic_list_read_delimit_mode_content_greater;
+                }
+              }
 
               // shorten the length to better convert the remainder to a number.
-              length--;
+              --length;
             }
-            else if (arguments.argv[location][length - 1] == fss_basic_list_read_delimit_mode_name_lesser[0]) {
-              main->delimit_mode = fss_basic_list_read_delimit_mode_depth_lesser;
+            else if (arguments->argv[location][length - 1] == fss_basic_list_read_delimit_mode_name_lesser[0]) {
+              if (!(data.delimit_mode == fss_basic_list_read_delimit_mode_none || data.delimit_mode == fss_basic_list_read_delimit_mode_all)) {
+                if (data.delimit_mode == fss_basic_list_read_delimit_mode_content_object) {
+                  data.delimit_mode = fss_basic_list_read_delimit_mode_content_lesser_object;
+                }
+                else {
+                  data.delimit_mode = fss_basic_list_read_delimit_mode_content_lesser;
+                }
+              }
 
               // shorten the length to better convert the remainder to a number.
-              length--;
+              --length;
             }
 
             f_string_range_t range = macro_f_string_range_t_initialize(length);
 
             // ignore leading plus sign.
-            if (arguments.argv[location][0] == '+') {
-              range.start++;
+            if (arguments->argv[location][0] == '+') {
+              ++range.start;
             }
 
-            status = fl_conversion_string_to_number_unsigned(arguments.argv[location], range, &main->delimit_depth);
+            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_list_read_long_delimit, arguments.argv[location]);
+              fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_list_read_long_delimit, arguments->argv[location]);
+
+              break;
             }
           }
+        } // for
+
+        // Guarantee the default value is "all".
+        if (!data.delimit_mode) {
+          data.delimit_mode = fss_basic_list_read_delimit_mode_all;
         }
       }
 
-      fss_basic_list_read_depths_t depths = fss_basic_list_read_depths_t_initialize;
-
-      f_fss_delimits_t delimits = f_fss_delimits_t_initialize;
-      f_fss_comments_t comments = f_fss_comments_t_initialize;
-
-      f_array_length_t original_size = main->quantity.total;
-
       if (F_status_is_error_not(status)) {
-        status = fss_basic_list_read_main_preprocess_depth(arguments, *main, &depths);
-
-        if (F_status_is_error(status)) {
-          fll_error_print(main->error, F_status_set_fine(status), "fss_basic_list_read_main_preprocess_depth", F_true);
-        }
+        status = fss_basic_list_read_depth_process(arguments, main, &data);
       }
 
       // 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) && depths.array[0].depth > 0) {
-        macro_fss_basic_list_read_depths_t_delete_simple(depths);
-        macro_f_fss_delimits_t_delete_simple(delimits);
-        macro_f_fss_comments_t_delete_simple(comments);
-
+      if (F_status_is_error_not(status) && data.depths.array[0].depth > 0) {
         if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-          fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
+          fss_basic_list_read_print_zero(main);
         }
 
+        fss_basic_list_read_data_delete_simple(&data);
         fss_basic_list_read_main_delete(main);
+
         return F_none;
       }
 
@@ -388,106 +466,127 @@ extern "C" {
         f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_select);
         f_color_print(main->error.to.stream, main->context.set.error, "' parameter requires a positive number.%c", f_string_eol_s[0]);
 
+        fss_basic_list_read_depths_resize(0, &data.depths);
+
         status = F_status_set_error(F_parameter);
       }
 
+      if (F_status_is_error_not(status)) {
+        for (f_array_length_t i = 0; i < data.files.used; ++i) {
+          macro_f_string_range_t_clear(data.files.array[i].range);
+        } // for
+      }
+
       if (F_status_is_error_not(status) && main->process_pipe) {
         f_file_t file = f_file_t_initialize;
 
         file.id = f_type_descriptor_input;
+        file.stream = f_type_input;
+
+        data.files.array[0].name = 0;
+        data.files.array[0].range.start = 0;
 
-        status = f_file_read(file, &main->buffer);
+        status = f_file_stream_read(file, &data.buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(main->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe);
+          fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_read", F_true, "-", "read", fll_error_file_type_pipe);
         }
-        else {
-          status = fss_basic_list_read_main_process_file(arguments, main, "-", depths, &delimits, &comments);
+        else if (data.buffer.used) {
+          data.files.array[0].range.stop = data.buffer.used - 1;
+
+          // This standard is newline sensitive, when appending files to the buffer if the file lacks a final newline then this could break the format for files appended thereafter.
+          // Guarantee that a newline exists at the end of the buffer.
+          status = f_string_append_assure(f_string_eol_s, 1, &data.buffer);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(main->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe);
+            fll_error_file_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true, "-", "read", fll_error_file_type_pipe);
           }
         }
-
-        // Clear buffers before continuing.
-        macro_f_fss_contents_t_delete_simple(main->contents);
-        macro_f_fss_objects_t_delete_simple(main->objects);
-        macro_f_string_dynamic_t_delete_simple(main->buffer);
+        else {
+          data.files.array[0].range.start = 1;
+        }
       }
 
       if (F_status_is_error_not(status) && main->remaining.used > 0) {
-        for (f_array_length_t i = 0; i < main->remaining.used; i++) {
-          f_file_t file = f_file_t_initialize;
+        f_file_t file = f_file_t_initialize;
+        f_array_length_t size_file = 0;
+
+        for (f_array_length_t i = 0; i < main->remaining.used; ++i) {
 
-          status = f_file_open(arguments.argv[main->remaining.array[i]], 0, &file);
+          data.files.array[data.files.used].range.start = data.buffer.used;
+          file.stream = 0;
+          file.id = -1;
 
-          main->quantity.total = original_size;
+          status = f_file_stream_open(arguments->argv[main->remaining.array[i]], 0, &file);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(main->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[main->remaining.array[i]], "open", fll_error_file_type_file);
+            fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_open", F_true, arguments->argv[main->remaining.array[i]], "open", fll_error_file_type_file);
+
             break;
           }
 
-          if (!main->quantity.total) {
-            status = f_file_size_by_id(file.id, &main->quantity.total);
+          size_file = 0;
+          status = f_file_size_by_id(file.id, &size_file);
+
+          if (F_status_is_error(status)) {
+            fll_error_file_print(main->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments->argv[main->remaining.array[i]], "read", fll_error_file_type_file);
+
+            break;
+          }
+
+          if (size_file) {
+            status = f_string_dynamic_resize(data.buffer.size + size_file, &data.buffer);
 
             if (F_status_is_error(status)) {
-              fll_error_file_print(main->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[main->remaining.array[i]], "read", fll_error_file_type_file);
+              fll_error_file_print(main->error, F_status_set_fine(status), "f_string_dynamic_resize", F_true, arguments->argv[main->remaining.array[i]], "read", fll_error_file_type_file);
 
-              f_file_stream_close(F_true, &file);
               break;
             }
 
-            // Skip past empty files.
-            if (!main->quantity.total) {
-              if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-                fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
-              }
+            status = f_file_stream_read(file, &data.buffer);
 
-              f_file_stream_close(F_true, &file);
-              continue;
-            }
-          }
+            if (F_status_is_error(status)) {
+              fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_read", F_true, arguments->argv[main->remaining.array[i]], "read", fll_error_file_type_file);
 
-          status = f_file_read_until(file, main->quantity.total, &main->buffer);
+              break;
+            }
+            else if (data.buffer.used > data.files.array[data.files.used].range.start) {
+              data.files.array[data.files.used].name = arguments->argv[main->remaining.array[i]];
+              data.files.array[data.files.used++].range.stop = data.buffer.used - 1;
 
-          f_file_stream_close(F_true, &file);
+              // This standard is newline sensitive, when appending files to the buffer if the file lacks a final newline then this could break the format for files appended thereafter.
+              // Guarantee that a newline exists at the end of the buffer.
+              status = f_string_append_assure(f_string_eol_s, 1, &data.buffer);
 
-          if (F_status_is_error(status)) {
-            fll_error_file_print(main->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[main->remaining.array[i]], "read", fll_error_file_type_file);
-            break;
+              if (F_status_is_error(status)) {
+                fll_error_file_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true, "-", "read", fll_error_file_type_pipe);
+              }
+            }
           }
-
-          status = fss_basic_list_read_main_process_file(arguments, main, arguments.argv[main->remaining.array[i]], depths, &delimits, &comments);
-
-          if (F_status_is_error(status)) {
-            fll_error_file_print(main->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, arguments.argv[main->remaining.array[i]], "read", fll_error_file_type_file);
-            break;
+          else {
+            data.files.array[data.files.used].range.start = 1;
           }
 
-          // Clear buffers before repeating the loop.
-          macro_f_fss_contents_t_delete_simple(main->contents);
-          macro_f_fss_objects_t_delete_simple(main->objects);
-          macro_f_string_dynamic_t_delete_simple(main->buffer);
+          f_file_stream_close(F_true, &file);
         } // for
 
-        if (F_status_is_error(status)) {
-          macro_f_fss_contents_t_delete_simple(main->contents);
-          macro_f_fss_objects_t_delete_simple(main->objects);
-          macro_f_string_dynamic_t_delete_simple(main->buffer);
-        }
+        f_file_stream_close(F_true, &file);
       }
 
-      macro_fss_basic_list_read_depths_t_delete_simple(depths);
-      macro_f_fss_delimits_t_delete_simple(delimits);
-      macro_f_fss_comments_t_delete_simple(comments);
+      if (F_status_is_error_not(status)) {
+        status = fss_basic_list_read_process(arguments, main, &data);
+      }
+
+      fss_basic_list_read_data_delete_simple(&data);
     }
     else {
       f_color_print(main->error.to.stream, main->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol_s[0]);
       status = F_status_set_error(F_parameter);
     }
 
+    fss_basic_list_read_data_delete_simple(&data);
     fss_basic_list_read_main_delete(main);
+
     return status;
   }
 #endif // _di_fss_basic_list_read_main_
@@ -495,17 +594,13 @@ extern "C" {
 #ifndef _di_fss_basic_list_read_main_delete_
   f_status_t fss_basic_list_read_main_delete(fss_basic_list_read_main_t *main) {
 
-    for (f_array_length_t i = 0; i < fss_basic_list_read_total_parameters; i++) {
+    for (f_array_length_t i = 0; i < fss_basic_list_read_total_parameters; ++i) {
       macro_f_array_lengths_t_delete_simple(main->parameters[i].locations);
       macro_f_array_lengths_t_delete_simple(main->parameters[i].locations_sub);
       macro_f_array_lengths_t_delete_simple(main->parameters[i].values);
     } // for
 
-    macro_f_fss_contents_t_delete_simple(main->contents);
-    macro_f_fss_objects_t_delete_simple(main->objects);
-    macro_f_string_dynamic_t_delete_simple(main->buffer);
     macro_f_array_lengths_t_delete_simple(main->remaining);
-
     macro_f_color_context_t_delete_simple(main->context);
 
     return F_none;
index 7541f3616066a2f9ad011bf8a56c151034c82ac2..f89640e6596660a108a938cda2a9694832f70a5c 100644 (file)
@@ -145,23 +145,42 @@ extern "C" {
   #define fss_basic_list_read_total_parameters 21
 #endif // _di_fss_basic_list_read_defines_
 
+/**
+ * FSS Delimit Parameter data.
+ *
+ * fss_basic_list_read_delimit_mode_*:
+ *   - all:                    All delimits are to be aplied.
+ *   - content:                Content are to have delimits applied.
+ *   - content_greater:        Content at this number or higher are to have delimits applied.
+ *   - content_greater_object: Objects and Content at this number or higher are to have delimits applied.
+ *   - content_lesser:         Content at this number or lower are to have delimits applied.
+ *   - content_lesser_object:  Objects and Content at this number or lower are to have delimits applied.
+ *   - content_object:         Objects and Content are to have delimits applied
+ *   - object:                 Objects arre to have delimits applied.
+ */
 #ifndef _di_fss_basic_list_read_delimit_mode_
   #define fss_basic_list_read_delimit_mode_name_none    "none"
   #define fss_basic_list_read_delimit_mode_name_all     "all"
+  #define fss_basic_list_read_delimit_mode_name_object  "object"
   #define fss_basic_list_read_delimit_mode_name_greater "+"
   #define fss_basic_list_read_delimit_mode_name_lesser  "-"
 
   #define fss_basic_list_read_delimit_mode_name_none_length    4
   #define fss_basic_list_read_delimit_mode_name_all_length     3
+  #define fss_basic_list_read_delimit_mode_name_object_length  6
   #define fss_basic_list_read_delimit_mode_name_greater_length 1
   #define fss_basic_list_read_delimit_mode_name_lesser_length  1
 
   enum {
     fss_basic_list_read_delimit_mode_none = 1,
     fss_basic_list_read_delimit_mode_all,
-    fss_basic_list_read_delimit_mode_depth,
-    fss_basic_list_read_delimit_mode_depth_greater,
-    fss_basic_list_read_delimit_mode_depth_lesser,
+    fss_basic_list_read_delimit_mode_content,
+    fss_basic_list_read_delimit_mode_content_greater,
+    fss_basic_list_read_delimit_mode_content_greater_object,
+    fss_basic_list_read_delimit_mode_content_lesser,
+    fss_basic_list_read_delimit_mode_content_lesser_object,
+    fss_basic_list_read_delimit_mode_content_object,
+    fss_basic_list_read_delimit_mode_object,
   };
 #endif // _di_fss_basic_list_read_delimit_modes_
 
@@ -175,14 +194,6 @@ extern "C" {
     f_file_t output;
     fll_error_print_t error;
 
-    f_string_dynamic_t buffer;
-    f_fss_objects_t objects;
-    f_fss_contents_t contents;
-    f_string_quantity_t quantity;
-
-    uint8_t delimit_mode;
-    f_array_length_t delimit_depth;
-
     f_color_context_t context;
   } fss_basic_list_read_main_t;
 
@@ -193,12 +204,6 @@ extern "C" {
       F_false, \
       macro_f_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
       fll_error_print_t_initialize, \
-      f_string_dynamic_t_initialize, \
-      f_fss_objects_t_initialize, \
-      f_fss_contents_t_initialize, \
-      f_string_quantity_t_initialize, \
-      fss_basic_list_read_delimit_mode_all, \
-      0, \
       f_color_context_t_initialize, \
     }
 #endif // _di_fss_basic_list_read_main_t_
@@ -236,7 +241,7 @@ extern "C" {
  * @see fss_basic_list_read_main_delete()
  */
 #ifndef _di_fss_basic_list_read_main_
-  extern f_status_t fss_basic_list_read_main(const f_console_arguments_t arguments, fss_basic_list_read_main_t *main);
+  extern f_status_t fss_basic_list_read_main(f_console_arguments_t * const arguments, fss_basic_list_read_main_t *main);
 #endif // _di_fss_basic_list_read_main_
 
 /**
index c5196380512e7be39439398315f7d3214aef7725..a018dafd806a61f87c1010dcaf939efb24fb18c5 100644 (file)
@@ -2,14 +2,14 @@
 
 int main(const int argc, const f_string_t *argv) {
 
-  const f_console_arguments_t arguments = { argc, argv };
+  f_console_arguments_t arguments = { argc, argv };
   fss_basic_list_read_main_t data = fss_basic_list_read_main_t_initialize;
 
   if (f_pipe_input_exists()) {
     data.process_pipe = F_true;
   }
 
-  const f_status_t status = fss_basic_list_read_main(arguments, &data);
+  const f_status_t status = fss_basic_list_read_main(&arguments, &data);
 
   // flush output pipes before closing.
   fflush(f_type_output);
index 745408cf3007a299e5926638ce5a32c8a8c27a4e..8258046f7cb01def2cbc6d8f62a653d76b6e150a 100644 (file)
@@ -5,6 +5,59 @@
 extern "C" {
 #endif
 
+#ifndef _di_fss_basic_list_read_data_delete_simple_
+  void fss_basic_list_read_data_delete_simple(fss_basic_list_read_data_t *data) {
+
+    if (!data) return;
+
+    // data->files is expected to be statically loaded and cannot be deallocated.
+
+    fss_basic_list_read_depths_resize(0, &data->depths);
+
+    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_fss_delimits_t_delete_simple(data->delimits_object);
+    macro_f_fss_delimits_t_delete_simple(data->delimits_content);
+    macro_f_fss_comments_t_delete_simple(data->comments);
+  }
+#endif // _di_fss_basic_list_read_data_delete_simple_
+
+#ifndef _di_fss_basic_list_read_depth_delete_simple_
+  void fss_basic_list_read_depth_delete_simple(fss_basic_list_read_depth_t *depth) {
+
+    if (!depth) return;
+
+    f_string_dynamic_resize(0, &depth->value_name);
+  }
+#endif // _di_fss_basic_list_read_depth_delete_simple_
+
+#ifndef _di_fss_basic_list_read_depths_resize_
+  f_status_t fss_basic_list_read_depths_resize(const f_array_length_t length, fss_basic_list_read_depths_t *depths) {
+
+    if (!depths) {
+      return F_status_set_error(F_parameter);
+    }
+
+    for (f_array_length_t i = length; i < depths->size; ++i) {
+      fss_basic_list_read_depth_delete_simple(&depths->array[i]);
+    } // for
+
+    const f_status_t status = f_memory_resize(depths->size, length, sizeof(fss_basic_list_read_depth_t), (void **) & depths->array);
+
+    if (F_status_is_error_not(status)) {
+      depths->size = length;
+
+      if (depths->used > depths->size) {
+        depths->used = length;
+      }
+    }
+
+    return status;
+  }
+#endif // _di_fss_basic_list_read_depths_resize_
+
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 93ad6b7757130d8b5d44dc0cff81ce9a7768de8b..692ae8a6675988433a84100cbbd748ff8d7454c6 100644 (file)
@@ -15,13 +15,13 @@ extern "C" {
 /**
  * A structure of parameters applied at some depth.
  *
- * depth: the depth number in which this is to be processed at.
+ * depth: The depth number in which this is to be processed at.
  *
- * index_at: position of the "--at" parameter value in the argv list, when 0 there is no parameter.
- * index_name: position of the "--name" parameter value in the argv list, when 0 there is no parameter.
+ * index_at:   Position of the "--at" parameter value in the argv list, when 0 there is no parameter.
+ * index_name: Position of the "--name" parameter value in the argv list, when 0 there is no parameter.
  *
- * value_at: the value of the "--at" parameter, already processed and ready to use, only when index_at > 0.
- * value_name: the value of the "--name" parameter, already processed and ready to use, only when index_name > 0.
+ * value_at:   The value of the "--at" parameter, already processed and ready to use, only when index_at > 0.
+ * value_name: The value of the "--name" parameter, already processed and ready to use, only when index_name > 0.
  */
 #ifndef _di_fss_basic_list_read_depth_t_
   typedef struct {
@@ -49,16 +49,14 @@ extern "C" {
     structure.index_name = 0; \
     structure.value_at = 0; \
     macro_f_string_dynamic_t_clear(structure.value_name)
-
-  #define macro_fss_basic_list_read_depth_t_delete_simple(structure)  macro_f_string_dynamic_t_delete_simple(structure.value_name);
 #endif // _di_fss_basic_list_read_depth_t_
 
 /**
  * An array of depth parameters.
  *
- * array: the array of depths.
- * size: total amount of allocated space.
- * used: total number of allocated spaces used.
+ * array: The array of depths.
+ * size:  Total amount of allocated space.
+ * used:  Total number of allocated spaces used.
  */
 #ifndef _di_fss_basic_list_read_depths_t_
   typedef struct {
@@ -71,43 +69,166 @@ extern "C" {
   #define fss_basic_list_read_depths_t_initialize { 0, 0, 0 }
 
   #define macro_fss_basic_list_read_depths_t_clear(depths) macro_f_memory_structure_clear(depths)
+#endif // _di_fss_basic_list_read_depths_t_
+
+/**
+ * A structure for designating where within the buffer a particular file exists, using a statically allocated array.
+ *
+ * name:  The name of the file representing the range. Set string to NULL to represent the STDIN pipe.
+ * range: A range within the buffer representing the file.
+ */
+#ifndef _di_fss_basic_list_read_file_t_
+  typedef struct {
+    f_string_t name;
+    f_string_range_t range;
+  } fss_basic_list_read_file_t;
 
-  #define macro_fss_basic_list_read_depths_t_delete_simple(depths) \
-    depths.used = depths.size; \
-    while (depths.used > 0) { \
-      depths.used--; \
-      macro_fss_basic_list_read_depth_t_delete_simple(depths.array[depths.used]); \
-    } \
-    if (!depths.used) macro_f_memory_structure_delete_simple(depths, fss_basic_list_read_depth_t)
-
-  #define macro_fss_basic_list_read_depths_t_resize(status, depths, new_length) \
-    status = F_none; \
-    if (new_length < depths.size) { \
-      f_array_length_t i = depths.size - new_length; \
-      for (; i < depths.size; i++) { \
-        macro_fss_basic_list_read_depth_t_delete_simple(depths.array[i]); \
-      } \
-    } \
-    if (status == F_none) status = f_memory_resize(depths.size, new_length, sizeof(fss_basic_list_read_depth_t), (void **) & depths.array); \
-    if (status == F_none) { \
-      depths.size = new_length; \
-      if (depths.used > depths.size) depths.used = new_length; \
+  #define fss_basic_list_read_file_t_initialize \
+    { \
+      f_string_t_initialize, \
+      f_string_range_t_initialize, \
     }
+#endif // _di_fss_basic_list_read_file_t_
 
-  #define macro_fss_basic_list_read_depths_t_adjust(status, depths, new_length) \
-    status = F_none; \
-    if (new_length < depths.size) { \
-      f_array_length_t i = depths.size - new_length; \
-      for (; i < depths.size; i++) { \
-        macro_fss_basic_list_read_depth_t_delete_simple(depths.array[i]); \
-      } \
-    } \
-    if (status == F_none) status = f_memory_adjust(depths.size, new_length, sizeof(fss_basic_list_read_depth_t), (void **) & depths.array); \
-    if (status == F_none) { \
-      depths.size = new_length; \
-      if (depths.used > depths.size) depths.used = new_length; \
+/**
+ * An array of files.
+ *
+ * This is intended to be defined and used statically allocated and as such no dynamic allocation or dynamic deallocation methods are provided.
+ *
+ * The STDIN pipe is reserved for index 0 and as such size and used must be initialized to 1.
+ *
+ * array: The array of depths.
+ * size:  Total amount of allocated space.
+ * used:  Total number of allocated spaces used.
+ */
+#ifndef _di_fss_basic_list_read_files_t_
+  typedef struct {
+    fss_basic_list_read_file_t *array;
+
+    f_array_length_t size;
+    f_array_length_t used;
+  } fss_basic_list_read_files_t;
+
+  #define fss_basic_list_read_files_t_initialize { 0, 1, 1 }
+#endif // _di_fss_basic_list_read_files_t_
+
+/**
+ * The data structure for FSS Basic Read.
+ *
+ * fss_basic_list_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.
+ *   - 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.
+ *   - object:  The Object is to be printed.
+ *   - select:  A specific Content at a given position is to be selected (Think of this as select a column for some Content).
+ *   - total:   The total lines found and selected is printed instead of the Content.
+ *   - trim:    Empty space before and after Objects and Content will not be printed (They will be trimmed).
+ *
+ * options:          Bitwise flags representing parameters.
+ * delimit_mode:     The delimit mode.
+ * delimit_depth:    The delimit depth.
+ * select:           The Content to select (column number).
+ * line:             The Content to select (row number).
+ * files:            A statically allocated array of files for designating where in the buffer a file is represented.
+ * depths:           The array of parameters for each given depth.
+ * buffer:           The buffer containing all loaded files (and STDIN pipe).
+ * objects:          The positions within the buffer representing Objects.
+ * contents:         The positions within the buffer representing Contents.
+ * delimits_object:  The positions within the buffer representing Object character delimits.
+ * delimits_content: The positions within the buffer representing Content character delimits.
+ */
+#ifndef _di_fss_basic_list_read_data_t_
+  #define fss_basic_list_read_data_option_at      0x1
+  #define fss_basic_list_read_data_option_content 0x2
+  #define fss_basic_list_read_data_option_empty   0x4
+  #define fss_basic_list_read_data_option_line    0x8
+  #define fss_basic_list_read_data_option_name    0x10
+  #define fss_basic_list_read_data_option_object  0x20
+  #define fss_basic_list_read_data_option_select  0x40
+  #define fss_basic_list_read_data_option_total   0x80
+  #define fss_basic_list_read_data_option_trim    0x100
+
+  typedef struct {
+    uint16_t option;
+    uint8_t delimit_mode;
+    f_array_length_t delimit_depth;
+    f_number_unsigned_t select;
+    f_number_unsigned_t line;
+
+    fss_basic_list_read_files_t files;
+    fss_basic_list_read_depths_t depths;
+
+    f_string_dynamic_t buffer;
+    f_fss_objects_t objects;
+    f_fss_contents_t contents;
+    f_fss_delimits_t delimits_object;
+    f_fss_delimits_t delimits_content;
+    f_fss_comments_t comments;
+  } fss_basic_list_read_data_t;
+
+  #define fss_basic_list_read_data_t_initialize \
+    { \
+      0, \
+      fss_basic_list_read_delimit_mode_all, \
+      0, \
+      0, \
+      0, \
+      fss_basic_list_read_files_t_initialize, \
+      fss_basic_list_read_depths_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_fss_objects_t_initialize, \
+      f_fss_contents_t_initialize, \
+      f_fss_delimits_t_initialize, \
+      f_fss_delimits_t_initialize, \
+      f_fss_comments_t_initialize, \
     }
-#endif // _di_fss_basic_list_read_depths_t_
+#endif // _di_fss_basic_list_read_data_t_
+
+/**
+ * Fully deallocate all memory for the given data without caring about return status.
+ *
+ * @param data
+ *   The data to deallocate.
+ */
+#ifndef _di_fss_basic_list_read_data_delete_simple_
+  extern void fss_basic_list_read_data_delete_simple(fss_basic_list_read_data_t *daa) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_data_delete_simple_
+
+/**
+ * Fully deallocate all memory for the given depth without caring about return status.
+ *
+ * @param depth
+ *   The depth to deallocate.
+ */
+#ifndef _di_fss_basic_list_read_depth_delete_simple_
+  extern void fss_basic_list_read_depth_delete_simple(fss_basic_list_read_depth_t *depth) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_depth_delete_simple_
+
+/**
+ * Resize the depth array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param depths
+ *   The depth array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ *   Errors (with error bit) from: fss_basic_list_read_depths_increase().
+ *
+ * @see f_memory_resize()
+ *
+ * @see fss_basic_list_read_depth_delete_simple()
+ * @see fss_basic_list_read_depths_increase()
+ */
+#ifndef _di_fss_basic_list_read_depths_resize_
+  extern f_status_t fss_basic_list_read_depths_resize(const f_array_length_t length, fss_basic_list_read_depths_t *depths) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_depths_resize_
 
 #ifdef __cplusplus
 } // extern "C"
index 8b70e6ef81c66fa43ff4259657d03712d532efb3..a659303924899e5e8ec62d535e7a72b843b92c78 100644 (file)
 extern "C" {
 #endif
 
-#ifndef _di_fss_basic_list_read_main_preprocess_depth_
-  f_status_t fss_basic_list_read_main_preprocess_depth(const f_console_arguments_t arguments, const fss_basic_list_read_main_t main, fss_basic_list_read_depths_t *depths) {
+#ifndef _di_fss_basic_list_read_delimit_content_is_
+  f_status_t fss_basic_list_read_delimit_content_is(const f_array_length_t depth, fss_basic_list_read_data_t * const data) {
+
+    if (data->delimit_mode == fss_basic_list_read_delimit_mode_none) {
+      return F_false;
+    }
+
+    if (data->delimit_mode == fss_basic_list_read_delimit_mode_all) {
+      return F_true;
+    }
+
+    if (depth < data->delimit_depth) {
+      return data->delimit_mode == fss_basic_list_read_delimit_mode_content_lesser;
+    }
+
+    if (depth == data->delimit_depth) {
+      return F_true;
+    }
+
+    return data->delimit_mode == fss_basic_list_read_delimit_mode_content_greater;
+  }
+#endif // _di_fss_basic_list_read_delimit_content_is_
+
+#ifndef _di_fss_basic_list_read_delimit_object_is_
+  f_status_t fss_basic_list_read_delimit_object_is(const f_array_length_t depth, fss_basic_list_read_data_t * const data) {
+
+    switch (data->delimit_mode) {
+      case fss_basic_list_read_delimit_mode_none:
+      case fss_basic_list_read_delimit_mode_content:
+      case fss_basic_list_read_delimit_mode_content_greater:
+      case fss_basic_list_read_delimit_mode_content_lesser:
+        return F_false;
+
+      case fss_basic_list_read_delimit_mode_all:
+      case fss_basic_list_read_delimit_mode_content_object:
+      case fss_basic_list_read_delimit_mode_content_greater_object:
+      case fss_basic_list_read_delimit_mode_content_lesser_object:
+      case fss_basic_list_read_delimit_mode_object:
+        return F_true;
+
+      default:
+        break;
+    }
+
+    return depth == data->delimit_depth || data->delimit_mode == fss_basic_list_read_delimit_mode_content_lesser;
+  }
+#endif // _di_fss_basic_list_read_delimit_object_is_
+
+#ifndef _di_fss_basic_list_read_depth_process_
+  f_status_t fss_basic_list_read_depth_process(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) {
+
     f_status_t status = F_none;
 
     {
       f_array_length_t depth_size = 1;
 
-      if (main.parameters[fss_basic_list_read_parameter_depth].result == f_console_result_additional) {
-        depth_size = main.parameters[fss_basic_list_read_parameter_depth].values.used;
+      if (main->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_additional) {
+        depth_size = main->parameters[fss_basic_list_read_parameter_depth].values.used;
       }
 
-      macro_fss_basic_list_read_depths_t_resize(status, (*depths), depth_size);
+      if (depth_size > data->depths.size) {
+        status = fss_basic_list_read_depths_resize(depth_size, &data->depths);
 
-      if (F_status_is_error(status)) {
-        f_color_print(main.error.to.stream, main.context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol_s[0]);
-        return status;
+        if (F_status_is_error(status)) {
+          fll_error_print(main->error, F_status_set_fine(status), "fss_basic_list_read_depths_resize", F_true);
+
+          return status;
+        }
       }
 
-      depths->used = depth_size;
+      data->depths.used = depth_size;
     }
 
     f_array_length_t position_depth = 0;
     f_array_length_t position_at = 0;
     f_array_length_t position_name = 0;
 
-    for (f_array_length_t i = 0; i < depths->used; i++) {
-      depths->array[i].depth = 0;
-      depths->array[i].index_at = 0;
-      depths->array[i].index_name = 0;
-      depths->array[i].value_at = 0;
+    for (f_array_length_t i = 0; i < data->depths.used; ++i) {
+
+      data->depths.array[i].depth = 0;
+      data->depths.array[i].index_at = 0;
+      data->depths.array[i].index_name = 0;
+      data->depths.array[i].value_at = 0;
 
-      macro_f_string_dynamic_t_clear(depths->array[i].value_name);
+      macro_f_string_dynamic_t_clear(data->depths.array[i].value_name);
 
-      if (!main.parameters[fss_basic_list_read_parameter_depth].values.used) {
+      if (!main->parameters[fss_basic_list_read_parameter_depth].values.used) {
         position_depth = 0;
       }
       else {
-        position_depth = main.parameters[fss_basic_list_read_parameter_depth].values.array[i];
+        position_depth = main->parameters[fss_basic_list_read_parameter_depth].values.array[i];
 
-        const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments.argv[position_depth]));
+        const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments->argv[position_depth]));
 
-        status = fl_conversion_string_to_number_unsigned(arguments.argv[position_depth], range, &depths->array[i].depth);
+        status = fl_conversion_string_to_number_unsigned(arguments->argv[position_depth], range, &data->depths.array[i].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_list_read_long_depth, arguments.argv[position_depth]);
+          fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_list_read_long_depth, arguments->argv[position_depth]);
+
           return status;
         }
       }
 
-      if (main.parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) {
-        for (; position_at < main.parameters[fss_basic_list_read_parameter_at].values.used; position_at++) {
+      if (main->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) {
+        for (; position_at < main->parameters[fss_basic_list_read_parameter_at].values.used; ++position_at) {
 
-          if (main.parameters[fss_basic_list_read_parameter_at].values.array[position_at] < position_depth) {
+          if (main->parameters[fss_basic_list_read_parameter_at].values.array[position_at] < position_depth) {
             continue;
           }
 
-          if (i + 1 < depths->used && main.parameters[fss_basic_list_read_parameter_at].values.array[position_at] > main.parameters[fss_basic_list_read_parameter_depth].values.array[i + 1]) {
+          if (i + 1 < data->depths.used && main->parameters[fss_basic_list_read_parameter_at].values.array[position_at] > main->parameters[fss_basic_list_read_parameter_depth].values.array[i + 1]) {
             break;
           }
 
-          depths->array[i].index_at = main.parameters[fss_basic_list_read_parameter_at].values.array[position_at];
+          data->depths.array[i].index_at = main->parameters[fss_basic_list_read_parameter_at].values.array[position_at];
 
-          const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments.argv[depths->array[i].index_at]));
+          const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments->argv[data->depths.array[i].index_at]));
 
-          status = fl_conversion_string_to_number_unsigned(arguments.argv[depths->array[i].index_at], range, &depths->array[i].value_at);
+          status = fl_conversion_string_to_number_unsigned(arguments->argv[data->depths.array[i].index_at], range, &data->depths.array[i].value_at);
 
           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_list_read_long_at, arguments.argv[depths->array[i].index_at]);
+            fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_list_read_long_at, arguments->argv[data->depths.array[i].index_at]);
+
             return status;
           }
         } // for
       }
 
-      if (main.parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) {
-        for (; position_name < main.parameters[fss_basic_list_read_parameter_name].values.used; position_name++) {
+      if (main->parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) {
+        for (; position_name < main->parameters[fss_basic_list_read_parameter_name].values.used; position_name++) {
 
-          if (main.parameters[fss_basic_list_read_parameter_name].values.array[position_name] < position_depth) {
+          if (main->parameters[fss_basic_list_read_parameter_name].values.array[position_name] < position_depth) {
             continue;
           }
 
-          if (i + 1 < depths->used && main.parameters[fss_basic_list_read_parameter_name].values.array[position_name] > main.parameters[fss_basic_list_read_parameter_depth].values.array[i + 1]) {
+          if (i + 1 < data->depths.used && main->parameters[fss_basic_list_read_parameter_name].values.array[position_name] > main->parameters[fss_basic_list_read_parameter_depth].values.array[i + 1]) {
             break;
           }
 
-          depths->array[i].index_name = main.parameters[fss_basic_list_read_parameter_name].values.array[position_name];
+          data->depths.array[i].index_name = main->parameters[fss_basic_list_read_parameter_name].values.array[position_name];
 
-          if (main.parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) {
-            status = fl_string_rip(arguments.argv[depths->array[i].index_name], strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name);
+          if (main->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) {
+            status = fl_string_rip(arguments->argv[data->depths.array[i].index_name], strlen(arguments->argv[data->depths.array[i].index_name]), &data->depths.array[i].value_name);
           }
           else {
-            status = f_string_append(arguments.argv[depths->array[i].index_name], strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name);
+            status = f_string_append(arguments->argv[data->depths.array[i].index_name], strlen(arguments->argv[data->depths.array[i].index_name]), &data->depths.array[i].value_name);
           }
 
           if (F_status_is_error(status)) {
-            f_status_t status_code = F_status_set_fine(status);
-
-            // @todo: move error printing into common function.
-            if (status_code == F_memory_not) {
-              f_color_print(main.error.to.stream, main.context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol_s[0]);
-            }
-            else if (status_code == F_string_too_large) {
-              f_color_print(main.error.to.stream, main.context.set.error, "%sUnable to process '", 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_list_read_long_trim);
-              f_color_print(main.error.to.stream, main.context.set.error, "' because the maximum buffer size was reached.%c", f_string_eol_s[0]);
-            }
-            else {
-              f_string_t function = "f_string_append";
-
-              if (main.parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) {
-                function = "fl_string_rip";
-              }
-
-              f_color_print(main.error.to.stream, main.context.set.error, "%sAn unhandled error (", fll_error_print_error);
-              f_color_print(main.error.to.stream, main.context.set.notable, "%u", status_code);
-              f_color_print(main.error.to.stream, main.context.set.error, ") has occurred while calling ");
-              f_color_print(main.error.to.stream, main.context.set.notable, "%s()", function);
-              f_color_print(main.error.to.stream, main.context.set.error, ".%c", f_string_eol_s[0]);
-            }
+            fll_error_print(main->error, F_status_set_fine(status), main->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found ? "fl_string_rip" : "f_string_append", F_true);
 
             return status;
           }
 
-          if (!depths->array[i].value_name.used) {
-            f_color_print(main.error.to.stream, main.context.set.error, "%sThe '", 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_list_read_long_name);
-            f_color_print(main.error.to.stream, main.context.set.error, "' must not be an empty string.%c", f_string_eol_s[0]);
+          if (!data->depths.array[i].value_name.used) {
+            if (main->error.verbosity != f_console_verbosity_quiet) {
+              f_color_print(main->error.to.stream, main->context.set.error, "%sThe '", 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_list_read_long_name);
+              f_color_print(main->error.to.stream, main->context.set.error, "' must not be an empty string.%c", f_string_eol_s[0]);
+            }
 
             return F_status_set_error(F_parameter);
           }
@@ -139,27 +173,31 @@ extern "C" {
       }
     } // for
 
-    for (f_array_length_t i = 0; i < depths->used; i++) {
+    for (f_array_length_t i = 0; i < data->depths.used; ++i) {
 
-      for (f_array_length_t j = i + 1; j < depths->used; j++) {
+      for (f_array_length_t j = i + 1; j < data->depths.used; ++j) {
 
-        if (depths->array[i].depth == depths->array[j].depth) {
-          f_color_print(main.error.to.stream, main.context.set.error, "%sThe value '", fll_error_print_error);
-          f_color_print(main.error.to.stream, main.context.set.notable, "%llu", depths->array[i].depth);
-          f_color_print(main.error.to.stream, main.context.set.error, "' may only be specified once for the parameter '");
-          f_color_print(main.error.to.stream, main.context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_depth);
-          f_color_print(main.error.to.stream, main.context.set.error, "'.%c", f_string_eol_s[0]);
+        if (data->depths.array[i].depth == data->depths.array[j].depth) {
+          if (main->error.verbosity != f_console_verbosity_quiet) {
+            f_color_print(main->error.to.stream, main->context.set.error, "%sThe value '", fll_error_print_error);
+            f_color_print(main->error.to.stream, main->context.set.notable, "%llu", data->depths.array[i].depth);
+            f_color_print(main->error.to.stream, main->context.set.error, "' may only be specified once for the parameter '");
+            f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_list_read_long_depth);
+            f_color_print(main->error.to.stream, main->context.set.error, "'.%c", f_string_eol_s[0]);
+          }
 
           return F_status_set_error(F_parameter);
         }
-        else if (depths->array[i].depth > depths->array[j].depth) {
-          f_color_print(main.error.to.stream, main.context.set.error, "%sThe 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_list_read_long_depth);
-          f_color_print(main.error.to.stream, main.context.set.error, "' may not have the value '");
-          f_color_print(main.error.to.stream, main.context.set.notable, "%llu", depths->array[i].depth);
-          f_color_print(main.error.to.stream, main.context.set.error, "' before the value '");
-          f_color_print(main.error.to.stream, main.context.set.notable, "%llu", depths->array[j].depth);
-          f_color_print(main.error.to.stream, main.context.set.error, "'.%c", f_string_eol_s[0]);
+        else if (data->depths.array[i].depth > data->depths.array[j].depth) {
+          if (main->error.verbosity != f_console_verbosity_quiet) {
+            f_color_print(main->error.to.stream, main->context.set.error, "%sThe 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_list_read_long_depth);
+            f_color_print(main->error.to.stream, main->context.set.error, "' may not have the value '");
+            f_color_print(main->error.to.stream, main->context.set.notable, "%llu", data->depths.array[i].depth);
+            f_color_print(main->error.to.stream, main->context.set.error, "' before the value '");
+            f_color_print(main->error.to.stream, main->context.set.notable, "%llu", data->depths.array[j].depth);
+            f_color_print(main->error.to.stream, main->context.set.error, "'.%c", f_string_eol_s[0]);
+          }
 
           return F_status_set_error(F_parameter);
         }
@@ -168,480 +206,547 @@ extern "C" {
 
     return F_none;
   }
-#endif // _di_fss_basic_list_read_main_preprocess_depth_
-
-#ifndef _di_fss_basic_list_read_main_process_file_
-  f_status_t fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_main_t *main, const f_string_t filename, const fss_basic_list_read_depths_t depths, f_fss_delimits_t *delimits, f_fss_comments_t *comments) {
-    f_status_t status = F_none;
+#endif // _di_fss_basic_list_read_depth_process_
 
-    const f_array_lengths_t except_none = f_array_lengths_t_initialize;
-    bool delimited = F_true;
+#ifndef _di_fss_basic_list_read_file_identify_
+  f_string_t fss_basic_list_read_file_identify(const f_array_length_t at, const fss_basic_list_read_files_t files) {
 
-    // for this standard, delimits would always be applied, except for when delimit_depth is greater than 0.
-    if (main->delimit_mode == fss_basic_list_read_delimit_mode_none || (main->delimit_depth && (main->delimit_mode == fss_basic_list_read_delimit_mode_depth || main->delimit_mode == fss_basic_list_read_delimit_mode_depth_greater))) {
-      delimited = F_false;
-    }
+    for (f_array_length_t i = 0; i < files.used; ++i) {
 
-    {
-      f_string_range_t input = macro_f_string_range_t_initialize(main->buffer.used);
+      if (at >= files.array[i].range.start && at <= files.array[i].range.stop) {
+        return files.array[i].name;
+      }
+    } // for
 
-      delimits->used = 0;
-      comments->used = 0;
+    return "";
+  }
+#endif // _di_fss_basic_list_read_file_identify_
 
-      status = fll_fss_basic_list_read(main->buffer, &input, &main->objects, &main->contents, delimits, 0, comments);
+#ifndef _di_fss_basic_list_read_load_number_
+  f_status_t fss_basic_list_read_load_number(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, const f_array_length_t parameter, const f_string_t name, f_number_unsigned_t *number) {
 
-      if (F_status_is_error(status)) {
-        // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate.
-        fll_error_file_print(main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, filename, "process", fll_error_file_type_file);
-      }
-      else if (status == F_data_not_stop || status == F_data_not_eos) {
-        macro_f_fss_contents_t_delete_simple(main->contents);
-        macro_f_fss_objects_t_delete_simple(main->objects);
-        macro_f_string_dynamic_t_delete_simple(main->buffer);
-
-        if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-          fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
-          return F_none;
-        }
+    if (main->parameters[parameter].result == f_console_result_additional) {
+      const f_array_length_t index = main->parameters[parameter].values.array[main->parameters[parameter].values.used - 1];
+      const f_string_range_t range = macro_f_string_range_t_initialize(strnlen(arguments->argv[index], f_console_parameter_size));
 
-        return F_status_set_warning(status);
-      }
+      const f_status_t status = fl_conversion_string_to_number_unsigned(arguments->argv[index], range, number);
 
       if (F_status_is_error(status)) {
-        macro_f_fss_contents_t_delete_simple(main->contents);
-        macro_f_fss_objects_t_delete_simple(main->objects);
-        macro_f_string_dynamic_t_delete_simple(main->buffer);
+        fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, name, arguments->argv[index]);
 
         return status;
       }
 
-      f_array_length_t i = 0;
-      f_array_length_t j = 0;
-
-      // comments are not to be part of the file, so remove them.
-      for (; i < comments->used; ++i) {
-        for (j = comments->array[i].start; j <= comments->array[i].stop; ++j) {
-          main->buffer.string[j] = f_fss_delimit_placeholder;
-        } // for
-      } // for
+      return F_true;
     }
 
-    f_number_unsigned_t select = 0;
+    return F_false;
+  }
+#endif // _di_fss_basic_list_read_load_number_
 
-    if (main->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) {
-      const f_array_length_t index = main->parameters[fss_basic_list_read_parameter_select].values.array[main->parameters[fss_basic_list_read_parameter_select].values.used - 1];
-      const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments.argv[index]));
+#ifndef _di_fss_basic_list_read_print_at_
+  void fss_basic_list_read_print_at(fss_basic_list_read_main_t * const main, fss_basic_list_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) {
 
-      status = fl_conversion_string_to_number_unsigned(arguments.argv[index], range, &select);
+    if (at >= data->contents.used) {
+      return;
+    }
 
-      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_list_read_long_select, arguments.argv[index]);
-        return status;
+    if ((data->option & fss_basic_list_read_data_option_object) || (data->option & fss_basic_list_read_data_option_content) && (data->contents.array[at].used || (data->option & fss_basic_list_read_data_option_empty))) {
+      if (data->option & fss_basic_list_read_data_option_object) {
+        if (data->option & fss_basic_list_read_data_option_trim) {
+          fl_print_trim_except_dynamic_partial(main->output.stream, data->buffer, data->objects.array[at], delimits_object);
+        }
+        else {
+          f_print_except_dynamic_partial(main->output.stream, data->buffer, data->objects.array[at], delimits_object);
+        }
+
+        fss_basic_list_read_print_object_end(main);
       }
 
-      // This standard does not support multiple content groups.
-      if (select > 0) {
-        return F_none;
+      if (data->option & fss_basic_list_read_data_option_content) {
+        if (data->contents.array[at].used) {
+          fss_basic_list_read_print_content_ignore(main);
+          f_print_except_dynamic_partial(main->output.stream, data->buffer, data->contents.array[at].array[0], delimits_content);
+          fss_basic_list_read_print_content_ignore(main);
+        }
       }
-    }
 
-    f_array_length_t line = 0;
+      fss_basic_list_read_print_set_end(main);
+    }
+  }
+#endif // _di_fss_basic_list_read_print_at_
 
-    if (main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
-      const f_array_length_t index = main->parameters[fss_basic_list_read_parameter_line].values.array[main->parameters[fss_basic_list_read_parameter_line].values.used - 1];
-      const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments.argv[index]));
+#ifndef _di_fss_basic_list_read_print_at_object_
+  void fss_basic_list_read_print_at_object(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) {
 
-      status = fl_conversion_string_to_number_unsigned(arguments.argv[index], range, &line);
+    if (at >= data->objects.used) {
+      return;
+    }
 
-      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_list_read_long_line, arguments.argv[index]);
-        return status;
-      }
+    if (data->option & fss_basic_list_read_data_option_trim) {
+      fl_print_trim_except_dynamic_partial(main->output.stream, data->buffer, data->objects.array[at], delimits_object);
+    }
+    else {
+      f_print_except_dynamic_partial(main->output.stream, data->buffer, data->objects.array[at], delimits_object);
     }
 
-    bool names[main->objects.used];
+    fss_basic_list_read_print_object_end(main);
+  }
+#endif // _di_fss_basic_list_read_print_at_object_
 
-    f_array_length_t i = 0;
-    f_array_length_t j = 0;
+#ifndef _di_fss_basic_list_read_print_content_end_
+  void fss_basic_list_read_print_content_end(fss_basic_list_read_main_t * const main) {
 
-    if (depths.array[0].index_name > 0) {
-      memset(names, 0, sizeof(bool) * main->objects.used);
+    // @todo remove this function from fss basic list read.
 
-      if (main->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) {
-        for (i = 0; i < main->objects.used; i++) {
+    if (main->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(main->output.stream, "%c", fss_basic_list_read_pipe_content_start);
+    }
+  }
+#endif // _di_fss_basic_list_read_print_content_end_
 
-          if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[0].value_name, main->buffer, main->objects.array[i], except_none, *delimits) == F_equal_to) {
-            names[i] = 1;
-          }
-        } // for
+#ifndef _di_fss_basic_list_read_print_content_ignore_
+  void fss_basic_list_read_print_content_ignore(fss_basic_list_read_main_t * const main) {
+
+    if (main->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(main->output.stream, "%c", fss_basic_list_read_pipe_content_ignore);
+    }
+  }
+#endif // _di_fss_basic_list_read_print_content_ignore_
+
+#ifndef _di_fss_basic_list_read_print_object_end_
+  void fss_basic_list_read_print_object_end(fss_basic_list_read_main_t * const main) {
+
+    if (main->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(main->output.stream, "%c", fss_basic_list_read_pipe_content_start);
+    }
+    else {
+      if (main->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
+        fprintf(main->output.stream, "%c%c", f_fss_basic_list_open, f_fss_basic_list_open_end);
       }
       else {
-        for (i = 0; i < main->objects.used; i++) {
-          if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[0].value_name, main->buffer, main->objects.array[i], except_none, *delimits) == F_equal_to) {
-            names[i] = 1;
-          }
-        } // for
+        fprintf(main->output.stream, "%c", f_fss_eol);
       }
     }
-    else {
-      memset(names, 1, sizeof(bool) * main->objects.used);
-    }
+  }
+#endif // _di_fss_basic_list_read_print_object_end_
 
-    bool include_empty = 0;
+#ifndef _di_fss_basic_list_read_print_set_end_
+  void fss_basic_list_read_print_set_end(fss_basic_list_read_main_t * const main) {
 
-    if (main->parameters[fss_basic_list_read_parameter_empty].result == f_console_result_found) {
-      include_empty = 1;
+    if (main->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(main->output.stream, "%c", fss_basic_list_read_pipe_content_end);
     }
+  }
+#endif // _di_fss_basic_list_read_print_set_end_
 
-    if (main->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) {
-      if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-        if (depths.array[0].index_at > 0) {
-          if (depths.array[0].value_at < main->objects.used && names[depths.array[0].value_at]) {
-            fprintf(main->output.stream, "1%c", f_string_eol_s[0]);
-          }
-          else {
-            fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
-          }
-        }
-        else if (depths.array[0].index_name > 0) {
-          f_array_length_t total = 0;
+#ifndef _di_fss_basic_list_read_print_one_
+  void fss_basic_list_read_print_one(fss_basic_list_read_main_t * const main) {
+    fprintf(main->output.stream, "1%c", f_string_eol_s[0]);
+  }
+#endif // _di_fss_basic_list_read_print_one_
 
-          for (i = 0; i < main->objects.used; i++) {
-            if (!names[i]) continue;
+#ifndef _di_fss_basic_list_read_print_zero_
+  void fss_basic_list_read_print_zero(fss_basic_list_read_main_t * const main) {
+    fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
+  }
+#endif // _di_fss_basic_list_read_print_zero_
 
-            total++;
-          } // for
+#ifndef _di_fss_basic_list_read_load_
+  f_status_t fss_basic_list_read_load(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) {
 
-          fprintf(main->output.stream, "%llu%c", total, f_string_eol_s[0]);
-        }
-        else {
-          fprintf(main->output.stream, "%llu%c", main->objects.used, f_string_eol_s[0]);
-        }
+    f_string_range_t input = macro_f_string_range_t_initialize(data->buffer.used);
+
+    data->delimits_object.used = 0;
+    data->delimits_content.used = 0;
+
+    const f_status_t status = fll_fss_basic_list_read(data->buffer, &input, &data->objects, &data->contents, &data->delimits_object, &data->delimits_content, &data->comments);
+
+    if (F_status_is_error(status)) {
+      const f_string_t file_name = fss_basic_list_read_file_identify(input.start, data->files);
+
+      fll_error_file_print(main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, file_name ? file_name : "-", "process", fll_error_file_type_file);
+
+      return status;
+    }
+    else if (status == F_data_not_stop || status == F_data_not_eos) {
+      if (data->option & fss_basic_list_read_data_option_total) {
+        fss_basic_list_read_print_zero(main);
 
         return F_none;
       }
 
-      f_status_t (*print_object)(FILE *, const f_string_static_t, const f_string_range_t, const f_array_lengths_t) = &f_print_except_dynamic_partial;
+      return F_status_set_warning(status);
+    }
+
+    return F_none;
+  }
+#endif // _di_fss_basic_list_read_load_
+
+#ifndef _di_fss_basic_list_read_process_
+  f_status_t fss_basic_list_read_process(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) {
+
+    f_status_t status = fss_basic_list_read_process_option(arguments, main, data);
+    if (F_status_is_error(status)) return status;
 
-      if (main->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) {
-        print_object = &fl_print_trim_except_dynamic_partial;
+    // This standard does not support multiple content groups.
+    if ((data->option & fss_basic_list_read_data_option_select) && data->select) {
+      if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
+        fss_basic_list_read_print_zero(main);
       }
 
-      if (depths.array[0].index_at > 0) {
-        f_array_length_t at = 0;
-        f_array_length_t i = 0;
+      return F_none;
+    }
 
-        for (; i < main->objects.used; i++) {
+    status = fss_basic_list_read_load(main, data);
+    if (F_status_is_error(status)) return status;
 
-          if (names[i]) {
-            if (at == depths.array[0].value_at) {
-              print_object(main->output.stream, main->buffer, main->objects.array[i], delimited ? *delimits : except_none);
+    bool names[data->objects.used];
 
-              fss_basic_list_read_print_object_end(*main);
+    status = fss_basic_list_read_process_name(data, names);
+    if (F_status_is_error(status)) return status;
 
-              if (main->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
-                if (main->contents.array[i].used) {
-                  fss_basic_list_read_print_content_ignore(*main);
-                  f_print_except_dynamic_partial(main->output.stream, main->buffer, main->contents.array[i].array[0], delimited ? *delimits : except_none);
-                  fss_basic_list_read_print_content_ignore(*main);
-                }
-              }
+    if (data->depths.array[0].index_at) {
+      return fss_basic_list_read_process_at(main, data, names);
+    }
 
-              fss_basic_list_read_print_set_end(*main);
-              break;
-            }
+    if (data->option & fss_basic_list_read_data_option_total) {
+      return fss_basic_list_read_process_total(main, data, names);
+    }
 
-            at++;
-          }
-        } // for
+    if (data->option & fss_basic_list_read_data_option_line) {
+      return fss_basic_list_read_process_line(main, data, names);
+    }
 
-        return F_none;
-      }
+    f_array_lengths_t except_none = f_array_lengths_t_initialize;
+    f_array_lengths_t *delimits_object = fss_basic_list_read_delimit_object_is(0, data) ? &data->delimits_object : &except_none;
+    f_array_lengths_t *delimits_content = fss_basic_list_read_delimit_content_is(0, data) ? &data->delimits_content : &except_none;
 
-      for (i = 0; i < main->objects.used; i++) {
+    for (f_array_length_t i = 0; i < data->contents.used; ++i) {
 
-        if (!names[i]) continue;
+      if (!names[i]) continue;
 
-        print_object(main->output.stream, main->buffer, main->objects.array[i], delimited ? *delimits : except_none);
+      fss_basic_list_read_print_at(main, data, i, *delimits_object, *delimits_content);
+    } // for
 
-        fss_basic_list_read_print_object_end(*main);
+    return F_none;
+  }
+#endif // _di_fss_basic_list_read_process_
 
-        if (main->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
-          if (main->contents.array[i].used) {
-            fss_basic_list_read_print_content_ignore(*main);
-            f_print_except_dynamic_partial(main->output.stream, main->buffer, main->contents.array[i].array[0], delimited ? *delimits : except_none);
-            fss_basic_list_read_print_content_ignore(*main);
-          }
-        }
+#ifndef _di_fss_basic_list_read_process_at_
+  f_status_t fss_basic_list_read_process_at(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, bool names[]) {
 
-        fss_basic_list_read_print_set_end(*main);
-      } // for
+    if (data->depths.array[0].value_at >= data->objects.used) {
+      if (names[data->depths.array[0].value_at] && (data->option & fss_basic_list_read_data_option_total)) {
+        fss_basic_list_read_print_zero(main);
+      }
 
       return F_none;
     }
 
-    if (depths.array[0].index_at > 0) {
-      if (depths.array[0].value_at >= main->objects.used) {
-        if (names[depths.array[0].value_at] && main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-          fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
+    f_array_lengths_t except_none = f_array_lengths_t_initialize;
+    f_array_lengths_t *delimits_object = fss_basic_list_read_delimit_object_is(0, data) ? &data->delimits_object : &except_none;
+    f_array_lengths_t *delimits_content = fss_basic_list_read_delimit_content_is(0, data) ? &data->delimits_content : &except_none;
+
+    f_array_length_t at = 0;
+    f_array_length_t line = 0;
+    f_status_t status = F_none;
+
+    for (f_array_length_t i = 0; i < data->objects.used; ++i) {
+
+      if (!names[i]) continue;
+
+      if (at == data->depths.array[0].value_at) {
+        if (data->option & fss_basic_list_read_data_option_line) {
+          status = fss_basic_list_read_process_at_line(at, *delimits_object, *delimits_content, main, data, &line);
+          if (status == F_success) return F_none;
+        }
+        else if (data->option & fss_basic_list_read_data_option_total) {
+          if (data->contents.array[i].used) {
+            fss_basic_list_read_print_one(main);
+          }
+          else {
+            fss_basic_list_read_print_zero(main);
+          }
+        }
+        else {
+          fss_basic_list_read_print_at(main, data, i, *delimits_object, *delimits_content);
         }
 
-        return F_none;
+        break;
       }
 
-      f_array_length_t at = 0;
-      f_array_length_t total = 0;
-      f_array_length_t line_current = 0;
+      ++at;
+    } // for
 
-      for (; i < main->objects.used; i++) {
+    // The line was never found.
+    if (data->option & fss_basic_list_read_data_option_line) {
+      if (data->option & fss_basic_list_read_data_option_total) {
+        fss_basic_list_read_print_zero(main);
+      }
+    }
 
-        if (names[i]) {
-          if (at == depths.array[0].value_at) {
-            if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-              if (!main->contents.array[i].used) {
-                fprintf(main->output.stream, "0%c", f_string_eol_s[0]);
-              }
-              else {
-                total = 1;
+    return F_none;
+  }
+#endif // _di_fss_basic_list_read_process_at_
 
-                for (j = main->contents.array[i].array[0].start; j <= main->contents.array[i].array[0].stop; j++) {
-                  if (!main->buffer.string[j]) continue;
+#ifndef _di_fss_basic_list_read_process_at_line_
+  f_status_t fss_basic_list_read_process_at_line(const f_array_length_t at, const f_array_lengths_t delimits_object, const f_array_lengths_t delimits_content, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, f_array_length_t *line) {
 
-                  if (main->buffer.string[j] == f_string_eol_s[0]) {
-                    total++;
-                  }
-                } // for
+    if (data->option & fss_basic_list_read_data_option_object) {
+      if (*line == data->line) {
+        if (data->option & fss_basic_list_read_data_option_total) {
+          fss_basic_list_read_print_one(main);
+        }
+        else {
+          fss_basic_list_read_print_at_object(main, data, at, delimits_object);
+        }
 
-                fprintf(main->output.stream, "%llu%c", total, f_string_eol_s[0]);
-              }
+        return F_success;
+      }
 
-              return F_none;
-            }
+      ++(*line);
+    }
 
-            if (main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
-              if (!main->contents.array[i].used) {
-                if (include_empty && !line) {
-                  fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-                  fss_basic_list_read_print_set_end(*main);
-                }
-              }
-              else {
-                i = main->contents.array[i].array[0].start;
-
-                if (!line) {
-                  for (; i <= main->contents.array[i].array[0].stop; i++) {
-                    if (!main->buffer.string[i]) continue;
-                    if (main->buffer.string[i] == f_string_eol_s[0]) {
-                      fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-                      break;
-                    }
-
-                    fprintf(main->output.stream, "%c", main->buffer.string[i]);
-                  } // for
-                }
-                else {
-                  line_current = 0;
-
-                  for (; i <= main->contents.array[i].array[0].stop; i++) {
-                    if (!main->buffer.string[i]) continue;
-
-                    if (main->buffer.string[i] == f_string_eol_s[0]) {
-                      line_current++;
-
-                      if (line_current == line) {
-                        i++;
-
-                        for (; i <= main->contents.array[i].array[0].stop; i++) {
-                          if (!main->buffer.string[i]) continue;
-
-                          if (main->buffer.string[i] == f_string_eol_s[0]) {
-                            fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-                            break;
-                          }
-
-                          fprintf(main->output.stream, "%c", main->buffer.string[i]);
-                        } // for
-
-                        break;
-                      }
-                    }
-                  } // for
-                }
-              }
-
-              return F_none;
-            }
+    // There is only a single Content column for this standard.
+    if (data->option & fss_basic_list_read_data_option_content) {
+      if (!data->contents.array[at].used) {
+        return F_none;
+      }
+
+      f_string_range_t range = f_string_range_t_initialize;
+      f_array_length_t i = 0;
+
+      range.start = data->contents.array[at].array[0].start;
+      range.stop = data->contents.array[at].array[0].stop;
+
+      // This content has no data, do not even check "include empty" because it cannot be counted as a line.
+      if (range.start > range.stop) {
+        return F_none;
+      }
 
-            if (main->contents.array[i].used > 0) {
-              fss_basic_list_read_print_content_ignore(*main);
-              f_print_except_dynamic_partial(main->output.stream, main->buffer, main->contents.array[i].array[0], delimited ? *delimits : except_none);
-              fss_basic_list_read_print_content_ignore(*main);
+      for (i = range.start; i <= range.stop; ++i) {
 
-              fss_basic_list_read_print_set_end(*main);
+        if (data->buffer.string[i] == f_string_eol_s[0]) {
+          if (*line == data->line) {
+            range.stop = i;
+
+            if (data->option & fss_basic_list_read_data_option_total) {
+              fss_basic_list_read_print_one(main);
             }
-            else if (include_empty) {
-              fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-              fss_basic_list_read_print_set_end(*main);
+            else {
+              f_print_except_dynamic_partial(main->output.stream, data->buffer, range, delimits_content);
             }
 
-            break;
+            return F_success;
           }
 
-          at++;
+          range.start = i + 1;
+
+          if (i <= range.stop) {
+            ++(*line);
+          }
         }
       } // for
 
-      return F_none;
-    }
-
-    if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
-      f_array_length_t total = 0;
+      // If Content does not end with a newline, it still must be treated as the last line.
+      if (data->buffer.string[range.stop] != f_string_eol_s[0]) {
+        ++(*line);
 
-      for (i = 0; i < main->objects.used; i++) {
-        if (!names[i]) continue;
+        if (*line == data->line) {
+          if (data->option & fss_basic_list_read_data_option_total) {
+            fss_basic_list_read_print_one(main);
+          }
+          else {
+            range.stop = data->contents.array[at].array[0].stop;
 
-        if (!main->contents.array[i].used) {
-          if (include_empty) {
-            total++;
+            f_print_except_dynamic_partial(main->output.stream, data->buffer, range, delimits_content);
+            fprintf(main->output.stream, "%c", f_string_eol_s[0]);
           }
 
-          continue;
+          return F_success;
         }
+      }
+    }
 
-        for (j = main->contents.array[i].array[0].start; j <= main->contents.array[i].array[0].stop; j++) {
-          if (!main->buffer.string[j]) continue;
+    return F_none;
+  }
+#endif // _di_fss_basic_list_read_process_at_line_
 
-          if (main->buffer.string[j] == f_string_eol_s[0]) {
-            total++;
-          }
-        } // for
-      } // for
+#ifndef _di_fss_basic_list_read_process_line_
+  f_status_t fss_basic_list_read_process_line(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, bool names[]) {
 
-      fprintf(main->output.stream, "%llu%c", total, f_string_eol_s[0]);
-      return F_none;
-    }
+    f_array_lengths_t except_none = f_array_lengths_t_initialize;
+    f_array_lengths_t *delimits_object = fss_basic_list_read_delimit_object_is(0, data) ? &data->delimits_object : &except_none;
+    f_array_lengths_t *delimits_content = fss_basic_list_read_delimit_content_is(0, data) ? &data->delimits_content : &except_none;
 
-    if (main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
-      for (f_array_length_t line_current = 0; i < main->contents.used; i++) {
-        if (!names[i]) continue;
-
-        if (!main->contents.array[i].used) {
-          if (include_empty) {
-            if (line_current == line) {
-              fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-              fss_basic_list_read_print_set_end(*main);
-              break;
-            }
+    f_array_length_t line = 0;
+    f_status_t status = F_none;
 
-            line_current++;
-          }
+    for (f_array_length_t i = 0; i < data->contents.used; ++i) {
 
-          continue;
-        }
-
-        j = main->contents.array[i].array[0].start;
+      if (!names[i]) continue;
 
-        if (line_current != line) {
-          for (; j <= main->contents.array[i].array[0].stop; j++) {
+      status = fss_basic_list_read_process_at_line(i, *delimits_object, *delimits_content, main, data, &line);
+      if (status == F_success) break;
+    } // for
 
-            if (main->buffer.string[j] == f_string_eol_s[0]) {
-              line_current++;
+    return F_none;
+  }
+#endif // _di_fss_basic_list_read_process_line_
 
-              if (line_current == line) {
-                j++;
-                break;
-              }
-            }
-          } // for
-        }
+#ifndef _di_fss_basic_list_read_process_name_
+  f_status_t fss_basic_list_read_process_name(fss_basic_list_read_data_t *data, bool names[]) {
 
-        if (line_current == line) {
-          if (j > main->contents.array[i].array[0].stop) continue;
+    f_array_lengths_t except_none = f_array_lengths_t_initialize;
 
-          for (; j <= main->contents.array[i].array[0].stop; j++) {
-            if (!main->buffer.string[j]) continue;
+    if (data->depths.array[0].index_name > 0) {
+      f_array_length_t i = 0;
 
-            if (main->buffer.string[j] == f_string_eol_s[0]) {
-              fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-              break;
-            }
+      memset(names, F_false, sizeof(bool) * data->objects.used);
 
-            fprintf(main->output.stream, "%c", main->buffer.string[j]);
-          } // for
+      if (data->option & fss_basic_list_read_data_option_trim) {
+        for (i = 0; i < data->objects.used; ++i) {
 
-          break;
-        }
-      } // for
+          if (fl_string_dynamic_partial_compare_except_trim_dynamic(data->depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, data->delimits_object) == F_equal_to) {
+            names[i] = F_true;
+          }
+        } // for
+      }
+      else {
+        for (i = 0; i < data->objects.used; ++i) {
 
-      return F_none;
+           if (fl_string_dynamic_partial_compare_except_dynamic(data->depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, data->delimits_object) == F_equal_to) {
+            names[i] = F_true;
+          }
+        } // for
+      }
+    }
+    else {
+      memset(names, F_true, sizeof(bool) * data->objects.used);
     }
 
-    for (i = 0; i < main->contents.used; i++) {
-      if (!names[i]) continue;
+    return F_none;
+  }
+#endif // _di_fss_basic_list_read_process_name_
 
-      if (!main->contents.array[i].used) {
-        if (include_empty) {
-          fprintf(main->output.stream, "%c", f_string_eol_s[0]);
-          fss_basic_list_read_print_set_end(*main);
-        }
+#ifndef _di_fss_basic_list_read_process_option_
+  f_status_t fss_basic_list_read_process_option(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) {
 
-        continue;
-      }
+    f_status_t status = F_none;
 
-      fss_basic_list_read_print_content_ignore(*main);
-      f_print_except_dynamic_partial(main->output.stream, main->buffer, main->contents.array[i].array[0], delimited ? *delimits : except_none);
-      fss_basic_list_read_print_content_ignore(*main);
+    if (main->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) {
+      data->option |= fss_basic_list_read_data_option_at;
+    }
 
-      fss_basic_list_read_print_set_end(*main);
-    } // for
+    if (main->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
+      data->option |= fss_basic_list_read_data_option_content;
+    }
 
-    return F_none;
-  }
-#endif // _di_fss_basic_list_read_main_process_file_
+    if (main->parameters[fss_basic_list_read_parameter_empty].result == f_console_result_found) {
+      data->option |= fss_basic_list_read_data_option_empty;
+    }
 
-#ifndef _di_fss_basic_list_read_print_object_end_
-  void fss_basic_list_read_print_object_end(const fss_basic_list_read_main_t main) {
+    if (main->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
+      data->option |= fss_basic_list_read_data_option_line;
 
-    if (main.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
-      fprintf(main.output.stream, "%c", fss_basic_list_read_pipe_content_start);
+      status = fss_basic_list_read_load_number(arguments, main, fss_basic_list_read_parameter_line, fss_basic_list_read_long_line, &data->line);
+      if (F_status_is_error(status)) return status;
     }
-    else {
-      if (main.parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
-        fprintf(main.output.stream, "%c%c", f_fss_basic_list_open, f_fss_basic_list_open_end);
-      }
-      else {
-        fprintf(main.output.stream, "%c", f_fss_eol);
-      }
+
+    if (main->parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) {
+      data->option |= fss_basic_list_read_data_option_name;
     }
-  }
-#endif // _di_fss_basic_list_read_print_object_end_
 
-#ifndef _di_fss_basic_list_read_print_content_end_
-  void fss_basic_list_read_print_content_end(const fss_basic_list_read_main_t main) {
+    if (main->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) {
+      data->option |= fss_basic_list_read_data_option_object;
+    }
+
+    if (main->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) {
+      data->option |= fss_basic_list_read_data_option_select;
 
-    if (main.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
-      fprintf(main.output.stream, "%c", fss_basic_list_read_pipe_content_start);
+      status = fss_basic_list_read_load_number(arguments, main, fss_basic_list_read_parameter_select, fss_basic_list_read_long_select, &data->select);
+      if (F_status_is_error(status)) return status;
     }
-  }
-#endif // _di_fss_basic_list_read_print_content_end_
 
-#ifndef _di_fss_basic_list_read_print_content_ignore_
-  void fss_basic_list_read_print_content_ignore(const fss_basic_list_read_main_t main) {
+    if (main->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
+      data->option |= fss_basic_list_read_data_option_total;
+    }
 
-    if (main.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
-      fprintf(main.output.stream, "%c", fss_basic_list_read_pipe_content_ignore);
+    if (main->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) {
+      data->option |= fss_basic_list_read_data_option_trim;
     }
+
+    // Default to content if neither Object nor Content is explicitly requested.
+    if (!(data->option & (fss_basic_list_read_data_option_content | fss_basic_list_read_data_option_object))) {
+      data->option |= fss_basic_list_read_data_option_content;
+    }
+
+    return F_none;
   }
-#endif // _di_fss_basic_list_read_print_content_ignore_
+#endif // _di_fss_basic_list_read_process_option_
 
-#ifndef _di_fss_basic_list_read_print_set_end_
-  void fss_basic_list_read_print_set_end(const fss_basic_list_read_main_t main) {
+#ifndef _di_fss_basic_list_read_process_total_
+  f_status_t fss_basic_list_read_process_total(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, bool names[]) {
+
+    f_array_length_t total = 0;
+    f_string_range_t range = f_string_range_t_initialize;
+    f_array_length_t i = 0;
+
+    for (f_array_length_t at = 0; at < data->contents.used; ++at) {
+
+      if (!names[at]) continue;
+
+      if (data->option & fss_basic_list_read_data_option_object) {
+        ++total;
+      }
+
+      // There is only a single Content column for this standard.
+      if (data->option & fss_basic_list_read_data_option_content) {
+
+        if (!data->contents.array[at].used) continue;
+
+        range.start = data->contents.array[at].array[0].start;
+        range.stop = data->contents.array[at].array[0].stop;
+
+        // This content has no data, do not even check "include empty" because it cannot be counted as a line.
+        if (range.start > range.stop) {
+          continue;
+        }
+
+        for (i = range.start; i <= range.stop; ++i) {
 
-    if (main.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
-      fprintf(main.output.stream, "%c", fss_basic_list_read_pipe_content_end);
+          if (data->buffer.string[i] == f_string_eol_s[0]) {
+            range.start = i + 1;
+
+            if (i <= range.stop) {
+              ++total;
+            }
+          }
+        } // for
+
+        // If Content does not end with a newline, it still must be treated as the last line.
+        if (data->buffer.string[range.stop] != f_string_eol_s[0]) {
+          ++total;
+        }
+      }
+    } // for
+
+    if (data->option & fss_basic_list_read_data_option_line) {
+      if (data->line < total) {
+        fss_basic_list_read_print_one(main);
+      }
+      else {
+        fss_basic_list_read_print_zero(main);
+      }
     }
+    else {
+      fprintf(main->output.stream, "%llu%c", total, f_string_eol_s[0]);
+    }
+
+    return F_none;
   }
-#endif // _di_fss_basic_list_read_print_set_end_
+#endif // _di_fss_basic_list_read_process_total_
 
 #ifdef __cplusplus
 } // extern "C"
index 53e834fa3bb47f3a21b55e8535e3ecdbc0eae7a4..db4b47308877b692e36809125f653e0a3fd09601 100644 (file)
@@ -13,66 +13,154 @@ extern "C" {
 #endif
 
 /**
- * Pre-process the parameters, parsing out and handling the depth and depth related parameters.
+ * Determine if the given depth is to be delimited or not for Content.
+ *
+ * @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_list_read_delimit_content_is_
+  extern f_status_t fss_basic_list_read_delimit_content_is(const f_array_length_t depth, fss_basic_list_read_data_t * const data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_delimit_content_is_
+
+/**
+ * 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_list_read_delimit_object_is_
+  extern f_status_t fss_basic_list_read_delimit_object_is(const f_array_length_t depth, fss_basic_list_read_data_t * const data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_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).
  *
  * @param arguments
- *   The console arguments to pre-process.
+ *   The parameters passed to the process.
  * @param main
  *   The main data.
- * @param depths
- *   This stores the pre-processed depth parameters.
+ * @param data
+ *   The program data.
  *
  * @return
  *   F_none on success.
  *
- *   Status codes (with error bit) are returned on any problem.
+ *   Errors (with error bit) from: f_string_append().
+ *   Errors (with error bit) from: fl_string_rip().
+ *   Errors (with error bit) from: fl_conversion_string_to_number_unsigned().
+ *
+ *   Errors (with error bit) from: fss_basic_list_read_depths_resize().
+ *
+ * @see f_string_append()
+ * @see fl_string_rip()
+ * @see fl_conversion_string_to_number_unsigned()
+ *
+ * @see fss_basic_list_read_depths_resize()
  */
-#ifndef _di_fss_basic_list_read_main_preprocess_depth_
-  extern f_status_t fss_basic_list_read_main_preprocess_depth(const f_console_arguments_t arguments, const fss_basic_list_read_main_t main, fss_basic_list_read_depths_t *depths) f_attribute_visibility_internal;
-#endif // _di_fss_basic_list_read_main_preprocess_depth_
+#ifndef _di_fss_basic_list_read_depth_process_
+  extern f_status_t fss_basic_list_read_depth_process(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_depth_process_
 
 /**
- * Process a given file.
+ * Get the name of the file the given position represents within the buffer.
+ *
+ * @param at
+ *   The position within the buffer.
+ * @param files
+ *   The representation of files and their respective ranges within the buffer.
+ *
+ * @return
+ *   A string with the name when found.
+ *   NULL is returned if the range represents the STDIN pipe.
+ *
+ *   On failure to identify, an empty string is returned.
+ */
+#ifndef _di_fss_basic_list_read_file_identify_
+  extern f_string_t fss_basic_list_read_file_identify(const f_array_length_t at, const fss_basic_list_read_files_t files) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_file_identify_
+
+/**
+ * Load a given number parameter.
+ *
+ * This will print an error message on error.
  *
  * @param arguments
  *   The console arguments passed to the program.
  * @param main
  *   The main data.
- * @param file_name
- *   The name of the file being processed.
- * @param depths
- *   The processed depth parameters.
- * @param delimits
- *   An array of delimits detected during processing.
- * @param comments
- *   An array of ranges representing where comments are found within any valid content.
- *   This only stores comments found within valid content only.
+ * @param parameter
+ *   An ID representing the parameter.
+ * @param name
+ *   The parameter name to print on error.
+ * @param number
+ *   The location to store the loaded number.
  *
  * @return
- *   F_none on success.
+ *   F_true on success and the parameter was found (and is valid).
+ *   F_false on success and the parameter was not found.
+ *
+ *   Errors (with error bit) from: fl_conversion_string_to_number_unsigned().
  *
- *   Status codes (with error bit) are returned on any problem.
+ * @see fl_conversion_string_to_number_unsigned()
  *
- * @see fss_basic_list_read_main_preprocess_depth()
+ * @see fss_basic_list_read_depths_resize()
  */
-#ifndef _di_fss_basic_list_read_main_process_file_
-  extern f_status_t fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_main_t *main, const f_string_t file_name, const fss_basic_list_read_depths_t depths, f_fss_delimits_t *delimits, f_fss_comments_t *comments) f_attribute_visibility_internal;
-#endif // _di_fss_basic_list_read_main_process_file_
+#ifndef _di_fss_basic_list_read_load_number_
+  extern f_status_t fss_basic_list_read_load_number(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, const f_array_length_t parameter, const f_string_t name, f_number_unsigned_t *number) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_load_number_
 
 /**
- * Print the end of an object (which is essentially the start of a content).
+ * Print the Object and Content at the given position.
+ *
+ * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print.
  *
  * @param main
  *   The main data.
+ * @param data
+ *   The program data.
+ * @param at
+ *   The index in the Objects and Contents to print.
+ * @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_list_read_print_object_end_
-  extern void fss_basic_list_read_print_object_end(const fss_basic_list_read_main_t main) f_attribute_visibility_internal;
-#endif // _di_fss_basic_list_read_print_object_end_
+#ifndef _di_fss_basic_list_read_print_at_
+  extern void fss_basic_list_read_print_at(fss_basic_list_read_main_t * const main, fss_basic_list_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_list_read_print_at_
+
+/**
+ * Explicitly print the Object at the given position.
+ *
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ * @param at
+ *   The index in the Objects and Contents to print.
+ * @param delimits_object
+ *   The delimits to be applied to an Object.
+ */
+#ifndef _di_fss_basic_list_read_print_at_object_
+  extern void fss_basic_list_read_print_at_object(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_at_object_
 
 /**
- * Print the ignore character for content.
+ * Print the ignore character for Content.
  *
  * This is only used in pipe output mode.
  *
@@ -80,29 +168,230 @@ extern "C" {
  *   The main data.
  */
 #ifndef _di_fss_basic_list_read_print_content_ignore_
-  extern void fss_basic_list_read_print_content_ignore(const fss_basic_list_read_main_t main) f_attribute_visibility_internal;
+  extern void fss_basic_list_read_print_content_ignore(fss_basic_list_read_main_t * const main) f_attribute_visibility_internal;
 #endif // _di_fss_basic_list_read_print_content_ignore_
 
 /**
- * Print the end of an content.
+ * Print the end of Content.
  *
  * @param main
  *   The main data.
  */
 #ifndef _di_fss_basic_list_read_print_content_end_
-  extern void fss_basic_list_read_print_content_end(const fss_basic_list_read_main_t main) f_attribute_visibility_internal;
+  extern void fss_basic_list_read_print_content_end(fss_basic_list_read_main_t * const main) f_attribute_visibility_internal;
 #endif // _di_fss_basic_list_read_print_content_end_
 
 /**
- * Print the end of an object/content set.
+ * Print the end of an Object (which is essentially the start of Content).
+ *
+ * @param main
+ *   The main data.
+ */
+#ifndef _di_fss_basic_list_read_print_object_end_
+  extern void fss_basic_list_read_print_object_end(fss_basic_list_read_main_t * const main) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_object_end_
+
+/**
+ * Print the number one and a newline.
+ *
+ * @param main
+ *   The main data.
+ */
+#ifndef _di_fss_basic_list_read_print_one_
+  extern void fss_basic_list_read_print_one(fss_basic_list_read_main_t * const main) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_one_
+
+/**
+ * Print the end of an Object/Content set.
  *
  * @param main
  *   The main data.
  */
 #ifndef _di_fss_basic_list_read_print_set_end_
-  extern void fss_basic_list_read_print_set_end(const fss_basic_list_read_main_t main) f_attribute_visibility_internal;
+  extern void fss_basic_list_read_print_set_end(fss_basic_list_read_main_t * const main) f_attribute_visibility_internal;
 #endif // _di_fss_basic_list_read_print_set_end_
 
+/**
+ * Print the number zero and a newline.
+ *
+ * @param main
+ *   The main data.
+ */
+#ifndef _di_fss_basic_list_read_print_zero_
+  extern void fss_basic_list_read_print_zero(fss_basic_list_read_main_t * const main) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_zero_
+
+/**
+ * Process the buffer, loading the FSS data.
+ *
+ * This will print an error message on error.
+ *
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_data_not_stop (with warning bit) on no valid FSS data found and reached stopping point.
+ *   F_data_not_eos (with warning bit) on no valid FSS data found and reached end of string.
+ *
+ *   Errors (with error bit) from: fll_fss_basic_list_read()
+ *
+ * @see fll_fss_basic_list_read()
+ *
+ * @see fss_basic_list_read_process_option()
+ */
+#ifndef _di_fss_basic_list_read_load_
+  extern f_status_t fss_basic_list_read_load(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_load_
+
+/**
+ * Perform the basic read processing on the buffer.
+ *
+ * This will print an error message on error.
+ *
+ * @param arguments
+ *   The parameters passed to the process.
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: fss_basic_list_read_load()
+ *   Errors (with error bit) from: fss_basic_list_read_process_option()
+ *
+ * @see fss_basic_list_read_load()
+ * @see fss_basic_list_read_process_option()
+ */
+#ifndef _di_fss_basic_list_read_process_
+  extern f_status_t fss_basic_list_read_process(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_
+
+/**
+ * Process based on at parameter.
+ *
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ * @param names
+ *   An array of booleans representing whether or not some Object name is to be used.
+ *   (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.)
+ *
+ * @return
+ *   F_none on success.
+ *
+ * @see fss_basic_list_read_process_at_line()
+ */
+#ifndef _di_fss_basic_list_read_process_at_
+  extern f_status_t fss_basic_list_read_process_at(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, bool names[]) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_at_
+
+/**
+ * Process based on at parameter for some line.
+ *
+ * @param main
+ *   The main data.
+ * @param delimits_object
+ *   The delimits to be applied to an Object.
+ * @param delimits_content
+ *   The delimits to be applied to Content.
+ * @param data
+ *   The program data.
+ * @param line
+ *   The current line being processed.
+ *   This will be incremented as necessary.
+ *
+ * @return
+ *   F_none on success but no line was matched (and possibly printed).
+ *   F_success on success and the line was matched (and possibly printed).
+ */
+#ifndef _di_fss_basic_list_read_process_at_line_
+  extern f_status_t fss_basic_list_read_process_at_line(const f_array_length_t at, const f_array_lengths_t delimits_object, const f_array_lengths_t delimits_content, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, f_array_length_t *line) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_at_line_
+
+/**
+ * Process based on line parameter.
+ *
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ * @param names
+ *   An array of booleans representing whether or not some Object name is to be used.
+ *   (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.)
+ *
+ * @return
+ *   F_none on success.
+ */
+#ifndef _di_fss_basic_list_read_process_line_
+  extern f_status_t fss_basic_list_read_process_line(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, bool names[]) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_line_
+
+/**
+ * Process the Objects in the buffer, determining if the Object name is to be used or not.
+ *
+ * How an Object name is determined to be used or not is dependent on several parameters, such as --name, --depth, --at, and --line.
+ *
+ * @param data
+ *   The program data.
+ * @param names
+ *   An array of booleans representing whether or not some Object name is to be used.
+ *   (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.)
+ *
+ * @return
+ *   F_none on success.
+ */
+#ifndef _di_fss_basic_list_read_process_name_
+  extern f_status_t fss_basic_list_read_process_name(fss_basic_list_read_data_t *data, bool names[]) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_name_
+
+/**
+ * Process the parameters, populating the option property of the program data.
+ *
+ * @param arguments
+ *   The parameters passed to the process.
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: fss_basic_list_read_load_setting()
+ *
+ * @see fll_fss_basic_list_read()
+ *
+ * @see fss_basic_list_read_load_setting()
+ */
+#ifndef _di_fss_basic_list_read_process_option_
+  extern f_status_t fss_basic_list_read_process_option(f_console_arguments_t * const arguments, fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_option_
+
+/**
+ * Process based on total parameter.
+ *
+ * @param main
+ *   The main data.
+ * @param data
+ *   The program data.
+ * @param names
+ *   An array of booleans representing whether or not some Object name is to be used.
+ *   (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.)
+ *
+ * @return
+ *   F_none on success.
+ */
+#ifndef _di_fss_basic_list_read_process_total_
+  extern f_status_t fss_basic_list_read_process_total(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t *data, bool names[]) f_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_process_total_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif