From fdb14fab1355bab97f1e988823d963c544a6e748 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 7 Jan 2020 21:44:33 -0600 Subject: [PATCH] Progress: continue working on fss_extended_list --- build/level_1/settings | 4 +- build/level_2/settings | 4 +- build/monolithic/settings | 4 +- level_0/f_fss/c/fss.h | 682 +++++++++--------- level_1/fl_fss/c/fss_extended_list.c | 91 +-- level_1/fl_fss/c/fss_extended_list.h | 6 +- level_1/fl_fss/c/fss_macro.h | 27 +- level_2/fll_fss/c/fss_extended_list.c | 70 +- level_2/fll_fss/c/fss_extended_list.h | 8 +- .../c/private-fss_basic_list_read.c | 2 +- level_3/fss_basic_read/c/private-fss_basic_read.c | 2 +- .../c/fss_extended_list_read.c | 218 ++++-- .../c/fss_extended_list_read.h | 10 +- .../c/private-fss_extended_list_read.c | 788 ++++++++++++--------- .../c/private-fss_extended_list_read.h | 93 ++- .../c/private-fss_extended_read.c | 6 +- 16 files changed, 1139 insertions(+), 876 deletions(-) diff --git a/build/level_1/settings b/build/level_1/settings index 0157198..610e33e 100644 --- a/build/level_1/settings +++ b/build/level_1/settings @@ -12,9 +12,9 @@ build_linker ar build_libraries -lc build_libraries_fll -lfll_0 build_libraries_fll-level -lfll_0 -build_sources_library color.c console.c directory.c file.c fss.c fss_basic.c fss_basic_list.c fss_extended.c serialized.c socket.c status.c string.c utf.c +build_sources_library color.c console.c directory.c file.c fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c serialized.c socket.c status.c string.c utf.c build_sources_program -build_sources_headers color.h console.h directory.h file.h fss.h fss_basic.h fss_basic_list.h fss_status.h fss_extended.h fss_macro.h serialized.h socket.h status.h string.h utf.h +build_sources_headers color.h console.h directory.h file.h fss.h fss_basic.h fss_basic_list.h fss_status.h fss_extended.h fss_extended_list.h fss_macro.h serialized.h socket.h status.h string.h utf.h build_shared yes build_static yes diff --git a/build/level_2/settings b/build/level_2/settings index 773a50b..c63f279 100644 --- a/build/level_2/settings +++ b/build/level_2/settings @@ -12,9 +12,9 @@ build_linker ar build_libraries -lc build_libraries_fll -lfll_0 -lfll_1 build_libraries_fll-level -lfll_0 -lfll_1 -build_sources_library execute.c file.c fss_basic.c fss_basic_list.c fss_extended.c fss_status.c program.c status.c +build_sources_library execute.c file.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c program.c status.c build_sources_program -build_sources_headers execute.h file.h fss_basic.h fss_basic_list.h fss_extended.h fss_status.h program.h status.h +build_sources_headers execute.h file.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h program.h status.h build_shared yes build_static yes diff --git a/build/monolithic/settings b/build/monolithic/settings index 9d4cfdd..a543da2 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -11,9 +11,9 @@ build_compiler gcc build_linker ar build_libraries -lc build_libraries_fll -build_sources_library level_0/console.c level_0/conversion.c level_0/file.c level_0/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_1/color.c level_1/console.c level_1/directory.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/utf.c level_2/execute.c level_2/file.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_status.c level_2/program.c level_2/status.c +build_sources_library level_0/console.c level_0/conversion.c level_0/file.c level_0/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_1/color.c level_1/console.c level_1/directory.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/utf.c level_2/execute.c level_2/file.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c build_sources_program -build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/file.h level_0/fss.h level_0/memory.h level_0/path_fll.h level_0/path_filesystem.h level_0/pipe.h level_0/print.h level_0/serialized.h level_0/socket.h level_0/status.h level_0/string.h level_0/type.h level_0/type_array.h level_0/utf.h level_1/color.h level_1/console.h level_1/directory.h level_1/file.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_status.h level_1/fss_extended.h level_1/fss_macro.h level_1/serialized.h level_1/socket.h level_1/status.h level_1/string.h level_1/utf.h level_2/execute.h level_2/file.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_status.h level_2/program.h level_2/status.h +build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/file.h level_0/fss.h level_0/memory.h level_0/path_fll.h level_0/path_filesystem.h level_0/pipe.h level_0/print.h level_0/serialized.h level_0/socket.h level_0/status.h level_0/string.h level_0/type.h level_0/type_array.h level_0/utf.h level_1/color.h level_1/console.h level_1/directory.h level_1/file.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_status.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/serialized.h level_1/socket.h level_1/status.h level_1/string.h level_1/utf.h level_2/execute.h level_2/file.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/program.h level_2/status.h build_sources_bash build_sources_settings build_shared yes diff --git a/level_0/f_fss/c/fss.h b/level_0/f_fss/c/fss.h index 5d7eaea..045fc32 100644 --- a/level_0/f_fss/c/fss.h +++ b/level_0/f_fss/c/fss.h @@ -293,7 +293,7 @@ extern "C" { #endif // _di_f_fss_contents_ /** - * This holds a child content object and its associated content. + * This holds a item object and its associated content. * * Child content represents content nested within some other content and never represents the top-most content. * @@ -304,30 +304,30 @@ extern "C" { * content: The content associated with the object. * parent: A location referencing a parrent object or content that this object content is nested under. */ -#ifndef _di_fss_content_child_ +#ifndef _di_fss_item_ typedef struct { f_fss_object object; f_fss_content content; f_array_length parent; - } f_fss_content_child; + } f_fss_item; - #define f_fss_content_child_initialize { f_fss_object_initialize, f_fss_content_initialize, f_array_length_initialize } + #define f_fss_item_initialize { f_fss_object_initialize, f_fss_content_initialize, f_array_length_initialize } /** - * Reset a fss content child stucture to 0 (clear all values). + * Reset a fss item stucture to 0 (clear all values). * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * content_child: the f_fss_content_child structure to operate on. + * item: the f_fss_item structure to operate on. */ - #define f_macro_fss_content_child_clear(content_child) \ - content_child.object.start = 1; \ - content_child.object.stop = 0; \ - f_macro_fss_content_clear(content_child.content); \ - content_child.parent = 0; + #define f_macro_fss_item_clear(item) \ + item.object.start = 1; \ + item.object.stop = 0; \ + f_macro_fss_content_clear(item.content); \ + item.parent = 0; /** - * Create a new fss content child structure. + * Create a new fss item structure. * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * @@ -336,88 +336,86 @@ extern "C" { * type: the structure type. * length: the new size of the array. */ - #define f_macro_fss_content_child_new(status, content_child, length) \ - content_child.object.start = 1; \ - content_child.object.stop = 0; \ - f_macro_fss_content_new(status, content_child.content, length) \ - content_child.parent = 0; + #define f_macro_fss_item_new(status, item, length) \ + item.object.start = 1; \ + item.object.stop = 0; \ + f_macro_fss_content_new(status, item.content, length) \ + item.parent = 0; /** - * Delete a fss content child. + * Delete a fss item. * - * status: the status to return. - * content_child: the f_fss_content_child structure to operate on. + * status: the status to return. + * item: the f_fss_item structure to operate on. */ - #define f_macro_fss_content_child_delete(status, content_child) \ - f_macro_fss_content_delete(status, content_child.content) \ + #define f_macro_fss_item_delete(status, item) \ + f_macro_fss_content_delete(status, item.content) \ if (status == f_none) { \ - content_child.object.start = 1; \ - content_child.object.stop = 0; \ - content_child.parent = 0; \ + item.object.start = 1; \ + item.object.stop = 0; \ + item.parent = 0; \ } /** - * Destroy a fss content child. + * Destroy a fss item. * - * status: the status to return. - * content_child: the f_fss_content_child structure to operate on. + * status: the status to return. + * item: the f_fss_item structure to operate on. */ - #define f_macro_fss_content_child_destroy(status, content_child) \ - f_macro_fss_content_destroy(status, content_child.content) \ + #define f_macro_fss_item_destroy(status, item) \ + f_macro_fss_content_destroy(status, item.content) \ if (status == f_none) { \ - content_child.object.start = 1; \ - content_child.object.stop = 0; \ - content_child.parent = 0; \ + item.object.start = 1; \ + item.object.stop = 0; \ + item.parent = 0; \ } /** - * Delete a fss content child. + * Delete a fss item. * - * content_child: the f_fss_content_child structure to operate on. + * item: the f_fss_item structure to operate on. */ - #define f_macro_fss_content_child_delete_simple(content_child) \ - f_macro_fss_content_delete_simple(content_child.content); \ - content_child.object.start = 1; \ - content_child.object.stop = 0; \ - content_child.parent = 0; + #define f_macro_fss_item_delete_simple(item) \ + f_macro_fss_content_delete_simple(item.content); \ + item.object.start = 1; \ + item.object.stop = 0; \ + item.parent = 0; /** - * Destroy a fss content child. + * Destroy a fss item. * - * content_child: the f_fss_content_child structure to operate on. + * item: the f_fss_item structure to operate on. */ - #define f_macro_fss_content_child_destroy_simple(content_child) \ - f_macro_fss_content_destroy_simple(content_child.content); \ - content_child.object.start = 1; \ - content_child.object.stop = 0; \ - content_child.parent = 0; + #define f_macro_fss_item_destroy_simple(item) \ + f_macro_fss_content_destroy_simple(item.content); \ + item.object.start = 1; \ + item.object.stop = 0; \ + item.parent = 0; /** - * Resize a fss content child. + * Resize a fss item. * - * status: the status to return. - * content_child: the f_fss_content_child structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * item: the f_fss_item structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_child_resize(status, content_child, new_length) f_macro_fss_content_resize(status, content_child.content, new_length); + #define f_macro_fss_item_resize(status, item, new_length) f_macro_fss_content_resize(status, item.content, new_length); /** - * Adjust a fss content child. + * Adjust a fss item. * - * status: the status to return. - * content_child: the f_fss_content_child structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * item: the f_fss_item structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_child_adjust(status, content_child, new_length) f_macro_fss_content_adjust(status, content_child.content, new_length); + #define f_macro_fss_item_adjust(status, item, new_length) f_macro_fss_content_adjust(status, item.content, new_length); -#endif // _di_fss_content_child_ +#endif // _di_fss_item_ /** - * This holds an array of fss_content_child. + * This holds an array of fss_item. * - * This is designed to be used as a part of f_fss_content_nest. - * Range represents the full range of the particular content set. - * Range can exist before the first child and after the last child to represent unnested data within the content. + * This is designed to be used as a part of f_fss_nest. * * For example: * object { @@ -438,283 +436,276 @@ extern "C" { * More content after. * } * - * range: A location range representing the full start/stop locations of the entire set. * array: The array of object, their associated content, and their associated parent. * size: Total amount of allocated space. * used: Total number of allocated spaces used. */ -#ifndef _di_fss_content_childs_ +#ifndef _di_fss_items_ typedef struct { - f_string_location range; - f_fss_content_child *array; - f_array_length size; - f_array_length used; - } f_fss_content_childs; + f_fss_item *array; - #define f_fss_content_childs_initialize { f_string_location_initialize, 0, 0, 0 } + f_array_length size; + f_array_length used; + } f_fss_items; + + #define f_fss_items_initialize { 0, 0, 0 } /** - * Reset a fss content childs to 0 (clear all values). + * Reset a fss items to 0 (clear all values). * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * content_childs: the f_fss_content_childs structure to operate on. + * items: the f_fss_items structure to operate on. */ - #define f_macro_fss_content_childs_clear(content_childs) \ - content_childs.range.start = 1; \ - content_childs.range_stop = 0; \ - content_childs.array = 0; \ - content_childs.size = 0; \ - content_childs.used = 0; + #define f_macro_fss_items_clear(items) \ + items.array = 0; \ + items.size = 0; \ + items.used = 0; /** - * Create a new fss content childs. + * Create a new fss items. * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * status: the status to return. - * content_childs: the f_fss_content_childs structure to operate on. - * new_length: the new size of the array. - */ - #define f_macro_fss_content_childs_new(status, content_childs, length) \ - content_childs.range.start = 1; \ - content_childs.range_stop = 0; \ - content_childs.array = 0; \ - content_childs.size = 0; \ - content_childs.used = 0; \ - status = f_memory_new((void **) & content_childs.array, sizeof(f_fss_content_child), new_length); \ + * status: the status to return. + * items: the f_fss_items structure to operate on. + * new_length: the new size of the array. + */ + #define f_macro_fss_items_new(status, items, length) \ + items.array = 0; \ + items.size = 0; \ + items.used = 0; \ + status = f_memory_new((void **) & items.array, sizeof(f_fss_item), new_length); \ if (status == f_none) { \ - content_childs.size = new_length; \ - content_childs.used = 0; \ + items.size = new_length; \ + items.used = 0; \ } /** - * Delete a fss content childs. + * Delete a fss items. * - * status: the status to return. - * content_childs: the f_fss_content_childs structure to operate on. + * status: the status to return. + * items: the f_fss_items structure to operate on. */ - #define f_macro_fss_content_childs_delete(status, content_childs) \ + #define f_macro_fss_items_delete(status, items) \ status = f_none; \ - content_childs.used = content_childs.size; \ - while (content_childs.used > 0) { \ - content_childs.used--; \ - f_macro_fss_content_child_delete(status, content_childs.array[content_childs.used]); \ + items.used = items.size; \ + while (items.used > 0) { \ + items.used--; \ + f_macro_fss_item_delete(status, items.array[items.used]); \ if (status != f_none) break; \ } \ - if (status == f_none) status = f_memory_delete((void **) & content_childs.array, sizeof(f_fss_content_child), content_childs.size); \ - if (status == f_none) content_childs.size = 0; + if (status == f_none) status = f_memory_delete((void **) & items.array, sizeof(f_fss_item), items.size); \ + if (status == f_none) items.size = 0; /** - * Destroy a fss content childs. + * Destroy a fss items. * - * status: the status to return. - * content_childs: the f_fss_content_childs structure to operate on. + * status: the status to return. + * items: the f_fss_items structure to operate on. */ - #define f_macro_fss_content_childs_destroy(status, content_childs) \ + #define f_macro_fss_items_destroy(status, items) \ status = f_none; \ - content_childs.used = content_childs.size; \ - while (content_childs.used > 0) { \ - content_childs.used--; \ - f_macro_fss_content_child_destroy(status, content_childs.array[content_childs.used]); \ + items.used = items.size; \ + while (items.used > 0) { \ + items.used--; \ + f_macro_fss_item_destroy(status, items.array[items.used]); \ if (status != f_none) break; \ } \ - if (status == f_none) status = f_memory_delete((void **) & content_childs.array, sizeof(f_fss_content_child), content_childs.size); \ - if (status == f_none) content_childs.size = 0; + if (status == f_none) status = f_memory_delete((void **) & items.array, sizeof(f_fss_item), items.size); \ + if (status == f_none) items.size = 0; /** - * Delete a fss content childs. + * Delete a fss items. * - * content_childs: the f_fss_content_childs structure to operate on. + * items: the f_fss_items structure to operate on. */ - #define f_macro_fss_content_childs_delete_simple(content_childs) \ - content_childs.used = content_childs.size; \ - while (content_childs.used > 0) { \ - content_childs.used--; \ - f_macro_fss_content_child_delete(content_childs.array[content_childs.used]); \ - if (content_childs.used == 0) { \ - if (f_memory_delete((void **) & content_childs.array, sizeof(f_fss_content_child), content_childs.size)) { \ - content_childs.size = 0; \ + #define f_macro_fss_items_delete_simple(items) \ + items.used = items.size; \ + while (items.used > 0) { \ + items.used--; \ + f_macro_fss_item_delete_simple(items.array[items.used]); \ + if (items.used == 0) { \ + if (f_memory_delete((void **) & items.array, sizeof(f_fss_item), items.size)) { \ + items.size = 0; \ } \ } \ } /** - * Destroy a fss content childs. + * Destroy a fss items. * - * content_childs: the f_fss_content_childs structure to operate on. + * items: the f_fss_items structure to operate on. */ - #define f_macro_fss_content_childs_destroy_simple(content_childs) \ - content_childs.used = content_childs.size; \ - while (content_childs.used > 0) { \ - content_childs.used--; \ - f_macro_fss_content_child_destroy(status, content_childs.array[content_childs.used]); \ - if (content_childs.used == 0) { \ - if (f_memory_destroy((void **) & content_childs.array, sizeof(f_fss_content_child), content_childs.size)) { \ - content_childs.size = 0; \ + #define f_macro_fss_items_destroy_simple(items) \ + items.used = items.size; \ + while (items.used > 0) { \ + items.used--; \ + f_macro_fss_item_destroy_simple(status, items.array[items.used]); \ + if (items.used == 0) { \ + if (f_memory_destroy((void **) & items.array, sizeof(f_fss_item), items.size)) { \ + items.size = 0; \ } \ } \ } /** - * Resize a fss content childs. + * Resize a fss items. * - * status: the status to return. - * content_childs: the f_fss_content_childs structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * items: the f_fss_items structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_childs_resize(status, content_childs, new_length) \ + #define f_macro_fss_items_resize(status, items, new_length) \ status = f_none; \ - if (new_length < content_childs.size) { \ - f_array_length i = content_childs.size - new_length; \ - for (; i < content_childs.size; i++) { \ - f_macro_fss_content_child_delete(status, content_childs.array[i]); \ + if (new_length < items.size) { \ + f_array_length i = items.size - new_length; \ + for (; i < items.size; i++) { \ + f_macro_fss_item_delete(status, items.array[i]); \ if (status != f_none) break; \ } \ } \ - if (status == f_none) status = f_memory_resize((void **) & content_childs.array, sizeof(f_fss_content_child), content_childs.size, new_length); \ + if (status == f_none) status = f_memory_resize((void **) & items.array, sizeof(f_fss_item), items.size, new_length); \ if (status == f_none) { \ - if (new_length > content_childs.size) { \ - f_array_length i = content_childs.size; \ + if (new_length > items.size) { \ + f_array_length i = items.size; \ for (; i < new_length; i++) { \ - memset(&content_childs.array[i], 0, sizeof(f_fss_content_child)); \ + memset(&items.array[i], 0, sizeof(f_fss_item)); \ } \ } \ - content_childs.range.start = 1; \ - content_childs.range.stop = 0; \ - content_childs.size = new_length; \ - if (content_childs.used > content_childs.size) content_childs.used = new_length; \ + items.size = new_length; \ + if (items.used > items.size) items.used = new_length; \ } /** - * Adjust a fss content childs. + * Adjust a fss items. * - * status: the status to return. - * content_childs: the f_fss_content_childs structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * items: the f_fss_items structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_childs_adjust(status, content_childs, new_length) \ + #define f_macro_fss_items_adjust(status, items, new_length) \ status = f_none; \ - if (new_length < content_childs.size) { \ - length_variable i = content_childs.size - new_length; \ - for (; i < content_childs.size; i++) { \ - f_macro_fss_content_child_destroy(status, content_childs.array[i]); \ + if (new_length < items.size) { \ + length_variable i = items.size - new_length; \ + for (; i < items.size; i++) { \ + f_macro_fss_item_destroy(status, items.array[i]); \ if (status != f_none) break; \ } \ } \ - if (status == f_none) status = f_memory_adjust((void **) & content_childs.array, sizeof(f_fss_content_child), content_childs.size, new_length); \ + if (status == f_none) status = f_memory_adjust((void **) & items.array, sizeof(f_fss_item), items.size, new_length); \ if (status == f_none) { \ - if (new_length > content_childs.size) { \ - length_variable i = content_childs.size; \ + if (new_length > items.size) { \ + length_variable i = items.size; \ for (; i < new_length; i++) { \ - memset(&content_childs.array[i], 0, sizeof(f_fss_content_child)); \ + memset(&items.array[i], 0, sizeof(f_fss_item)); \ } \ } \ - content_childs.range.start = 1; \ - content_childs.range_stop = 0; \ - content_childs.size = new_length; \ - if (content_childs.used > content_childs.size) content_childs.used = new_length; \ + items.size = new_length; \ + if (items.used > items.size) items.used = new_length; \ } -#endif // _di_fss_content_childs_ +#endif // _di_fss_items_ /** - * This holds an array of f_fss_content_childs. + * This holds an array of f_fss_items. * * Each array row represents the nesting depth. * The top-level will not have any parent, so "parent" must be ignored on anything at index 0. * The parent identifier is expected to reference a position in the nesting depth immediately above it. + * @todo: consider instead of using a "parent", have setting set to 0 to represent no data. * - * array: an array of f_fss_content_childs objects. - * size: Total amount of allocated space. - * used: Total number of allocated spaces used. + * depth: An array of f_fss_items, with each index representing the depth. + * size: Total amount of allocated space. + * used: Total number of allocated spaces used. */ -#ifndef _di_fss_content_nest_ +#ifndef _di_fss_nest_ typedef struct { - f_fss_content_childs *array; - f_array_length size; - f_array_length used; - } f_fss_content_nest; + f_fss_items *depth; + + f_array_length size; + f_array_length used; + } f_fss_nest; - #define f_fss_content_nest_initialize { 0, 0, 0 } + #define f_fss_nest_initialize { 0, 0, 0 } /** * Reset a fss content nest to 0 (clear all values). * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * content_nest: the f_fss_content_nest structure to operate on. + * nest: the f_fss_nest structure to operate on. */ - #define f_macro_fss_content_nest_clear(content_nest) \ - content_nest.array = 0; \ - content_nest.size = 0; \ - content_nest.used = 0; + #define f_macro_fss_nest_clear(nest) \ + nest.depth = 0; \ + nest.size = 0; \ + nest.used = 0; /** * Create a new fss content nest. * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * status: the status to return. - * content_nest: the f_fss_content_nest structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * nest: the f_fss_nest structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_nest_new(status, content_nest, length) \ - content_nest.array = 0; \ - content_nest.size = 0; \ - content_nest.used = 0; \ - status = f_memory_new((void **) & content_nest.array, sizeof(f_fss_content_childs), new_length); \ + #define f_macro_fss_nest_new(status, nest, length) \ + nest.depth = 0; \ + nest.size = 0; \ + nest.used = 0; \ + status = f_memory_new((void **) & nest.depth, sizeof(f_fss_items), new_length); \ if (status == f_none) { \ - content_nest.size = new_length; \ - content_nest.used = 0; \ + nest.size = new_length; \ + nest.used = 0; \ } /** * Delete a fss content nest. * - * status: the status to return. - * content_nest: the f_fss_content_nest structure to operate on. + * status: the status to return. + * nest: the f_fss_nest structure to operate on. */ - #define f_macro_fss_content_nest_delete(status, content_nest) \ + #define f_macro_fss_nest_delete(status, nest) \ status = f_none; \ - content_nest.used = content_nest.size; \ - while (content_nest.used > 0) { \ - content_nest.used--; \ - f_macro_fss_content_childs_delete(status, content_nest.array[content_nest.used]); \ + nest.used = nest.size; \ + while (nest.used > 0) { \ + nest.used--; \ + f_macro_fss_items_delete(status, nest.depth[nest.used]); \ if (status != f_none) break; \ } \ - if (status == f_none) status = f_memory_delete((void **) & content_nest.array, sizeof(f_fss_content_childs), content_nest.size); \ - if (status == f_none) content_nest.size = 0; + if (status == f_none) status = f_memory_delete((void **) & nest.depth, sizeof(f_fss_items), nest.size); \ + if (status == f_none) nest.size = 0; /** * Destroy a fss content nest. * - * status: the status to return. - * content_nest: the f_fss_content_nest structure to operate on. + * status: the status to return. + * nest: the f_fss_nest structure to operate on. */ - #define f_macro_fss_content_nest_destroy(status, content_nest) \ + #define f_macro_fss_nest_destroy(status, nest) \ status = f_none; \ - content_nest.used = content_nest.size; \ - while (content_nest.used > 0) { \ - content_nest.used--; \ - f_macro_fss_content_childs_destroy(status, content_nest.array[content_nest.used]); \ + nest.used = nest.size; \ + while (nest.used > 0) { \ + nest.used--; \ + f_macro_fss_items_destroy(status, nest.depth[nest.used]); \ if (status != f_none) break; \ } \ - if (status == f_none) status = f_memory_delete((void **) & content_nest.array, sizeof(f_fss_content_childs), content_nest.size); \ - if (status == f_none) content_nest.size = 0; + if (status == f_none) status = f_memory_delete((void **) & nest.depth, sizeof(f_fss_items), nest.size); \ + if (status == f_none) nest.size = 0; /** * Delete a fss content nest. * - * content_nest: the f_fss_content_nest structure to operate on. + * nest: the f_fss_nest structure to operate on. */ - #define f_macro_fss_content_nest_delete_simple(content_nest) \ - content_nest.used = content_nest.size; \ - while (content_nest.used > 0) { \ - content_nest.used--; \ - f_macro_fss_content_childs_delete_simple(content_nest.array[content_nest.used]); \ - if (content_nest.used == 0) { \ - if (f_memory_delete((void **) & content_nest.array, sizeof(f_fss_content_childs), content_nest.size)) { \ - content_nest.size = 0; \ + #define f_macro_fss_nest_delete_simple(nest) \ + nest.used = nest.size; \ + while (nest.used > 0) { \ + nest.used--; \ + f_macro_fss_items_delete_simple(nest.depth[nest.used]); \ + if (nest.used == 0) { \ + if (f_memory_delete((void **) & nest.depth, sizeof(f_fss_items), nest.size)) { \ + nest.size = 0; \ } \ } \ } @@ -722,16 +713,16 @@ extern "C" { /** * Destroy a fss content nest. * - * content_nest: the f_fss_content_nest structure to operate on. + * nest: the f_fss_nest structure to operate on. */ - #define f_macro_fss_content_nest_destroy_simple(content_nest) \ - content_nest.used = content_nest.size; \ - while (content_nest.used > 0) { \ - content_nest.used--; \ - f_macro_fss_content_childs_destroy_simple(content_nest.array[content_nest.used]); \ - if (content_nest.used == 0) { \ - if (f_memory_destroy((void **) & content_nest.array, sizeof(f_fss_content_childs), content_nest.size)) { \ - content_nest.size = 0; \ + #define f_macro_fss_nest_destroy_simple(nest) \ + nest.used = nest.size; \ + while (nest.used > 0) { \ + nest.used--; \ + f_macro_fss_items_destroy_simple(nest.depth[nest.used]); \ + if (nest.used == 0) { \ + if (f_memory_destroy((void **) & nest.depth, sizeof(f_fss_items), nest.size)) { \ + nest.size = 0; \ } \ } \ } @@ -739,154 +730,155 @@ extern "C" { /** * Resize a fss content nest. * - * status: the status to return. - * content_nest: the f_fss_content_nest structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * nest: the f_fss_nest structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_nest_resize(status, content_nest, new_length) \ + #define f_macro_fss_nest_resize(status, nest, new_length) \ status = f_none; \ - if (new_length < content_nest.size) { \ - f_array_length i = content_nest.size - new_length; \ - for (; i < content_nest.size; i++) { \ - f_macro_fss_content_childs_delete(status, content_nest.array[i]); \ + if (new_length < nest.size) { \ + f_array_length i = nest.size - new_length; \ + for (; i < nest.size; i++) { \ + f_macro_fss_items_delete(status, nest.depth[i]); \ if (status != f_none) break; \ } \ } \ - if (status == f_none) status = f_memory_resize((void **) & content_nest.array, sizeof(f_fss_content_childs), content_nest.size, new_length); \ + if (status == f_none) status = f_memory_resize((void **) & nest.depth, sizeof(f_fss_items), nest.size, new_length); \ if (status == f_none) { \ - if (new_length > content_nest.size) { \ - f_array_length i = content_nest.size; \ + if (new_length > nest.size) { \ + f_array_length i = nest.size; \ for (; i < new_length; i++) { \ - memset(&content_nest.array[i], 0, sizeof(f_fss_content_childs)); \ + memset(&nest.depth[i], 0, sizeof(f_fss_items)); \ } \ } \ - content_nest.size = new_length; \ - if (content_nest.used > content_nest.size) content_nest.used = new_length; \ + nest.size = new_length; \ + if (nest.used > nest.size) nest.used = new_length; \ } /** * Adjust a fss content nest. * - * status: the status to return. - * content_nest: the f_fss_content_nest structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * nest: the f_fss_nest structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_nest_adjust(status, content_nest, new_length) \ + #define f_macro_fss_nest_adjust(status, nest, new_length) \ status = f_none; \ - if (new_length < content_nest.size) { \ - f_array_length i = content_nest.size - new_length; \ - for (; i < content_nest.size; i++) { \ - f_macro_fss_content_childs_destroy(status, content_nest.array[i]); \ + if (new_length < nest.size) { \ + f_array_length i = nest.size - new_length; \ + for (; i < nest.size; i++) { \ + f_macro_fss_items_destroy(status, nest.depth[i]); \ if (status != f_none) break; \ } \ } \ - if (status == f_none) status = f_memory_adjust((void **) & content_nest.array, sizeof(f_fss_content_child), content_nest.size, new_length); \ + if (status == f_none) status = f_memory_adjust((void **) & nest.depth, sizeof(f_fss_item), nest.size, new_length); \ if (status == f_none) { \ - if (new_length > content_nest.size) { \ - f_array_length i = content_nest.size; \ + if (new_length > nest.size) { \ + f_array_length i = nest.size; \ for (; i < new_length; i++) { \ - memset(&content_childs.array[i], 0, sizeof(f_fss_content_child)); \ + memset(&items.depth[i], 0, sizeof(f_fss_item)); \ } \ } \ - content_nest.size = new_length; \ - if (content_nest.used > content_nest.size) content_nest.used = new_length; \ + nest.size = new_length; \ + if (nest.used > nest.size) nest.used = new_length; \ } -#endif // _di_fss_content_nest_ +#endif // _di_fss_nest_ /** - * This holds an array of f_fss_content_nest. + * This holds an array of f_fss_nest. * - * array: an array of f_fss_content_nest objects. + * array: an array of f_fss_nest. * size: Total amount of allocated space. * used: Total number of allocated spaces used. */ -#ifndef _di_fss_content_nests_ +#ifndef _di_fss_nests_ typedef struct { - f_fss_content_nest *array; - f_array_length size; - f_array_length used; - } f_fss_content_nests; + f_fss_nest *array; + + f_array_length size; + f_array_length used; + } f_fss_nests; - #define f_fss_content_nests_initialize { 0, 0, 0 } + #define f_fss_nests_initialize { 0, 0, 0 } /** * Reset a fss content nests to 0 (clear all values). * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * content_nests: the f_fss_content_nests structure to operate on. + * nests: the f_fss_nests structure to operate on. */ - #define f_macro_fss_content_nests_clear(content_nests) \ - content_nests.array = 0; \ - content_nests.size = 0; \ - content_nests.used = 0; + #define f_macro_fss_nests_clear(nests) \ + nests.array = 0; \ + nests.size = 0; \ + nests.used = 0; /** * Create a new fss content nests. * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. * - * status: the status to return. - * content_nests: the f_fss_content_nests structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * nests: the f_fss_nests structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_nests_new(status, content_nests, length) \ - content_nests.array = 0; \ - content_nests.size = 0; \ - content_nests.used = 0; \ - status = f_memory_new((void **) & content_nests.array, sizeof(f_fss_content_nest), new_length); \ + #define f_macro_fss_nests_new(status, nests, length) \ + nests.array = 0; \ + nests.size = 0; \ + nests.used = 0; \ + status = f_memory_new((void **) & nests.array, sizeof(f_fss_nest), new_length); \ if (status == f_none) { \ - content_nests.size = new_length; \ - content_nests.used = 0; \ + nests.size = new_length; \ + nests.used = 0; \ } /** * Delete a fss content nests. * - * status: the status to return. - * content_nests: the f_fss_content_nests structure to operate on. + * status: the status to return. + * nests: the f_fss_nests structure to operate on. */ - #define f_macro_fss_content_nests_delete(content_nests) \ + #define f_macro_fss_nests_delete(nests) \ status = f_none; \ - content_nests.used = content_nests.size; \ - while (content_nests.used > 0) { \ - content_nests.used--; \ - f_macro_fss_content_nest_delete(status, content_nests.array[content_nests.used]); \ + nests.used = nests.size; \ + while (nests.used > 0) { \ + nests.used--; \ + f_macro_fss_nest_delete(status, nests.array[nests.used]); \ if (status != f_none) break; \ } \ - if (status == f_none) status = f_memory_delete((void **) & content_nests.array, sizeof(f_fss_content_nest), content_nests.size); \ - if (status == f_none) content_nests.size = 0; + if (status == f_none) status = f_memory_delete((void **) & nests.array, sizeof(f_fss_nest), nests.size); \ + if (status == f_none) nests.size = 0; /** * Destroy a fss content nests. * - * status: the status to return. - * content_nests: the f_fss_content_nests structure to operate on. + * status: the status to return. + * nests: the f_fss_nests structure to operate on. */ - #define f_macro_fss_content_nests_destroy(content_nests) \ + #define f_macro_fss_nests_destroy(nests) \ status = f_none; \ - content_nests.used = content_nests.size; \ - while (content_nests.used > 0) { \ - content_nests.used--; \ - f_macro_fss_content_nest_destroy(status, content_nests.array[content_nests.used]); \ + nests.used = nests.size; \ + while (nests.used > 0) { \ + nests.used--; \ + f_macro_fss_nest_destroy(status, nests.array[nests.used]); \ if (status != f_none) break; \ } \ - if (status == f_none) status = f_memory_destroy((void **) & content_nests.array, sizeof(f_fss_content_nest), content_nests.size); \ - if (status == f_none) content_nests.size = 0; + if (status == f_none) status = f_memory_destroy((void **) & nests.array, sizeof(f_fss_nest), nests.size); \ + if (status == f_none) nests.size = 0; /** * Delete a fss content nests. * - * content_nests: the f_fss_content_nests structure to operate on. + * nests: the f_fss_nests structure to operate on. */ - #define f_macro_fss_content_nests_delete_simple(content_nests) \ - content_nests.used = content_nests.size; \ - while (content_nests.used > 0) { \ - content_nests.used--; \ - f_macro_fss_content_nest_delete_simple(content_nests.array[content_nests.used]); \ - if (content_nests.used == 0) { \ - if (f_memory_delete((void **) & content_nests.array, sizeof(f_fss_content_nest), content_nests.size)) { \ - content_nests.size = 0; \ + #define f_macro_fss_nests_delete_simple(nests) \ + nests.used = nests.size; \ + while (nests.used > 0) { \ + nests.used--; \ + f_macro_fss_nest_delete_simple(nests.array[nests.used]); \ + if (nests.used == 0) { \ + if (f_memory_delete((void **) & nests.array, sizeof(f_fss_nest), nests.size)) { \ + nests.size = 0; \ } \ } \ } @@ -894,16 +886,16 @@ extern "C" { /** * Destroy a fss content nests. * - * content_nests: the f_fss_content_nests structure to operate on. + * nests: the f_fss_nests structure to operate on. */ - #define f_macro_fss_content_nests_destroy_simple(content_nests) \ - content_nests.used = content_nests.size; \ - while (content_nests.used > 0) { \ - content_nests.used--; \ - f_macro_fss_content_nest_destroy_simple(content_nests.array[content_nests.used]); \ - if (content_nests.used == 0) { \ - if (f_memory_destroy((void **) & content_nests.array, sizeof(f_fss_content_nest), content_nests.size)) { \ - content_nests.size = 0; \ + #define f_macro_fss_nests_destroy_simple(nests) \ + nests.used = nests.size; \ + while (nests.used > 0) { \ + nests.used--; \ + f_macro_fss_nest_destroy_simple(nests.array[nests.used]); \ + if (nests.used == 0) { \ + if (f_memory_destroy((void **) & nests.array, sizeof(f_fss_nest), nests.size)) { \ + nests.size = 0; \ } \ } \ } @@ -911,59 +903,59 @@ extern "C" { /** * Resize a fss content nests. * - * status: the status to return. - * content_nests: the f_fss_content_nests structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * nests: the f_fss_nests structure to operate on. + * new_length: the new size of the array. */ - #define f_macro_fss_content_nests_resize(status, content_nests, new_length) \ + #define f_macro_fss_nests_resize(status, nests, new_length) \ status = f_none; \ - if (new_length < content_nests.size) { \ - f_array_length i = content_nests.size - new_length; \ - for (; i < content_nests.size; i++) { \ - f_macro_fss_content_nest_delete(status, content_nests.array[i]); \ + if (new_length < nests.size) { \ + f_array_length i = nests.size - new_length; \ + for (; i < nests.size; i++) { \ + f_macro_fss_nest_delete(status, nests.array[i]); \ if (status != f_none) break; \ } \ } \ - if (status == f_none) status = f_memory_resize((void **) & content_nests.array, sizeof(f_fss_content_nest), content_nests.size, new_length); \ + if (status == f_none) status = f_memory_resize((void **) & nests.array, sizeof(f_fss_nest), nests.size, new_length); \ if (status == f_none) { \ - if (new_length > content_nests.size) { \ - f_array_length i = content_nests.size; \ + if (new_length > nests.size) { \ + f_array_length i = nests.size; \ for (; i < new_length; i++) { \ - memset(&content_nests.array[i], 0, sizeof(f_fss_content_nest)); \ + memset(&nests.array[i], 0, sizeof(f_fss_nest)); \ } \ } \ - content_nests.size = new_length; \ - if (content_nests.used > content_nests.size) content_nests.used = new_length; \ + nests.size = new_length; \ + if (nests.used > nests.size) nests.used = new_length; \ } /** * Adjust a fss content nests. * - * status: the status to return. - * content_nests: the f_fss_content_nests structure to operate on. - * new_length: the new size of the array. + * status: the status to return. + * nests: the f_fss_nests structure to operate on. + * new_length: he new size of the array. */ - #define f_macro_fss_content_nests_adjust(status, content_nests, new_length) \ + #define f_macro_fss_nests_adjust(status, nests, new_length) \ status = f_none; \ - if (new_length < content_nests.size) { \ - f_array_length i = content_nests.size - new_length; \ - for (; i < content_nests.size; i++) { \ - f_macro_fss_content_nest_destroy(status, content_nests.array[i]); \ + if (new_length < nests.size) { \ + f_array_length i = nests.size - new_length; \ + for (; i < nests.size; i++) { \ + f_macro_fss_nest_destroy(status, nests.array[i]); \ if (status != f_none) break; \ } \ } \ - if (status == f_none) status = f_memory_adjust((void **) & content_nests.array, sizeof(f_fss_content_nest), content_nests.size, new_length); \ + if (status == f_none) status = f_memory_adjust((void **) & nests.array, sizeof(f_fss_nest), nests.size, new_length); \ if (status == f_none) { \ - if (new_length > content_nests.size) { \ - f_array_length i = content_nests.size; \ + if (new_length > nests.size) { \ + f_array_length i = nests.size; \ for (; i < new_length; i++) { \ - memset(&content_nests.array[i], 0, sizeof(f_fss_content_nest)); \ + memset(&nests.array[i], 0, sizeof(f_fss_nest)); \ } \ } \ - content_nests.size = new_length; \ - if (content_nests.used > content_nests.size) content_nests.used = new_length; \ + nests.size = new_length; \ + if (nests.used > nests.size) nests.used = new_length; \ } -#endif // _di_fss_content_nests_ +#endif // _di_fss_nests_ #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_fss/c/fss_extended_list.c b/level_1/fl_fss/c/fss_extended_list.c index 96ad5d9..563fa69 100644 --- a/level_1/fl_fss/c/fss_extended_list.c +++ b/level_1/fl_fss/c/fss_extended_list.c @@ -181,7 +181,7 @@ extern "C" { #endif // _di_fl_fss_extended_list_object_read_ #ifndef _di_fl_fss_extended_list_content_read_ - f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_location *location, f_fss_content_nest *found) { + f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_location *location, f_fss_nest *found) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return f_status_set_error(f_invalid_parameter); if (location == 0) return f_status_set_error(f_invalid_parameter); @@ -199,9 +199,16 @@ extern "C" { f_string_lengths positions_start = f_string_lengths_initialize; fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*location)) - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), positions_start, delimits, f_none_on_eos, f_none_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), positions_start, delimits, f_none_on_eos, f_none_on_stop) - fl_macro_fss_allocate_content_nest_if_necessary((*found), delimits); + if (found->used + 1 >= found->size) { + f_macro_fss_nest_resize(status, (*found), found->size + f_fss_default_allocation_step + 1); + + if (f_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + } f_array_length depth = 0; f_string_length position_previous = location->start; @@ -215,7 +222,7 @@ extern "C" { return status; } - // initialize depth 0 start position. + // initialize depth 1 start position. // positions_start.used is used as a max depth (such that positions_start.used == max depth + 1). positions_start.array[0] = location->start; positions_start.used = 1; @@ -234,10 +241,10 @@ extern "C" { } if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop) + fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop) } continue; @@ -274,10 +281,10 @@ extern "C" { } // while if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) } // All slashes for an open are delimited (because it could represent a slash in the object name). @@ -327,10 +334,10 @@ extern "C" { } // while if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) } // this is a valid object open/close that has been delimited, save the slash delimit positions. @@ -376,7 +383,7 @@ extern "C" { if (is_object) { depth++; - if (depth >= positions_start.size) { + if (depth > positions_start.size) { f_macro_string_lengths_resize(status, positions_start, positions_start.size + f_fss_default_allocation_step); if (f_status_is_error(status)) { @@ -387,8 +394,8 @@ extern "C" { } } - if (positions_start.used <= depth) { - positions_start.used = depth + 1; + if (positions_start.used < depth) { + positions_start.used = depth; } positions_start.array[depth] = location_newline + 1; @@ -460,10 +467,10 @@ extern "C" { } // while if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) } if (buffer->string[location->start] == f_string_eol) { @@ -507,10 +514,10 @@ extern "C" { } // while if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) } } @@ -553,15 +560,17 @@ extern "C" { } // while if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) } if (buffer->string[location->start] == f_string_eol) { - if (found->used >= found->size) { - f_macro_fss_content_nest_resize(status, (*found), found->size + f_fss_default_allocation_step); + if (depth == 0) break; + + if (depth + 1 >= found->size) { + f_macro_fss_nest_resize(status, (*found), found->size + f_fss_default_allocation_step); if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); @@ -571,8 +580,8 @@ extern "C" { } } - if (found->array[depth].used >= found->array[depth].size) { - f_macro_fss_content_childs_resize(status, found->array[depth], found->array[depth].size + f_fss_default_allocation_step); + if (found->depth[depth].used >= found->depth[depth].size) { + f_macro_fss_items_resize(status, found->depth[depth], found->depth[depth].size + f_fss_default_allocation_step); if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); @@ -582,10 +591,10 @@ extern "C" { } } - f_array_length position = found->array[depth].used; + f_array_length position = found->depth[depth].used; - if (found->array[depth].array[position].content.used >= found->array[depth].array[position].content.size) { - f_macro_fss_content_resize(status, found->array[depth].array[position].content, found->array[depth].array[position].content.size + f_fss_default_allocation_step); + if (found->depth[depth].array[position].content.size != 1) { + f_macro_fss_content_resize(status, found->depth[depth].array[position].content, 1); if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); @@ -595,16 +604,16 @@ extern "C" { } } - found->array[depth].range.start = positions_start.array[depth]; - found->array[depth].range.stop = last_newline; - found->array[depth].array[position].object.start = object.start; - found->array[depth].array[position].object.stop = object.stop; - found->array[depth].array[position].content.array[found->array[depth].array[position].content.used].stop = last_newline; - found->array[depth].array[position].content.used++; - found->array[depth].used++; - found->used = positions_start.used; + found->depth[depth].array[position].object.start = object.start; + found->depth[depth].array[position].object.stop = object.stop; + found->depth[depth].array[position].content.array[0].start = positions_start.array[depth]; + found->depth[depth].array[position].content.array[0].stop = last_newline; + found->depth[depth].array[position].content.used = 1; + found->depth[depth].used++; - if (depth == 0) break; + if (depth >= found->used) { + found->used = depth + 1; + } last_newline = location->start; depth--; @@ -627,10 +636,10 @@ extern "C" { } // while if (depth > 0) { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) } } @@ -660,12 +669,12 @@ extern "C" { return status; } - found->array[0].range.start = positions_start.array[0]; - found->array[0].range.stop = location->start; + found->depth[0].array[found->depth[0].used].content.array[0].start = positions_start.array[0]; + found->depth[0].array[found->depth[0].used].content.array[0].stop = location->start; + found->depth[0].used++; location->start = last_newline + 1; - found->used++; - fl_macro_fss_content_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop) + fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop) f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); diff --git a/level_1/fl_fss/c/fss_extended_list.h b/level_1/fl_fss/c/fss_extended_list.h index 6de6fef..8653853 100644 --- a/level_1/fl_fss/c/fss_extended_list.h +++ b/level_1/fl_fss/c/fss_extended_list.h @@ -73,6 +73,10 @@ extern "C" { * This will update the buffer at the given range with any placeholders to unescape any escaped data. * Calling this more than once on the same buffer range could result in multiple unescaping. * + * This operates on the assumption that found.array[0].array[found.array[0].used].content is the current content being processed. + * Therefore the object for this content will also need to be found.array[0].array[found.array[0].used].object. + * The object at depth 0 will not be populated, but all nested objects will be populated at their respective depth along with the content. + * * @param buffer * The buffer to read from. * This will be updated with delimit placeholders as it is being processed. @@ -99,7 +103,7 @@ extern "C" { * f_invalid_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_fl_fss_extended_list_content_read_ - extern f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_location *location, f_fss_content_nest *found); + extern f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_location *location, f_fss_nest *found); #endif // _di_fl_fss_extended_list_content_read_ /** diff --git a/level_1/fl_fss/c/fss_macro.h b/level_1/fl_fss/c/fss_macro.h index eeca21a..22e7143 100644 --- a/level_1/fl_fss/c/fss_macro.h +++ b/level_1/fl_fss/c/fss_macro.h @@ -152,8 +152,8 @@ extern "C" { } #endif // _di_fl_macro_fss_allocate_content_if_necessary_ -#ifndef _di_fl_macro_fss_content_nest_return_on_overflow_ - #define fl_macro_fss_content_nest_return_on_overflow(buffer, location, found, delimits, positions, eos_status, stop_status) \ +#ifndef _di_fl_macro_fss_nest_return_on_overflow_ + #define fl_macro_fss_nest_return_on_overflow(buffer, location, found, delimits, positions, eos_status, stop_status) \ if (location.start >= buffer.used) { \ f_status macro_allocation_status = f_none; \ f_macro_string_lengths_delete(macro_allocation_status, delimits); \ @@ -170,10 +170,10 @@ extern "C" { /* @todo: found.array[found.used].stop = location.stop; */ \ return stop_status; \ } -#endif // _di_fl_macro_fss_content_nest_return_on_overflow_ +#endif // _di_fl_macro_fss_nest_return_on_overflow_ -#ifndef _di_fl_macro_fss_content_nest_delimited_return_on_overflow_ - #define fl_macro_fss_content_nest_delimited_return_on_overflow(buffer, location, found, delimits, positions, eos_status, stop_status) \ +#ifndef _di_fl_macro_fss_nest_delimited_return_on_overflow_ + #define fl_macro_fss_nest_delimited_return_on_overflow(buffer, location, found, delimits, positions, eos_status, stop_status) \ if (location.start >= buffer.used) { \ f_status macro_allocation_status = f_none; \ f_string_length i = 0; \ @@ -201,22 +201,7 @@ extern "C" { return stop_status; \ } // @todo: found.array[found.used].stop = location.stop; -#endif // _di_fl_macro_fss_content_nest_delimited_return_on_overflow_ - -#ifndef _di_fl_macro_fss_allocate_content_nest_if_necessary_ - #define fl_macro_fss_allocate_content_nest_if_necessary(content, delimits) \ - if (content.used >= content.size) { \ - f_status status = f_none; \ - \ - f_macro_fss_content_nest_resize(status, content, content.size + f_fss_default_allocation_step); \ - if (f_status_is_error(status)) { \ - f_status macro_allocation_status = f_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ - \ - return status; \ - } \ - } -#endif // _di_fl_macro_fss_allocate_content_nest_if_necessary_ +#endif // _di_fl_macro_fss_nest_delimited_return_on_overflow_ #ifndef _di_fl_macro_fss_object_seek_till_newline_ #define fl_macro_fss_object_seek_till_newline(buffer, location, delimits, eos_status, stop_status) \ diff --git a/level_2/fll_fss/c/fss_extended_list.c b/level_2/fll_fss/c/fss_extended_list.c index fa9018e..62a3c0d 100644 --- a/level_2/fll_fss/c/fss_extended_list.c +++ b/level_2/fll_fss/c/fss_extended_list.c @@ -5,64 +5,52 @@ extern "C" { #endif #ifndef _di_fll_fss_extended_list_read_ - f_return_status fll_fss_extended_list_read(f_string_dynamic *buffer, f_string_location *input, f_fss_objects *objects, f_fss_content_nests *contents) { + f_return_status fll_fss_extended_list_read(f_string_dynamic *buffer, f_string_location *input, f_fss_nest *nest) { #ifndef _di_level_3_parameter_checking_ if (buffer == 0) return f_status_set_error(f_invalid_parameter); - if (objects == 0) return f_status_set_error(f_invalid_parameter); - if (contents == 0) return f_status_set_error(f_invalid_parameter); + if (nest == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_3_parameter_checking_ f_status status = f_none; - f_string_length initial_used = objects->used; + f_string_length initial_used = 0; bool found_data = f_false; - do { - if (objects->used >= objects->size) { - f_macro_fss_objects_resize(status, (*objects), objects->used + f_fss_default_allocation_step); - - if (f_status_is_error(status)) { - return status; - } + if (nest->used == 0) { + f_macro_fss_nest_resize(status, (*nest), f_fss_default_allocation_step); + } + else { + initial_used = nest->depth[0].used; + } - f_macro_fss_content_nests_resize(status, (*contents), contents->used + f_fss_default_allocation_step); + do { + do { + if (nest->depth[0].used >= nest->depth[0].size) { + f_macro_fss_items_resize(status, nest->depth[0], nest->depth[0].used + f_fss_default_allocation_step); - if (f_status_is_error(status)) { - return status; + if (f_status_is_error(status)) { + return status; + } } - } - do { - status = fl_fss_extended_list_object_read(buffer, input, &objects->array[objects->used]); + status = fl_fss_extended_list_object_read(buffer, input, &nest->depth[0].array[nest->depth[0].used].object); if (input->start >= input->stop || input->start >= buffer->used) { if (status == fl_fss_found_object || status == fl_fss_found_object_no_content) { - objects->used++; - - if (contents->array[contents->used].used >= contents->array[contents->used].size) { - f_status status = f_none; - - f_macro_fss_content_nest_resize(status, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); - - if (f_status_is_error(status)) { - return status; - } - } - - contents->used++; + nest->depth[0].used++; return fl_fss_found_object_no_content; } if (found_data) { if (input->start >= buffer->used) { - return f_none_on_eos; + return f_none_on_eos; } return f_none_on_stop; } else { if (input->start >= buffer->used) { - return f_no_data_on_eos; + return f_no_data_on_eos; } return f_no_data_on_stop; @@ -71,17 +59,17 @@ extern "C" { if (status == fl_fss_found_object) { found_data = f_true; - status = fl_fss_extended_list_content_read(buffer, input, &contents->array[contents->used]); + status = fl_fss_extended_list_content_read(buffer, input, nest); break; } else if (status == fl_fss_found_object_no_content) { found_data = f_true; - if (contents->array[contents->used].used >= contents->array[contents->used].size) { + if (nest->depth[0].used >= nest->depth[0].size) { f_status status = f_none; - f_macro_fss_content_nest_resize(status, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); + f_macro_fss_items_resize(status, nest->depth[0], nest->depth[0].used + f_fss_default_allocation_step); if (f_status_is_error(status)) { return status; @@ -93,15 +81,13 @@ extern "C" { } while (status == fl_fss_found_no_object); if (status == f_none_on_eos || status == f_none_on_stop) { - contents->array[contents->used].used++; - objects->used++; - contents->used++; + nest->depth[0].used++; return status; } else if (status == f_no_data_on_eos || status == f_no_data_on_stop) { // If at least some valid object was found, then return f_none equivalents. - if (objects->used > initial_used) { + if (nest->depth[0].used > initial_used) { if (status == f_no_data_on_eos) return f_none_on_eos; if (status == f_no_data_on_stop) return f_none_on_stop; } @@ -114,8 +100,7 @@ extern "C" { // When content is found, the input->start is incremented, if content is found at input->stop, then input->start will be > input.stop. else if (input->start >= input->stop || input->start >= buffer->used) { if (status == fl_fss_found_object || status == fl_fss_found_content || status == fl_fss_found_no_content || status == fl_fss_found_object_no_content) { - objects->used++; - contents->used++; + nest->depth[0].used++; } if (input->start >= buffer->used) { @@ -125,8 +110,7 @@ extern "C" { return f_none_on_stop; } - objects->used++; - contents->used++; + nest->depth[0].used++; } while (input->start < f_string_max_size); return f_status_is_error(f_number_overflow); diff --git a/level_2/fll_fss/c/fss_extended_list.h b/level_2/fll_fss/c/fss_extended_list.h index e28030e..792a31f 100644 --- a/level_2/fll_fss/c/fss_extended_list.h +++ b/level_2/fll_fss/c/fss_extended_list.h @@ -34,10 +34,8 @@ extern "C" { * The buffer to read from. * @param location * The location within the buffer that is currently being read. - * @param objects - * This will be populated with all valid objects found. - * @param contents - * This will be populated with all valid contents found. + * @param nest + * An nested set of all objects and content. * * @return * f_none on success. @@ -53,7 +51,7 @@ extern "C" { * f_number_overflow (with error bit) if the maximimum buffer size is reached. */ #ifndef _di_fll_fss_extended_list_read_ - extern f_return_status fll_fss_extended_list_read(f_string_dynamic *buffer, f_string_location *input, f_fss_objects *objects, f_fss_content_nests *contents); + extern f_return_status fll_fss_extended_list_read(f_string_dynamic *buffer, f_string_location *input, f_fss_nest *nest); #endif // _di_fll_fss_extended_list_read_ /** diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c index 2fea610..99fc9b1 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c @@ -224,7 +224,7 @@ extern "C" { fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } else if (status == f_error_allocation || status == f_error_reallocation) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory"); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory."); } else if (status == f_incomplete_utf_on_stop) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at stop position (at "); diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-fss_basic_read.c index 15fa7fc..c06cdee 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.c +++ b/level_3/fss_basic_read/c/private-fss_basic_read.c @@ -224,7 +224,7 @@ extern "C" { fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } else if (status == f_error_allocation || status == f_error_reallocation) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory"); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory."); } else if (status == f_incomplete_utf_on_stop) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at stop position (at "); diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.c b/level_3/fss_extended_list_read/c/fss_extended_list_read.c index 92e29e7..91a8ab5 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.c @@ -19,15 +19,20 @@ extern "C" { fll_program_print_help_option(data.context, fss_extended_list_read_short_at, fss_extended_list_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); fll_program_print_help_option(data.context, fss_extended_list_read_short_depth, fss_extended_list_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); + fll_program_print_help_option(data.context, fss_extended_list_read_short_empty, fss_extended_list_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); fll_program_print_help_option(data.context, fss_extended_list_read_short_line, fss_extended_list_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print only the content at the given line."); fll_program_print_help_option(data.context, fss_extended_list_read_short_name, fss_extended_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); fll_program_print_help_option(data.context, fss_extended_list_read_short_object, fss_extended_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object instead of the content."); fll_program_print_help_option(data.context, fss_extended_list_read_short_select, fss_extended_list_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); - fll_program_print_help_option(data.context, fss_extended_list_read_short_total, fss_extended_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of objects."); + fll_program_print_help_option(data.context, fss_extended_list_read_short_total, fss_extended_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); fll_program_print_help_usage(data.context, fss_extended_list_read_name, "filename(s)"); - printf(" This program will print the content associated with the given object and content data based on the FSS-0003 Extended List standard.%c", f_string_eol); + fl_color_print(f_standard_output, data.context.important, data.context.reset, " Notes:"); + + printf("%c", f_string_eol, f_string_eol); + + printf(" This program will print the content associated with the given object and content data based on the FSS-0002 Basic List standard.%c", f_string_eol); printf("%c", f_string_eol); @@ -53,21 +58,13 @@ extern "C" { printf(" The parameter "); fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_depth); - printf(" should be in numeric order, but values in between may be skipped.%c", f_string_eol); + printf(" must be in numeric order, but values in between may be skipped.%c", f_string_eol); printf(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%c", f_string_eol); printf(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol); printf("%c", f_string_eol); printf(" The parameter "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_at); - printf(" cannot be used with the parameter "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_name); - printf(" at the same depth.%c", f_string_eol); - - printf("%c", f_string_eol); - - printf(" The parameter "); fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_select); printf(" selects a content index at a given depth.%c", f_string_eol); printf(" (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol); @@ -75,10 +72,22 @@ extern "C" { printf("%c", f_string_eol); printf(" Specify both "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_total); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_object); printf(" and the "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_line); - printf(" parameters to get the total lines.%c", f_string_eol); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_total); + printf(" parameters to get the total objects.%c", f_string_eol); + + printf("%c", f_string_eol); + + printf(" When both "); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_at); + printf(" and "); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_name); + printf(" parameters are specified (at the same depth), the "); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_at); + printf(" parameter value will be treated as a position relative to the specified "); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_name); + printf(" parameter value.%c", f_string_eol); printf("%c", f_string_eol); @@ -124,8 +133,6 @@ extern "C" { status = f_none; } - f_status status2 = f_none; - if (data->parameters[fss_extended_list_read_parameter_help].result == f_console_result_found) { fss_extended_list_read_print_help(*data); } @@ -133,8 +140,48 @@ extern "C" { fll_program_print_version(fss_extended_list_read_version); } else if (data->remaining.used > 0 || data->process_pipe) { + if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_at); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_depth); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_line); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_name); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a string."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_select); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_found) { - if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_found) { + if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_object); fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameter with the '"); @@ -155,21 +202,47 @@ extern "C" { } } - f_string_length counter = 0; - f_string_length target = 0; - f_string_length original_size = data->file_position.total_elements; + if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_line); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_total); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' parameter."); - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - target = (f_string_length) atoll(arguments.argv[data->parameters[fss_extended_list_read_parameter_at].additional.array[0]]); + return f_status_set_error(f_invalid_parameter); + } } + fss_extended_list_read_depths depths = fss_extended_list_read_depths_initialize; + + f_string_length counter = 0; + f_string_length original_size = data->file_position.total_elements; + status = fss_extended_list_read_main_preprocess_depth(arguments, *data, &depths); if (f_status_is_error(status)) { - macro_fss_extended_list_read_depths_delete(status2, depths); + macro_fss_extended_list_read_depths_delete_simple(depths); fss_extended_list_read_delete_data(data); return status; } + // Requested depths cannot be greater than contents depth. + if (depths.used > data->nest.used) { + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + fprintf(f_standard_output, "0%c", f_string_eol); + return f_none; + } + + return f_none; + } + + if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_select); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' parameter requires a positive number."); + return f_status_set_error(f_invalid_parameter); + } + if (data->process_pipe) { f_file file = f_file_initialize; @@ -179,70 +252,79 @@ extern "C" { if (f_status_is_error(status)) { fss_extended_list_read_print_file_error(data->context, "fl_file_read_fifo", "-", f_status_set_fine(status)); + macro_fss_extended_list_read_depths_delete_simple(depths); fss_extended_list_read_delete_data(data); return status; } - status = fss_extended_list_read_main_process_file(arguments, data, "-", target); + status = fss_extended_list_read_main_process_file(arguments, data, "-", depths); if (f_status_is_error(status)) { + macro_fss_extended_list_read_depths_delete_simple(depths); + fss_extended_list_read_delete_data(data); return status; } // Clear buffers before continuing. - f_macro_fss_contents_delete(status2, data->contents); - f_macro_fss_objects_delete(status2, data->objects); - f_macro_string_dynamic_delete(status2, data->buffer); + f_macro_fss_nest_delete_simple(data->nest); + f_macro_string_dynamic_delete_simple(data->buffer); } - for (; counter < data->remaining.used; counter++) { - f_file file = f_file_initialize; + if (data->remaining.used > 0) { + for (; counter < data->remaining.used; counter++) { + f_file file = f_file_initialize; - status = f_file_open(&file, arguments.argv[data->remaining.array[counter]]); + status = f_file_open(&file, arguments.argv[data->remaining.array[counter]]); - data->file_position.total_elements = original_size; + data->file_position.total_elements = original_size; - if (f_status_is_error(status)) { - fss_extended_list_read_print_file_error(data->context, "f_file_open", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); - fss_extended_list_read_delete_data(data); - return f_status_set_error(status); - } + if (f_status_is_error(status)) { + fss_extended_list_read_print_file_error(data->context, "f_file_open", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); + macro_fss_extended_list_read_depths_delete_simple(depths); + fss_extended_list_read_delete_data(data); + return status; + } - if (data->file_position.total_elements == 0) { - fseek(file.address, 0, SEEK_END); + if (data->file_position.total_elements == 0) { + fseek(file.address, 0, SEEK_END); - data->file_position.total_elements = ftell(file.address); + data->file_position.total_elements = ftell(file.address); - // Skip past empty files. - if (data->file_position.total_elements == 0) { - f_file_close(&file); - continue; + // Sskip past empty files. + if (data->file_position.total_elements == 0) { + f_file_close(&file); + continue; + } + + fseek(file.address, 0, SEEK_SET); } - fseek(file.address, 0, SEEK_SET); - } + status = fl_file_read(file, data->file_position, &data->buffer); - status = fl_file_read(file, data->file_position, &data->buffer); + f_file_close(&file); - f_file_close(&file); + if (f_status_is_error(status)) { + fss_extended_list_read_print_file_error(data->context, "fl_file_read", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); + macro_fss_extended_list_read_depths_delete_simple(depths); + fss_extended_list_read_delete_data(data); + return status; + } - if (f_status_is_error(status)) { - fss_extended_list_read_print_file_error(data->context, "fl_file_read", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); - fss_extended_list_read_delete_data(data); - return f_status_set_error(status); - } + status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths); - status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], target); + if (f_status_is_error(status)) { + macro_fss_extended_list_read_depths_delete_simple(depths); + fss_extended_list_read_delete_data(data); + return status; + } - if (f_status_is_error(status)) { - return status; - } + // Clear buffers before repeating the loop. + f_macro_fss_nest_delete_simple(data->nest); + f_macro_string_dynamic_delete_simple(data->buffer); + } // for + } - // Clear buffers before repeating the loop. - f_macro_fss_content_nests_delete(status2, data->contents); - f_macro_fss_objects_delete(status2, data->objects); - f_macro_string_dynamic_delete(status2, data->buffer); - } // for + macro_fss_extended_list_read_depths_delete_simple(depths); } else { fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files."); @@ -260,17 +342,17 @@ extern "C" { f_string_length i = 0; while (i < fss_extended_list_read_total_parameters) { - f_macro_string_lengths_delete(status, data->parameters[i].locations); - f_macro_string_lengths_delete(status, data->parameters[i].additional); + f_macro_string_lengths_delete_simple(data->parameters[i].locations); + f_macro_string_lengths_delete_simple(data->parameters[i].additional); i++; } // while - f_macro_fss_content_nests_delete(status, data->contents); - f_macro_fss_objects_delete(status, data->objects); - f_macro_string_dynamic_delete(status, data->buffer); - f_macro_string_lengths_delete(status, data->remaining); + f_macro_fss_nest_delete_simple(data->nest); + + f_macro_string_dynamic_delete_simple(data->buffer); + f_macro_string_lengths_delete_simple(data->remaining); - fl_macro_color_context_delete(status, data->context); + fl_macro_color_context_delete_simple(data->context); return f_none; } diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.h b/level_3/fss_extended_list_read/c/fss_extended_list_read.h index 91187c2..8f66cd1 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.h @@ -59,6 +59,7 @@ extern "C" { #ifndef _di_fss_extended_list_read_defines_ #define fss_extended_list_read_short_at "a" #define fss_extended_list_read_short_depth "d" + #define fss_extended_list_read_short_empty "e" #define fss_extended_list_read_short_line "l" #define fss_extended_list_read_short_name "n" #define fss_extended_list_read_short_object "o" @@ -67,6 +68,7 @@ extern "C" { #define fss_extended_list_read_long_at "at" #define fss_extended_list_read_long_depth "depth" + #define fss_extended_list_read_long_empty "empty" #define fss_extended_list_read_long_line "line" #define fss_extended_list_read_long_name "name" #define fss_extended_list_read_long_object "object" @@ -82,6 +84,7 @@ extern "C" { fss_extended_list_read_parameter_at, fss_extended_list_read_parameter_depth, + fss_extended_list_read_parameter_empty, fss_extended_list_read_parameter_line, fss_extended_list_read_parameter_name, fss_extended_list_read_parameter_object, @@ -98,6 +101,7 @@ extern "C" { f_console_parameter_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, f_false, f_console_type_inverse), \ f_console_parameter_initialize(fss_extended_list_read_short_at, fss_extended_list_read_long_at, 0, f_true, f_console_type_normal), \ f_console_parameter_initialize(fss_extended_list_read_short_depth, fss_extended_list_read_long_depth, 0, f_true, f_console_type_normal), \ + f_console_parameter_initialize(fss_extended_list_read_short_empty, fss_extended_list_read_long_empty, 0, f_false, f_console_type_normal), \ f_console_parameter_initialize(fss_extended_list_read_short_line, fss_extended_list_read_long_line, 0, f_true, f_console_type_normal), \ f_console_parameter_initialize(fss_extended_list_read_short_name, fss_extended_list_read_long_name, 0, f_true, f_console_type_normal), \ f_console_parameter_initialize(fss_extended_list_read_short_object, fss_extended_list_read_long_object, 0, f_false, f_console_type_normal), \ @@ -113,8 +117,7 @@ extern "C" { f_console_parameter parameters[fss_extended_list_read_total_parameters]; f_string_dynamic buffer; - f_fss_objects objects; - f_fss_content_nests contents; + f_fss_nest nest; f_file_position file_position; f_string_lengths remaining; bool process_pipe; @@ -126,8 +129,7 @@ extern "C" { { \ f_console_parameter_initialize_fss_extended_list_read, \ f_string_dynamic_initialize, \ - f_fss_objects_initialize, \ - f_fss_content_nests_initialize, \ + f_fss_nest_initialize, \ f_file_position_initialize, \ f_string_lengths_initialize, \ f_false, \ diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index 75a4c4b..27babba 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -18,441 +18,577 @@ extern "C" { } #endif // _di_fss_extended_list_read_print_file_error_ +#ifndef _di_fss_extended_list_read_print_number_argument_error_ + void fss_extended_list_read_print_number_argument_error(const fl_color_context context, const f_string function_name, const f_string parameter_name, const f_string argument, const f_status status) { + + if (status == f_invalid_parameter) { + fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling "); + fl_color_print(f_standard_error, context.notable, context.reset, "%s()", function_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "."); + } + else if (status == f_number_invalid) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is not a valid number for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_number_underflow) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is too small for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_number_overflow) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is too large for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_number_negative) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is negative, which is not allowed for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_number_positive) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' contains a '"); + fl_color_print(f_standard_error, context.notable, context.reset, "+"); + fl_color_print(f_standard_error, context.error, context.reset, "', which is not allowed for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_no_data) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "' must not be an empty string."); + } + else { + fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: An unhandled error ("); + fl_color_print(f_standard_error, context.notable, context.reset, "%u", status); + fl_color_print(f_standard_error, context.error, context.reset, ") has occurred while calling "); + fl_color_print(f_standard_error, context.notable, context.reset, "%s()", function_name); + fl_color_print(f_standard_error, context.error, context.reset, "' for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print(f_standard_error, context.error, context.reset, "' with the value '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + } +#endif // _di_fss_extended_list_read_print_number_argument_error_ + #ifndef _di_fss_extended_list_read_main_preprocess_depth_ f_return_status fss_extended_list_read_main_preprocess_depth(const f_console_arguments arguments, const fss_extended_list_read_data data, fss_extended_list_read_depths *depths) { f_status status = f_none; - // pre-process the depth and depth-sensitive parameters. - if (data.parameters[fss_extended_list_read_parameter_depth].result == f_console_result_additional) { - macro_fss_extended_list_read_depths_new(status, (*depths), data.parameters[fss_extended_list_read_parameter_depth].locations.used); + { + f_array_length depth_size = 1; + + if (data.parameters[fss_extended_list_read_parameter_depth].result == f_console_result_additional) { + depth_size = data.parameters[fss_extended_list_read_parameter_depth].additional.used; + } + + macro_fss_extended_list_read_depths_new(status, (*depths), depth_size); if (f_status_is_error(status)) { - f_status status2 = f_none; fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); - - macro_fss_extended_list_read_depths_delete(status2, (*depths)); - return f_status_set_error(f_invalid_parameter); + return status; } - f_array_length depth_position = data.parameters[fss_extended_list_read_parameter_depth].additional.array[0]; - f_array_length at_index = 0; - f_array_length name_index = 0; + depths->used = depth_size; + } + + f_array_length position_depth = 0; + f_array_length position_at = 0; + f_array_length position_name = 0; + + for (f_array_length 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; + depths->array[i].value_name = f_string_eos; + + if (data.parameters[fss_extended_list_read_parameter_depth].additional.used == 0) { + position_depth = 0; + } + else { + position_depth = data.parameters[fss_extended_list_read_parameter_depth].additional.array[i]; - depths->array[0].depth = (f_string_length) atoll(arguments.argv[depth_position]); - depths->array[0].parameter = 0; - depths->array[0].position = 0; - depths->used = 1; + status = fl_console_parameter_to_number_unsigned(arguments.argv[position_depth], &depths->array[i].depth); - f_string_length depth_previous = depths->array[0].depth; - f_string_length depth_current = depths->array[0].depth; + if (f_status_is_error(status)) { + fss_extended_list_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_extended_list_read_long_depth, arguments.argv[position_depth], f_status_set_fine(status)); + return status; + } + } if (data.parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - for (; at_index < data.parameters[fss_extended_list_read_parameter_at].additional.used; at_index++) { - if (data.parameters[fss_extended_list_read_parameter_at].additional.array[at_index] > depth_position) { - if (data.parameters[fss_extended_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_extended_list_read_parameter_at].additional.array[at_index] > data.parameters[fss_extended_list_read_parameter_depth].additional.array[1]) { - break; - } - } + for (; position_at < data.parameters[fss_extended_list_read_parameter_at].additional.used; position_at++) { + if (data.parameters[fss_extended_list_read_parameter_at].additional.array[position_at] < position_depth) { + continue; + } - depths->array[0].parameter = fss_extended_list_read_parameter_at; + if (i + 1 < depths->used && data.parameters[fss_extended_list_read_parameter_at].additional.array[position_at] > data.parameters[fss_extended_list_read_parameter_depth].additional.array[i + 1]) { + break; } - } // for - } - if (data.parameters[fss_extended_list_read_parameter_name].result == f_console_result_additional) { - for (; name_index < data.parameters[fss_extended_list_read_parameter_name].additional.used; name_index++) { - if (data.parameters[fss_extended_list_read_parameter_name].additional.array[name_index] > depth_position) { - if (data.parameters[fss_extended_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_extended_list_read_parameter_name].additional.array[name_index] > data.parameters[fss_extended_list_read_parameter_depth].additional.array[1]) { - break; - } - } + depths->array[i].index_at = data.parameters[fss_extended_list_read_parameter_at].additional.array[position_at]; - if (depths->array[0].parameter == fss_extended_list_read_parameter_at) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The '--%s' and '--%s' parameters cannot be specified at the same time (specified for depth '%llu').", fss_extended_list_read_long_at, fss_extended_list_read_long_name, depth_current); - return f_status_set_error(f_invalid_parameter); - } + status = fl_console_parameter_to_number_unsigned(arguments.argv[depths->array[i].index_at], &depths->array[i].value_at); - depths->array[0].parameter = fss_extended_list_read_parameter_name; + if (f_status_is_error(status)) { + fss_extended_list_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_extended_list_read_long_at, arguments.argv[depths->array[i].index_at], f_status_set_fine(status)); + return status; } } // for } - for (f_array_length i = 1; i < data.parameters[fss_extended_list_read_parameter_depth].locations.used; i++) { - depth_position = data.parameters[fss_extended_list_read_parameter_depth].additional.array[i]; - depth_current = (f_string_length) atoll(arguments.argv[depth_position]); - - if (depth_current > depth_previous) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The depth '%llu' cannot be specified before the depth '%llu'.", depth_previous, depth_current); - return f_status_set_error(f_invalid_parameter); - } - - if (depth_current == depth_previous) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The depth '%llu' cannot be the same as the depth '%llu'.", depth_previous, depth_current); - return f_status_set_error(f_invalid_parameter); - } - - if (data.parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - for (; at_index < data.parameters[fss_extended_list_read_parameter_at].additional.used; at_index++) { - if (data.parameters[fss_extended_list_read_parameter_at].additional.array[at_index] > depth_position) { - if (data.parameters[fss_extended_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_extended_list_read_parameter_at].additional.array[at_index] > data.parameters[fss_extended_list_read_parameter_depth].additional.array[i+1]) { - break; - } - } + if (data.parameters[fss_extended_list_read_parameter_name].result == f_console_result_additional) { + for (; position_name < data.parameters[fss_extended_list_read_parameter_name].additional.used; position_name++) { + if (data.parameters[fss_extended_list_read_parameter_name].additional.array[position_name] < position_depth) { + continue; + } - depths->array[i].parameter = fss_extended_list_read_parameter_at; - depths->array[i].position = data.parameters[fss_extended_list_read_parameter_at].additional.array[i]; - } - } // for - } + if (i + 1 < depths->used && data.parameters[fss_extended_list_read_parameter_name].additional.array[position_name] > data.parameters[fss_extended_list_read_parameter_depth].additional.array[i + 1]) { + break; + } - if (data.parameters[fss_extended_list_read_parameter_name].result == f_console_result_additional) { - for (; name_index < data.parameters[fss_extended_list_read_parameter_name].additional.used; name_index++) { - if (data.parameters[fss_extended_list_read_parameter_name].additional.array[name_index] > depth_position) { - if (data.parameters[fss_extended_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_extended_list_read_parameter_name].additional.array[name_index] > data.parameters[fss_extended_list_read_parameter_depth].additional.array[i+1]) { - break; - } - } + depths->array[i].index_name = data.parameters[fss_extended_list_read_parameter_name].additional.array[position_name]; + depths->array[i].value_name = arguments.argv[depths->array[i].index_name]; - if (depths->array[i].parameter == fss_extended_list_read_parameter_at) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The '--%s' and '--%s' parameters cannot be specified at the same time (specified for depth '%llu').", fss_extended_list_read_long_at, fss_extended_list_read_long_name, depth_current); - return f_status_set_error(f_invalid_parameter); - } + if (depths->array[i].value_name[0] == '\0') { + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_name); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' must not be an empty string."); - depths->array[i].parameter = fss_extended_list_read_parameter_name; - depths->array[i].position = data.parameters[fss_extended_list_read_parameter_name].additional.array[i]; - } - } // for - } + return f_status_set_error(f_invalid_parameter); + } + } // for + } + } // for - depths->array[i].depth = (f_string_length) atoll(arguments.argv[depth_position]); - depths->used++; - } // for - } - // when no depth parameter is specified, provide a implicit depth of 0 when depth-sensitive parameters are in use. - else { - if (data.parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - if (data.parameters[fss_extended_list_read_parameter_name].result == f_console_result_additional) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The '%s' and '%s' parameters must not be specified at the same time.", fss_extended_list_read_long_name, fss_extended_list_read_long_object); - return f_status_set_error(f_invalid_parameter); - } + for (f_array_length i = 0; i < depths->used; i++) { + for (f_array_length j = i + 1; j < depths->used; j++) { + if (depths->array[i].depth == depths->array[j].depth) { + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The value '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%llu", depths->array[i].depth); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "' may only be specified once for the parameter '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_depth); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "'."); - macro_fss_extended_list_read_depths_new(status, (*depths), 1); - if (f_status_is_error(status)) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); return f_status_set_error(f_invalid_parameter); } + else if (depths->array[i].depth > depths->array[j].depth) { + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "--%s", fss_extended_list_read_long_depth); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "' may not have the value '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%llu", depths->array[i].depth); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "' before the value '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%llu", depths->array[j].depth); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "'."); - depths->array[0].depth = (f_string_length) atoll(arguments.argv[data.parameters[fss_extended_list_read_parameter_depth].additional.array[0]]); - depths->array[0].parameter = fss_extended_list_read_parameter_at; - depths->array[0].position = 0; - depths->used = 1; - } - else if (data.parameters[fss_extended_list_read_parameter_name].result == f_console_result_additional) { - macro_fss_extended_list_read_depths_new(status, (*depths), 1); - if (f_status_is_error(status)) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); return f_status_set_error(f_invalid_parameter); } - - depths->array[0].depth = (f_string_length) atoll(arguments.argv[data.parameters[fss_extended_list_read_parameter_depth].additional.array[0]]); - depths->array[0].parameter = fss_extended_list_read_parameter_name; - depths->array[0].position = 0; - depths->used = 1; - } - } + } // for + } // for return f_none; } #endif // _di_fss_extended_list_read_main_preprocess_depth_ #ifndef _di_fss_extended_list_read_main_process_file_ - f_return_status fss_extended_list_read_main_process_file(const f_console_arguments arguments, fss_extended_list_read_data *data, const f_string filename, const f_string_length target) { + f_return_status fss_extended_list_read_main_process_file(const f_console_arguments arguments, fss_extended_list_read_data *data, const f_string filename, const fss_extended_list_read_depths depths) { f_status status = f_none; - f_status status2 = f_none; - - f_string_length current = 0; - f_string_length found = 0; { f_string_location input = f_string_location_initialize; input.start = 0; - input.stop = data->buffer.used - 1; + input.stop = data->buffer.used - 1; - status = fll_fss_extended_list_read(&data->buffer, &input, &data->objects, &data->contents); + status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest); if (f_status_is_error(status)) { status = f_status_set_fine(status); if (status == f_invalid_parameter) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_list_read() for the file '%s'", filename); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_extended_list_read()"); + fl_color_print(f_standard_error, data->context.error, data->context.reset, " for the file '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", filename); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } else if (status == f_error_allocation || status == f_error_reallocation) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory"); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory."); } else if (status == f_incomplete_utf_on_stop) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at stop position (at %d).", input.start); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at stop position (at "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%d", input.start); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, ")."); } else if (status == f_incomplete_utf_on_eos) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at end of string (at %d).", input.start); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at end of string (at "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%d", input.start); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, ")."); } else { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling fll_fss_extended_list_read() for the file '%s'", status, filename); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error ("); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%u", status); + fl_color_print(f_standard_error, data->context.error, data->context.reset, ") has occurred while calling "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_extended_list_read()"); + fl_color_print(f_standard_error, data->context.error, data->context.reset, " for the file '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", filename); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } - fss_extended_list_read_delete_data(data); return f_status_set_error(status); } else if (status == f_no_data_on_stop || status == f_no_data_on_eos) { - // clear buffers, then attempt the next file - f_macro_fss_contents_delete(status2, data->contents); - f_macro_fss_objects_delete(status2, data->objects); - f_macro_string_dynamic_delete(status2, data->buffer); + // Clear buffers, then attempt the next file. + f_macro_fss_nest_delete_simple(data->nest); + f_macro_string_dynamic_delete_simple(data->buffer); return f_status_set_warning(status); } } - // now that all of the files have been read, process the objects and contents - if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_none) { - fprintf(f_standard_output, "%llu\n", data->objects.used); + f_string_length select = 0; + + if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) { + status = fl_console_parameter_to_number_unsigned(arguments.argv[data->parameters[fss_extended_list_read_parameter_select].additional.array[data->parameters[fss_extended_list_read_parameter_select].additional.used - 1]], &select); + + if (f_status_is_error(status)) { + fss_extended_list_read_print_number_argument_error(data->context, "fl_console_parameter_to_number_unsigned", fss_extended_list_read_long_select, arguments.argv[data->parameters[fss_extended_list_read_parameter_select].additional.array[0]], f_status_set_fine(status)); + return status; + } + + // This standard does not support multiple content groups. + if (select > 0) { + return f_none; + } } - else { - current = 0; - if (data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_none) { - if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_none) { - for (; current < data->objects.used; current++) { - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional && found == target)) { + f_string_length line = 0; - /*if (data->parameters[fss_extended_list_read_parameter_size].result == f_console_result_found) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].range.start; - f_string_length size = 0; + if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { + status = fl_console_parameter_to_number_unsigned(arguments.argv[data->parameters[fss_extended_list_read_parameter_line].additional.array[data->parameters[fss_extended_list_read_parameter_line].additional.used - 1]], &line); - for (; counter <= data->contents.array[current].array[0].range.stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) size++; - } // for + if (f_status_is_error(status)) { + fss_extended_list_read_print_number_argument_error(data->context, "fl_console_parameter_to_number_unsigned", fss_extended_list_read_long_line, arguments.argv[data->parameters[fss_extended_list_read_parameter_line].additional.array[0]], f_status_set_fine(status)); + return status; + } + } - // the last newline is never present - size++; + if (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_additional && depths.used == 1)) { + return fss_extended_list_read_main_process_for_depth(arguments, data, filename, depths.array[0], line); + } - fprintf(f_standard_output, "%u\n", (unsigned int) size); - } - else { - fprintf(f_standard_output, "0\n"); - } - } - else*/ if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].range.start; - f_string_length position = 0; - f_string_length target = (f_string_length) atoll(arguments.argv[data->parameters[fss_extended_list_read_parameter_line].additional.array[0]]); - f_string_location range = f_string_location_initialize; - - // use an invalid range to communicate range not found - range.start = 1; - range.stop = 0; - - for (; counter <= data->contents.array[current].array[0].range.stop; counter++) { - if (position == target) { - range.start = counter; - - // explicit use of < instead of <= is done here so that the range.stop will always be accurate - for (; counter < data->contents.array[current].array[0].range.stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) { - break; - } - } // for - - range.stop = counter; - break; - } + // @todo: handle recursive situations, possibly calling the above block as a separate private function. - if (data->buffer.string[counter] == f_string_eol) { - position++; - } - } // for + return f_none; + } +#endif // _di_fss_extended_list_read_main_process_file_ - if (range.start <= range.stop) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, range); - } - } - } - else { - if (data->contents.array[current].used > 0) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->contents.array[current].array[0].range); - fprintf(f_standard_output, "\n"); - } - } - } +#ifndef _di_fss_extended_list_read_main_process_for_depth_ + f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments arguments, fss_extended_list_read_data *data, const f_string filename, const fss_extended_list_read_depth depth_setting, const f_string_length line) { + f_status status = f_none; - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { - break; - } - else { - found++; - } - } - } // for + f_fss_items *items = &data->nest.depth[depth_setting.depth]; + bool names[items->used]; + + if (depth_setting.index_name > 0) { + memset(names, 0, sizeof(bool) * items->used); + + f_string_length argv_length = strlen(depth_setting.value_name); + f_string_length name_length = 0; + + for (f_string_length i = 0; i < items->used; i++) { + name_length = (items->array[i].object.stop - items->array[i].object.start) + 1; + + if (name_length == argv_length) { + if (fl_string_compare(data->buffer.string + items->array[i].object.start, depth_setting.value_name, name_length, argv_length) == f_equal_to) { + names[i] = 1; + } } - else { - for (; current < data->objects.used; current++) { - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional && found == target)) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } + } // for + } + else { + memset(names, 1, sizeof(bool) * items->used); + } - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { - break; - } - else { - found++; - } - } + bool include_empty = 0; + + if (data->parameters[fss_extended_list_read_parameter_empty].result == f_console_result_found) { + include_empty = 1; + } + + if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_found) { + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + + if (depth_setting.index_at > 0) { + if (depth_setting.value_at < items->used && names[depth_setting.value_at]) { + fprintf(f_standard_output, "1%c", f_string_eol); + } + else { + fprintf(f_standard_output, "0%c", f_string_eol); + } + + return f_none; + } + else if (depth_setting.index_name > 0) { + f_string_length total = 0; + + for (f_string_length i = 0; i < items->used; i++) { + if (names[i] == 0) continue; + + total++; } // for + + fprintf(f_standard_output, "%llu%c", total, f_string_eol); + + return f_none; } + + fprintf(f_standard_output, "%llu%c", items->used, f_string_eol); + + return f_none; } else { - current = 0; + if (depth_setting.index_at > 0) { + if (depth_setting.value_at < items->used && names[depth_setting.value_at]) { + f_print_string_dynamic_partial(f_standard_output, data->buffer, items->array[depth_setting.value_at].object); + fprintf(f_standard_output, "%c", f_string_eol); + } - f_string_length total = 0; - f_string_length name_length = 0; - f_string_length argv_length = 0; + return f_none; + } - if (data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_additional) { - argv_length = strlen(arguments.argv[data->parameters[fss_extended_list_read_parameter_name].additional.array[0]]); + for (f_array_length i = 0; i < items->used; i++) { + if (names[i]) { + f_print_string_dynamic_partial(f_standard_output, data->buffer, items->array[depth_setting.value_at].object); + fprintf(f_standard_output, "%c", f_string_eol); + } + } // for + } - if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_none) { - for (; current < data->objects.used; current++) { - name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; + return f_none; + } - if (name_length == argv_length) { - if (fl_string_compare(data->buffer.string + data->objects.array[current].start, arguments.argv[data->parameters[fss_extended_list_read_parameter_name].additional.array[0]], name_length, argv_length) == f_equal_to) { + if (depth_setting.index_at > 0) { + if (depth_setting.value_at >= items->used) { + if (names[depth_setting.value_at] && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + fprintf(f_standard_output, "0%c", f_string_eol); + } - /*if (data->parameters[fss_extended_list_read_parameter_size].result == f_console_result_found) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].range.start; - f_string_length size = 0; + return f_none; + } - for (; counter <= data->contents.array[current].array[0].range.stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) size++; - } // for + f_array_length at = 0; + f_array_length i = 0; - // the last newline is never present - size++; + for (; i < items->used; i++) { + if (names[i]) { + if (at == depth_setting.value_at) { + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + if (items->array[i].content.used == 0) { + fprintf(f_standard_output, "0%c", f_string_eol); + } + else { + f_string_length total = 1; - fprintf(f_standard_output, "%u\n", (unsigned int) size); - } - else { - fprintf(f_standard_output, "0\n"); - } - } - else*/ if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].range.start; - f_string_length position = 0; - f_string_length target = (f_string_length) atoll(arguments.argv[data->parameters[fss_extended_list_read_parameter_line].additional.array[0]]); - f_string_location range = f_string_location_initialize; - - // use an invalid range to communicate range not found - range.start = 1; - range.stop = 0; - - for (; counter <= data->contents.array[current].array[0].range.stop; counter++) { - if (position == target) { - range.start = counter; - - // explicit use of < instead of <= is done here so that the range.stop will always be accurate - for (; counter < data->contents.array[current].array[0].range.stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) { - break; - } - } // for - - range.stop = counter; - break; - } - - if (data->buffer.string[counter] == f_string_eol) { - position++; - } - } // for - - if (range.start <= range.stop) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, range); - } - } - } - else { - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional && found == target)) { - if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { - total++; - } - else { - if (data->contents.array[current].used > 0) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->contents.array[current].array[0].range); - fprintf(f_standard_output, "\n"); - } - } - } - } + for (f_string_length j = items->array[i].content.array[0].start; j <= items->array[i].content.array[0].stop; j++) { + if (data->buffer.string[j] == f_string_eos) continue; - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { - break; - } - else { - found++; - } + if (data->buffer.string[j] == f_string_eol) { + total++; } - } + } // for + + fprintf(f_standard_output, "%llu%c", total, f_string_eol); } - } // for - if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_none) { - fprintf(f_standard_output, f_string_length_printf "\n", total); + return f_none; } - } - else { - // when and because the object parameter is specified, the name parameter refers to the content instead of the object - // therefore, make the search on the content and display the object - for (; current < data->contents.used; current++) { - if (data->contents.array[current].used > 0) { - name_length = data->contents.array[current].array[0].range.stop - data->contents.array[current].array[0].range.start + 1; - - if (name_length == argv_length) { - if (fl_string_compare(data->buffer.string + data->contents.array[current].array[0].range.start, arguments.argv[data->parameters[fss_extended_list_read_parameter_name].additional.array[0]], name_length, argv_length) == f_equal_to) { - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional && found == target)) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); + + if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { + if (items->array[i].content.used == 0) { + if (include_empty && line == 0) { + fprintf(f_standard_output, "%c", f_string_eol); + } + } + else { + f_string_length i = items->array[i].content.array[0].start; + + if (line == 0) { + for (; i <= items->array[i].content.array[0].stop; i++) { + if (data->buffer.string[i] == f_string_eos) continue; + if (data->buffer.string[i] == f_string_eol) { + fprintf(f_standard_output, "%c", f_string_eol); + break; } - if (data->parameters[fss_extended_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { + fprintf(f_standard_output, "%c", data->buffer.string[i]); + } // for + } + else { + f_string_length line_current = 0; + + for (; i <= items->array[i].content.array[0].stop; i++) { + if (data->buffer.string[i] == f_string_eos) continue; + + if (data->buffer.string[i] == f_string_eol) { + line_current++; + + if (line_current == line) { + i++; + + for (; i <= items->array[i].content.array[0].stop; i++) { + if (data->buffer.string[i] == f_string_eos) continue; + if (data->buffer.string[i] == f_string_eol) { + fprintf(f_standard_output, "%c", f_string_eol); + break; + } + + fprintf(f_standard_output, "%c", data->buffer.string[i]); + } // for + break; } - else { - found++; - } } - } + } // for } } - } // for + + return f_none; + } + + if (items->array[i].content.used > 0) { + f_print_string_dynamic_partial(f_standard_output, data->buffer, items->array[i].content.array[0]); + } + else if (include_empty) { + fprintf(f_standard_output, "%c", f_string_eol); + } + + break; } + + at++; } - } + } // for + + return f_none; + } + + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + f_string_length total = 0; + + for (f_string_length i = 0; i < items->used; i++) { + if (!names[i]) continue; + + if (items->array[i].content.used == 0) { + if (include_empty) { + total++; + } + + continue; + } + + for (f_string_length j = items->array[i].content.array[0].start; j <= items->array[i].content.array[0].stop; j++) { + if (data->buffer.string[j] == f_string_eos) continue; + + if (data->buffer.string[j] == f_string_eol) { + total++; + } + } // for + } // for + + fprintf(f_standard_output, "%llu%c", total, f_string_eol); + return f_none; } + if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) { + f_string_length line_current = 0; + f_string_length i = 0; + f_string_length j = 0; + + for (; i < items->used; i++) { + if (!names[i]) { + continue; + } + + if (items->array[i].content.used == 0) { + if (include_empty) { + if (line_current == line) { + fprintf(f_standard_output, "%c", f_string_eol); + break; + } + + line_current++; + } + + continue; + } + + j = items->array[i].content.array[0].start; + + if (line_current != line) { + for (; j <= items->array[i].content.array[0].stop; j++) { + if (data->buffer.string[j] == f_string_eol) { + line_current++; + + if (line_current == line) { + j++; + break; + } + } + } // for + } + + if (line_current == line) { + if (j > items->array[i].content.array[0].stop) continue; + + for (; j <= items->array[i].content.array[0].stop; j++) { + if (data->buffer.string[j] == f_string_eos) continue; + + if (data->buffer.string[j] == f_string_eol) { + fprintf(f_standard_output, "%c", f_string_eol); + break; + } + + fprintf(f_standard_output, "%c", data->buffer.string[j]); + } // for + + break; + } + } // for + + return f_none; + } + + for (f_string_length i = 0; i < items->used; i++) { + if (!names[i]) { + continue; + } + + if (items->array[i].content.used == 0) { + if (include_empty) { + fprintf(f_standard_output, "%c", f_string_eol); + } + + continue; + } + + f_print_string_dynamic_partial(f_standard_output, data->buffer, items->array[i].content.array[0]); + } // for + return f_none; } -#endif // _di_fss_extended_list_read_main_process_file_ +#endif // _di_fss_extended_list_read_main_process_for_depth_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h index 5aac844..4952acc 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h @@ -11,19 +11,27 @@ #ifdef __cplusplus extern "C" { #endif + /** * A structure of parameters applied at some depth. * * depth: the depth number in which this is to be processed at. - * parameter: the index representing the parameter enum of either the "at" parameter or the "name" parameter. - * position: the parameter position index within the argv representing the value associated with the designated 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. */ #ifndef _di_fss_extended_list_read_depth_ typedef struct { f_string_length depth; - f_array_length parameter; - f_array_length position; + f_array_length index_at; + f_array_length index_name; + + f_number_unsigned value_at; + f_string value_name; } fss_extended_list_read_depth; #define fss_extended_list_read_depth_initialize \ @@ -31,6 +39,8 @@ extern "C" { 0, \ 0, \ 0, \ + 0, \ + f_string_initialize, \ } #endif // _di_fss_extended_list_read_depth_ @@ -53,13 +63,16 @@ extern "C" { #define macro_fss_extended_list_read_depths_clear(depths) f_macro_memory_structure_clear(depths) - #define macro_fss_extended_list_read_depths_new(status, depths, length) f_macro_memory_structure_new(status, depths, fss_extended_list_read_depths, length) + #define macro_fss_extended_list_read_depths_new(status, depths, length) f_macro_memory_structure_new(status, depths, fss_extended_list_read_depth, length) - #define macro_fss_extended_list_read_depths_delete(status, depths) f_macro_memory_structure_delete(status, depths, fss_extended_list_read_depths) - #define macro_fss_extended_list_read_depths_destroy(status, depths) f_macro_memory_structure_destroy(status, depths, fss_extended_list_read_depths) + #define macro_fss_extended_list_read_depths_delete(status, depths) f_macro_memory_structure_delete(status, depths, fss_extended_list_read_depth) + #define macro_fss_extended_list_read_depths_destroy(status, depths) f_macro_memory_structure_destroy(status, depths, fss_extended_list_read_depth) - #define macro_fss_extended_list_read_depths_resize(status, depths, new_length) f_macro_memory_structure_resize(status, depths, fss_extended_list_read_depths, new_length) - #define macro_fss_extended_list_read_depths_adjust(status, depths, new_length) f_macro_memory_structure_adjust(status, depths, fss_extended_list_read_depths, new_length) + #define macro_fss_extended_list_read_depths_delete_simple(depths) f_macro_memory_structure_delete_simple(depths, fss_extended_list_read_depth) + #define macro_fss_extended_list_read_depths_destroy_simple(depths) f_macro_memory_structure_destroy_simple(depths, fss_extended_list_read_depth) + + #define macro_fss_extended_list_read_depths_resize(status, depths, new_length) f_macro_memory_structure_resize(status, depths, fss_extended_list_read_depth, new_length) + #define macro_fss_extended_list_read_depths_adjust(status, depths, new_length) f_macro_memory_structure_adjust(status, depths, fss_extended_list_read_depth, new_length) #endif // _di_fss_extended_list_read_depths_ /** @@ -79,12 +92,32 @@ extern "C" { #endif // _di_fss_extended_list_read_print_file_error_ /** + * Print number parameter argument error messages. + * + * @param context + * The color context information to use when printing. + * @param function_name + * The name of the function responsible for the error. + * @param parameter_name + * The name of the parameter responsible for the error. + * @param argument + * The value of the argument that is invalid. + * @param status + * The status code representing the error. + */ +#ifndef _di_fss_extended_list_read_print_number_argument_error_ + extern void fss_extended_list_read_print_number_argument_error(const fl_color_context context, const f_string function_name, const f_string parameter_name, const f_string argument, const f_status status) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_print_number_argument_error_ + +/** * Pre-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. * @param data - * The Program specific data. + * The program specific data. * @param depths * This stores the pre-processed depth parameters. * @@ -96,10 +129,48 @@ extern "C" { extern f_return_status fss_extended_list_read_main_preprocess_depth(const f_console_arguments arguments, const fss_extended_list_read_data data, fss_extended_list_read_depths *depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_preprocess_depth_ +/** + * Process a given file. + * + * @param arguments + * The console arguments passed to the program. + * @param data + * The program specific data. + * @param file_name + * The name of the file being processed. + * @param depths + * The processed depth parameters. + * + * @see fss_extended_list_read_main_preprocess_depth() + * @see fss_extended_list_read_main_process_for_depth() + */ #ifndef _di_fss_extended_list_read_main_process_file_ - extern f_return_status fss_extended_list_read_main_process_file(const f_console_arguments arguments, fss_extended_list_read_data *data, const f_string filename, const f_string_length target) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_read_main_process_file(const f_console_arguments arguments, fss_extended_list_read_data *data, const f_string file_name, const fss_extended_list_read_depths depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_process_file_ +/** + * Process the items for a given depth. + * + * This is intended to be used as a way to process the final specified depth. + * (for --depth 1 --depth 2 --depth 3, this would be called after navigating to depth 3.) + * + * @param arguments + * The console arguments passed to the program. + * @param data + * The program specific data. + * @param file_name + * The name of the file being processed. + * @param depth_setting + * The depth settings specific to the desired depth. + * @param line + * The line number parameter value, used for printing a specific line number for content. + * + * @see fss_extended_list_read_main_process_file() + */ +#ifndef _di_fss_extended_list_read_main_process_for_depth_ + extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments arguments, fss_extended_list_read_data *data, const f_string filename, const fss_extended_list_read_depth depth_setting, const f_string_length line) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_main_process_for_depth_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-fss_extended_read.c index a72b89a..7ba6354 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.c +++ b/level_3/fss_extended_read/c/private-fss_extended_read.c @@ -218,13 +218,13 @@ extern "C" { if (status == f_invalid_parameter) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling "); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_extended_list_read()"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_extended_read()"); fl_color_print(f_standard_error, data->context.error, data->context.reset, " for the file '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", filename); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } else if (status == f_error_allocation || status == f_error_reallocation) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory"); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory."); } else if (status == f_incomplete_utf_on_stop) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at stop position (at "); @@ -240,7 +240,7 @@ extern "C" { fl_color_print(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error ("); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%u", status); fl_color_print(f_standard_error, data->context.error, data->context.reset, ") has occurred while calling "); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_extended_list_read()"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_extended_read()"); fl_color_print(f_standard_error, data->context.error, data->context.reset, " for the file '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", filename); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); -- 1.8.3.1