A nested type has been created.
I suspect that I will need to change the structure of the other types to improve consistency, but more review and consideration is needed before any such changes are made.
A read program was written but it is essentially a copy and paste of Basic List, with a few minor changes just to make it compile.
The program arguments of all the FLL programs will need to be changed such that adding support for "depth" selection can be used for things lile Extended List.
The memory allocation is implemented but not reviewed.
I converted the behavior to support nesting, but I need to review the logic to ensure I caught everything.
No time was spent on the write support.
/**
* Stores information about a particular fss file, otherwise known as its header.
*
- * type: the kind of fss file is this.
+ * type: the kind of fss file is this.
* length: Total length of the header.
*/
#ifndef _di_f_fss_header_
* This holds an array of fss_headers.
*
* array: The array of headers.
- * size: Total amount of allocated space.
- * used: Total number of allocated spaces used.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
*/
#ifndef _di_f_fss_headers_
typedef struct {
* This holds an array of fss_object.
*
* array: The array of objects.
- * size: Total amount of allocated space.
- * used: Total number of allocated spaces used.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
*/
#ifndef _di_fss_objects_
typedef struct {
* There will be no nesting beyond the first level recorded in this structure.
*
* array: The array of content.
- * size: Total amount of allocated space.
- * used: Total number of allocated spaces used.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
*/
#ifndef _di_fss_content_
typedef struct {
* This holds an array of fss_content.
*
* array: The array of content arrays.
- * size: Total amount of allocated space.
- * used: Total number of allocated spaces used.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
*/
#ifndef _di_f_fss_contents_
typedef struct {
#endif // _di_f_fss_contents_
/**
- * This holds a object and its associated content.
+ * This holds a child content object and its associated content.
+ *
+ * Child content represents content nested within some other content and never represents the top-most content.
*
* To designate that either object or content is non-existent, set start position greater than stop position.
* In particular, set start to 1 and stop to 0.
*
- * object: The object.
+ * object: The object.
* content: The content associated with the object.
- * parent: A location referencing a parrent object or content that this object content is nested under.
+ * parent: A location referencing a parrent object or content that this object content is nested under.
*/
#ifndef _di_fss_content_child_
typedef struct {
#define f_fss_content_child_initialize { f_fss_object_initialize, f_fss_content_initialize, f_array_length_initialize }
- #define f_macro_fss_content_child_clear(object_content) f_macro_memory_structure_new(object_content)
+ /**
+ * Reset a fss content child 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.
+ */
+ #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;
+
+ /**
+ * Create a new fss content child structure.
+ *
+ * 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.
+ * structure: the structure to operate on.
+ * 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;
+
+ /**
+ * Delete a fss content child.
+ *
+ * status: the status to return.
+ * content_child: the f_fss_content_child structure to operate on.
+ */
+ #define f_macro_fss_content_child_delete(status, content_child) \
+ f_macro_fss_content_delete(status, content_child.content) \
+ if (status == f_none) { \
+ content_child.object.start = 1; \
+ content_child.object.stop = 0; \
+ content_child.parent = 0; \
+ }
+
+ /**
+ * Destroy a fss content child.
+ *
+ * status: the status to return.
+ * content_child: the f_fss_content_child structure to operate on.
+ */
+ #define f_macro_fss_content_child_destroy(status, content_child) \
+ f_macro_fss_content_destroy(status, content_child.content) \
+ if (status == f_none) { \
+ content_child.object.start = 1; \
+ content_child.object.stop = 0; \
+ content_child.parent = 0; \
+ }
+
+ /**
+ * Resize a fss content child.
+ *
+ * status: the status to return.
+ * content_child: the f_fss_content_child 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);
+
+ /**
+ * Adjust a fss content child.
+ *
+ * status: the status to return.
+ * content_child: the f_fss_content_child 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_content_child_new(status, object_content, length) f_macro_memory_structure_new(status, object_content, f_fss_content_child, length)
-
- #define f_macro_fss_content_child_delete(status, object_content) f_macro_memory_structure_delete(status, object_content, f_fss_content_child)
- #define f_macro_fss_content_child_destroy(status, object_content) f_macro_memory_structure_destroy(status, object_content, f_fss_content_child)
-
- #define f_macro_fss_content_child_resize(status, object_content, new_length) f_macro_memory_structure_resize(status, object_content, f_fss_content_child, new_length)
- #define f_macro_fss_content_child_adjust(status, object_content, new_length) f_macro_memory_structure_adjust(status, object_content, f_fss_content_child, new_length)
#endif // _di_fss_content_child_
/**
#define f_fss_content_childs_initialize { f_string_location_initialize, 0, 0, 0 }
- // @todo: f_macro_memory_structure.. might not be usable here, review and confirm/deny this.
- #define f_macro_fss_content_childs_clear(object_contents) f_macro_memory_structure_new(object_contents)
-
- #define f_macro_fss_content_childs_new(status, object_contents, length) f_macro_memory_structure_new(status, object_contents, f_fss_content_childs, length)
-
- #define f_macro_fss_content_childs_delete(status, object_contents) f_macro_memory_structure_delete(status, object_contents, f_fss_content_childs)
- #define f_macro_fss_content_childs_destroy(status, object_contents) f_macro_memory_structure_destroy(status, object_contents, f_fss_content_childs)
-
- #define f_macro_fss_content_childs_resize(status, object_contents, new_length) f_macro_memory_structure_resize(status, object_contents, f_fss_content_childs, new_length)
- #define f_macro_fss_content_childs_adjust(status, object_contents, new_length) f_macro_memory_structure_adjust(status, object_contents, f_fss_content_childs, new_length)
+ /**
+ * Reset a fss content childs 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.
+ */
+ #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;
+
+ /**
+ * Create a new fss content childs.
+ *
+ * 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); \
+ if (status == f_none) { \
+ content_childs.size = new_length; \
+ content_childs.used = 0; \
+ }
+
+ /**
+ * Delete a fss content childs.
+ *
+ * status: the status to return.
+ * content_childs: the f_fss_content_childs structure to operate on.
+ */
+ #define f_macro_fss_content_childs_delete(status, content_childs) \
+ status = f_none; \
+ while (content_childs.size > 0) { \
+ f_macro_fss_content_child_delete(status, content_childs.array[content_childs.size - 1]); \
+ if (status != f_none) break; \
+ content_childs.size--; \
+ } \
+ 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.used = 0;
+
+ /**
+ * Destroy a fss content childs.
+ *
+ * status: the status to return.
+ * content_childs: the f_fss_content_childs structure to operate on.
+ */
+ #define f_macro_fss_content_childs_destroy(status, content_childs) \
+ status = f_none; \
+ while (content_childs.size > 0) { \
+ f_macro_fss_content_child_destroy(status, content_childs.array[content_childs.size - 1]); \
+ if (status != f_none) break; \
+ content_childs.size--; \
+ } \
+ 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.used = 0;
+
+ /**
+ * Resize a fss content childs.
+ *
+ * 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_resize(status, content_childs, 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 (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) { \
+ if (new_length > content_childs.size) { \
+ f_array_length i = content_childs.size; \
+ for (; i < new_length; ++i) { \
+ memset(&content_childs.array[i], 0, sizeof(f_fss_content_child)); \
+ } \
+ } \
+ 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; \
+ }
+
+ /**
+ * Adjust a fss content childs.
+ *
+ * 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_adjust(status, content_childs, 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 (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) { \
+ if (new_length > content_childs.size) { \
+ length_variable i = content_childs.size; \
+ for (; i < new_length; ++i) { \
+ memset(&content_childs.array[i], 0, sizeof(f_fss_content_child)); \
+ } \
+ } \
+ 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; \
+ }
#endif // _di_fss_content_childs_
/**
* 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.
*
- * array: an array of child objects.
+ * array: an array of f_fss_content_childs objects.
* size: Total amount of allocated space.
* used: Total number of allocated spaces used.
*/
#define f_fss_content_nest_initialize { 0, 0, 0 }
- #define f_macro_fss_content_nest_clear(object_content_nested) f_macro_memory_structure_new(object_content_nested)
-
- #define f_macro_fss_content_nest_new(status, object_content_nested, length) f_macro_memory_structure_new(status, object_content_nested, f_fss_content_nest, length)
-
- #define f_macro_fss_content_nest_delete(status, object_content_nested) f_macro_memory_structure_delete(status, object_content_nested, f_fss_content_nest)
- #define f_macro_fss_content_nest_destroy(status, object_content_nested) f_macro_memory_structure_destroy(status, object_content_nested, f_fss_content_nest)
-
- #define f_macro_fss_content_nest_resize(status, object_content_nested, new_length) f_macro_memory_structure_resize(status, object_content_nested, f_fss_content_nest, new_length)
- #define f_macro_fss_content_nest_adjust(status, object_content_nested, new_length) f_macro_memory_structure_adjust(status, object_content_nested, f_fss_content_nest, new_length)
+ /**
+ * 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.
+ */
+ #define f_macro_fss_content_nest_clear(content_nest) \
+ content_nest.array = 0; \
+ content_nest.size = 0; \
+ content_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.
+ */
+ #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); \
+ if (status == f_none) { \
+ content_nest.size = new_length; \
+ content_nest.used = 0; \
+ }
+
+ /**
+ * Delete a fss content nest.
+ *
+ * status: the status to return.
+ * content_nest: the f_fss_content_nest structure to operate on.
+ */
+ #define f_macro_fss_content_nest_delete(status, content_nest) \
+ status = f_none; \
+ while (content_nest.size > 0) { \
+ f_macro_fss_content_childs_delete(status, content_nest.array[content_nest.size - 1]); \
+ if (status != f_none) break; \
+ content_nest.size--; \
+ } \
+ 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.used = 0;
+
+ /**
+ * Destroy a fss content nest.
+ *
+ * status: the status to return.
+ * content_nest: the f_fss_content_nest structure to operate on.
+ */
+ #define f_macro_fss_content_nest_destroy(status, content_nest) \
+ status = f_none; \
+ while (content_nest.size > 0) { \
+ f_macro_fss_content_childs_destroy(status, content_nest.array[content_nest.size - 1]); \
+ if (status != f_none) break; \
+ content_nest.size--; \
+ } \
+ 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.used = 0;
+
+ /**
+ * 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.
+ */
+ #define f_macro_fss_content_nest_resize(status, content_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 (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) { \
+ if (new_length > content_nest.size) { \
+ f_array_length i = content_nest.size; \
+ for (; i < new_length; ++i) { \
+ memset(&content_nest.array[i], 0, sizeof(f_fss_content_childs)); \
+ } \
+ } \
+ content_nest.size = new_length; \
+ if (content_nest.used > content_nest.size) content_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.
+ */
+ #define f_macro_fss_content_nest_adjust(status, content_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 (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) { \
+ if (new_length > content_nest.size) { \
+ f_array_length i = content_nest.size; \
+ for (; i < new_length; ++i) { \
+ memset(&content_childs.array[i], 0, sizeof(f_fss_content_child)); \
+ } \
+ } \
+ content_nest.size = new_length; \
+ if (content_nest.used > content_nest.size) content_nest.used = new_length; \
+ }
#endif // _di_fss_content_nest_
+/**
+ * This holds an array of f_fss_content_nest.
+ *
+ * array: an array of f_fss_content_nest objects.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
+ */
+#ifndef _di_fss_content_nests_
+ typedef struct {
+ f_fss_content_nest *array;
+ f_array_length size;
+ f_array_length used;
+ } f_fss_content_nests;
+
+ #define f_fss_content_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.
+ */
+ #define f_macro_fss_content_nests_clear(content_nests) \
+ content_nests.array = 0; \
+ content_nests.size = 0; \
+ content_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.
+ */
+ #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); \
+ if (status == f_none) { \
+ content_nests.size = new_length; \
+ content_nests.used = 0; \
+ }
+
+ /**
+ * Delete a fss content nests.
+ *
+ * status: the status to return.
+ * content_nests: the f_fss_content_nests structure to operate on.
+ */
+ #define f_macro_fss_content_nests_delete(status, content_nests) \
+ status = f_none; \
+ while (content_nests.size > 0) { \
+ f_macro_fss_content_nest_delete(status, content_nests.array[content_nests.size - 1]); \
+ if (status != f_none) break; \
+ content_nests.size--; \
+ } \
+ 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.used = 0;
+
+ /**
+ * Destroy a fss content nests.
+ *
+ * status: the status to return.
+ * content_nests: the f_fss_content_nests structure to operate on.
+ */
+ #define f_macro_fss_content_nests_destroy(status, content_nests) \
+ status = f_none; \
+ while (content_nests.size > 0) { \
+ f_macro_fss_content_nest_destroy(status, content_nests.array[content_nests.size - 1]); \
+ if (status != f_none) break; \
+ content_nests.size--; \
+ } \
+ 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.used = 0;
+
+ /**
+ * 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.
+ */
+ #define f_macro_fss_content_nests_resize(status, content_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 (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) { \
+ if (new_length > content_nests.size) { \
+ f_array_length i = content_nests.size; \
+ for (; i < new_length; ++i) { \
+ memset(&content_nests.array[i], 0, sizeof(f_fss_content_nest)); \
+ } \
+ } \
+ content_nests.size = new_length; \
+ if (content_nests.used > content_nests.size) content_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.
+ */
+ #define f_macro_fss_content_nests_adjust(status, content_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 (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) { \
+ if (new_length > content_nests.size) { \
+ f_array_length i = content_nests.size; \
+ for (; i < new_length; ++i) { \
+ memset(&content_nests.array[i], 0, sizeof(f_fss_content_nest)); \
+ } \
+ } \
+ content_nests.size = new_length; \
+ if (content_nests.used > content_nests.size) content_nests.used = new_length; \
+ }
+#endif // _di_fss_content_nests_
+
#ifdef __cplusplus
} // extern "C"
#endif
/**
* Reset a generic memory stucture to 0 (clear all values).
*
- * A generic memory structure has the following properties:
- * array: Some pointer to an array of values.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
+ * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks.
*
* structure: the structure to operate on.
*/
/**
* Create a new generic memory structure.
*
- * A generic memory structure has the following properties:
- * array: Some pointer to an array of values.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
+ * 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.
* structure: the structure to operate on.
/**
* Delete a generic memory structure.
*
- * A generic memory structure has the following properties:
- * array: Some pointer to an array of values.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
* status: the status to return.
* structure: the structure to operate on.
* type: the structure type.
/**
* Destroy a generic memory structure.
*
- * A generic memory structure has the following properties:
- * array: Some pointer to an array of values.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
* status: the status to return.
* structure: the structure to operate on.
* type: the structure type.
/**
* Resize a generic memory structure.
*
- * A generic memory structure has the following properties:
- * array: Some pointer to an array of values.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
* status: the status to return.
* structure: the structure to operate on.
* type: the structure type.
/**
* Adjust a generic memory structure.
*
- * A generic memory structure has the following properties:
- * array: Some pointer to an array of values.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
* status: the status to return.
* structure: the structure to operate on.
* type: the structure type.
#endif // _di_f_macro_memory_structure_adjust_
/**
- * Create a new generic memory structures.
+ * Reset a generic memory stuctures to 0 (clear all values).
*
- * A generic memory structures represents an array of structure with the following properties:
- * array: Some pointer to an array of structure.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
+ * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks.
*
* structures: the structures to operate on.
*/
/**
* Create a new generic memory structures.
*
- * A generic memory structures represents an array of structure with the following properties:
- * array: Some pointer to an array of structure.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
+ * 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.
* structures: the structures to operate on.
/**
* Delete a generic memory structures.
*
- * A generic memory structures represents an array of structure with the following properties:
- * array: Some pointer to an array of structure.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
* status: the status to return.
* structures: the structures to operate on.
- * type: the structure type.
- * new_length: the new size of the array.
+ * type: the structure type..
*/
#ifndef _di_f_macro_memory_structures_delete_
#define f_macro_memory_structures_delete(status, structures, type) \
status = f_none; \
while (structures.size > 0) { \
- --structures.size; \
- f_macro_memory_structure_delete(status, structures.array[structures.size], type); \
+ f_macro_memory_structure_delete(status, structures.array[structures.size - 1], type); \
if (status != f_none) break; \
+ structures.size--; \
} \
if (status == f_none) status = f_memory_delete((void **) & structures.array, sizeof(type), structures.size); \
if (status == f_none) structures.used = 0;
/**
* Destroy a generic memory structures.
*
- * A generic memory structures represents an array of structure with the following properties:
- * array: Some pointer to an array of structure.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
* status: the status to return.
* structures: the structures to operate on.
* type: the structure type.
- * new_length: the new size of the array.
*/
#ifndef _di_f_macro_memory_structures_destroy_
#define f_macro_memory_structures_destroy(status, structures, type) \
status = f_none; \
while (structures.size > 0) { \
- --structures.size; \
- f_macro_memory_structure_destroy(status, structures.array[structures.size], type); \
+ f_macro_memory_structure_destroy(status, structures.array[structures.size - 1], type); \
if (status != f_none) break; \
+ structures.size--; \
} \
if (status == f_none) status = f_memory_destroy((void **) & structures.array, sizeof(type), structures.size); \
if (status == f_none) structures.used = 0;
/**
* Resize a generic memory structures.
*
- * A generic memory structures represents an array of structure with the following properties:
- * array: Some pointer to an array of structure.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
- * status: the status to return.
- * structures: the structures to operate on.
- * type: the structure type.
- * new_length: the new size of the array.
+ * status: the status to return.
+ * structures: the structures to operate on.
+ * type: the structure type.
+ * new_length: the new size of the array.
+ * length_variable: the data type of the length variable.
*/
#ifndef _di_f_macro_memory_structures_resize_
#define f_macro_memory_structures_resize(status, structures, type, new_length, length_variable) \
/**
* Adjust a generic memory structures.
*
- * A generic memory structures represents an array of structure with the following properties:
- * array: Some pointer to an array of structure.
- * size: A number, generally unsigned, representing the size of the above array.
- * used: A number, generally unsigned, representing how much of the above size is in use in the above array.
- *
- * status: the status to return.
- * structures: the structures to operate on.
- * type: the structure type.
- * new_length: the new size of the array.
+ * status: the status to return.
+ * structures: the structures to operate on.
+ * type: the structure type.
+ * new_length: the new size of the array.
+ * length_variable: the data type of the length variable.
*/
#ifndef _di_f_macro_memory_structures_adjust_
#define f_macro_memory_structures_adjust(status, structures, type, new_length, length_variable) \
#endif // _di_f_string_length_
/**
+ * A structure containing an array of string lengths.
+ *
+ * array: the array of string lengths.
* size: total amount of allocated space.
* used: total number of allocated spaces used.
*/
#endif // _di_f_string_lengths_
/**
- * designates a start and stop position that represents a sub-string inside of some parent string.
- * use this to avoid resizing, restructuring, and reallocating the parent string to separate the sub-string.
+ * A structure designating a start and stop position that represents a sub-string inside of some parent string.
+ *
+ * Use this to avoid resizing, restructuring, and reallocating the parent string to separate the sub-string.
+ *
+ * In general, this project uses the start and stop position inclusively, meaning that a range of 0 to 1 would include positions 0 and position 1.
+ * Therefore, 0 to 0 would be a position of 0.
+ * Set start to some value larger than stop to designate no range.
+ *
+ * start: the start position.
+ * stop: the stop position.
*/
#ifndef _di_f_string_location_
typedef struct {
#endif // _di_f_string_location_
/**
- * an array of string locations.
+ * An array of string locations.
*
+ * array: the array of string locations.
* size: total amount of allocated space.
* used: total number of allocated spaces used.
*/
#endif // _di_f_string_locations_
/**
- * a string that supports contains a size attribute to handle dynamic allocations and deallocations.
- * save the string size along with the string, so that strlen(..) commands can be avoided as much as possible.
+ * A string that supports contains a size attribute to handle dynamic allocations and deallocations.
+ *
+ * Save the string size along with the string, so that strlen(..) commands can be avoided as much as possible.
*
+ * string: the string.
* size: total amount of allocated space.
* used: total number of allocated spaces used.
*/
#endif // _di_f_string_dynamic_
/**
- * an array of dynamic strings.
+ * An array of dynamic strings.
*
+ * array: the array of dynamic strings.
* size: total amount of allocated space.
* used: total number of allocated spaces used.
*/
// delimits must only be applied once a valid object is found.
f_string_lengths delimits = f_string_lengths_initialize;
+ f_string_lengths positions_start = f_string_lengths_initialize;
fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*location))
- fl_macro_fss_content_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ 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_allocate_content_if_necessary((*found), delimits);
- found->array[found->used].start = location->start;
f_array_length depth = 0;
- f_string_lengths positions_start = f_string_lengths_initialize;
f_string_length position_previous = location->start;
f_string_length last_newline = location->start;
f_fss_object object = f_fss_object_initialize;
if (is_open) {
f_bool is_object = f_false;
- f_string_location location_newline = location->start;
+ f_string_length location_newline = location->start;
if (slash_count % 2 == 0) {
is_object = f_true;
depth++;
if (depth >= positions_start.size) {
- f_macro_string_lengths_resize(status, (*positions_start), positions_start.size + f_fss_default_allocation_step);
+ f_macro_string_lengths_resize(status, positions_start, positions_start.size + f_fss_default_allocation_step);
if (f_status_is_error(status)) {
f_status allocation_status = f_none;
depth++;
if (depth >= positions_start.size) {
- f_macro_string_lengths_resize(status, (*positions_start), positions_start.size + f_fss_default_allocation_step);
+ f_macro_string_lengths_resize(status, positions_start, positions_start.size + f_fss_default_allocation_step);
if (f_status_is_error(status)) {
f_status allocation_status = f_none;
}
}
- 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->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 (f_status_is_error(status)) {
f_status allocation_status = f_none;
}
}
- f_array_length position = found->array[depth]->used;
+ f_array_length position = found->array[depth].used;
- if (found->array[depth]->array[position]->used >= found->array[depth]->content[position]->size) {
- f_macro_fss_contents_resize(status, found->array[depth]->array[position], found->array[depth]->array[position]->size + f_fss_default_allocation_step);
+ 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 (f_status_is_error(status)) {
f_status allocation_status = f_none;
}
}
- 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[found->array[depth]->array[position]->used].stop = last_newline;
- found->array[depth]->array[position]->used++;
- found->array[depth]->used++;
+ 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;
if (depth == 0) {
return status;
}
- found->array[0]->range.start = positions_start.array[0];
- found->array[0]->range.stop = location->start;
+ found->array[0].range.start = positions_start.array[0];
+ found->array[0].range.stop = location->start;
location->start = last_newline + 1;
found->used++;
- fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ fl_macro_fss_content_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop)
f_macro_string_lengths_delete(status, delimits);
f_macro_string_lengths_delete(status, positions_start);
if (buffer == 0) return f_status_set_error(f_invalid_parameter);
#endif // _di_level_1_parameter_checking_
+ // @todo
+ /*
f_status status = f_none;
f_bool is_comment = f_false;
f_bool has_graph = f_false;
else if (location->start >= content.used) {
return f_none_on_eos;
}
+ */
return f_none;
}
#ifndef _di_fl_macro_fss_apply_delimit_placeholders_
#define fl_macro_fss_apply_delimit_placeholders(buffer, delimits) \
{ \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
\
f_string_length i = 0; \
\
i++; \
} \
\
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
}
#endif // _di_fl_macro_fss_apply_delimit_placeholders_
#ifndef _di_fl_macro_fss_object_return_on_overflow_
#define fl_macro_fss_object_return_on_overflow(buffer, location, found, delimits, eos_status, stop_status) \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.stop = buffer.used - 1; \
return eos_status; \
} \
else if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.stop = location.stop; \
return stop_status; \
#ifndef _di_fl_macro_fss_object_delimited_return_on_overflow_
#define fl_macro_fss_object_delimited_return_on_overflow(buffer, location, found, delimits, eos_status, stop_status) \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.stop = buffer.used - 1; \
return eos_status; \
} \
else if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.stop = location.stop; \
return stop_status; \
#ifndef _di_fl_macro_fss_content_return_on_overflow_
#define fl_macro_fss_content_return_on_overflow(buffer, location, found, delimits, eos_status, stop_status) \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = buffer.used - 1; \
return eos_status; \
} \
else if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = location.stop; \
return stop_status; \
#ifndef _di_fl_macro_fss_content_delimited_return_on_overflow_
#define fl_macro_fss_content_delimited_return_on_overflow(buffer, location, found, delimits, eos_status, stop_status) \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = buffer.used - 1; \
return eos_status; \
} \
else if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = location.stop; \
return stop_status; \
#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) \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
- f_macro_string_lengths_delete(allocation_status, positions); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, positions); \
\
- found.array[found.used].stop = buffer.used - 1; \
+ /* @todo: found.array[found.used].stop = buffer.used - 1; */ \
return eos_status; \
} \
else if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
- f_macro_string_lengths_delete(allocation_status, positions); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, positions); \
\
- found.array[found.used].stop = location.stop; \
+ /* @todo: found.array[found.used].stop = location.stop; */ \
return stop_status; \
}
#endif // _di_fl_macro_fss_content_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) \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
- f_macro_string_lengths_delete(allocation_status, positions); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, positions); \
\
- found.array[found.used].stop = buffer.used - 1; \
return eos_status; \
} \
else if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
- f_macro_string_lengths_delete(allocation_status, positions); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, positions); \
\
- found.array[found.used].stop = location.stop; \
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_if_necessary_
\
f_macro_fss_content_resize(status, content, content.size + f_fss_default_allocation_step); \
if (f_status_is_error(status)) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
return status; \
} \
while (buffer.string[location.start] != f_string_eol) { \
++location.start; \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
return eos_status; \
} \
if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
return stop_status; \
} \
while (buffer.string[location.start] != f_string_eol) { \
++location.start; \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
return eos_status; \
} \
if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
return stop_status; \
} \
while (buffer.string[location.start] != f_string_eol) { \
++location.start; \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = location.stop; \
return eos_status; \
} \
if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_status macro_allocation_status = f_none; \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = location.stop; \
return stop_status; \
while (buffer.string[location.start] != f_string_eol) { \
++location.start; \
if (location.start >= buffer.used) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = location.stop; \
return eos_status; \
} \
if (location.start > location.stop) { \
- f_status allocation_status = f_none; \
+ f_status macro_allocation_status = f_none; \
f_string_length i = 0; \
\
while (i < delimits.used) { \
buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \
i++; \
} \
- f_macro_string_lengths_delete(allocation_status, delimits); \
+ f_macro_string_lengths_delete(macro_allocation_status, delimits); \
\
found.array[found.used].stop = location.stop; \
return stop_status; \
build_linker ar
build_libraries -lc
build_libraries_fll -lf_utf -lf_file -lf_conversion -lf_memory
-build_sources_library fss.c fss_basic.c fss_basic_list.c fss_extended.c
+build_sources_library fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c
build_sources_program
-build_sources_headers fss.h fss_basic.h fss_basic_list.h fss_status.h fss_extended.h fss_macro.h
+build_sources_headers fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_macro.h fss_status.h
build_sources_bash
build_sources_settings
build_shared yes
extern "C" {
#endif
+/**
+ * Read a buffer expected to be in fss-0000 format, getting all objects and their respective content.
+ *
+ * @param buffer
+ * 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.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_no_data_on_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing).
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ * f_unknown (with error bit) if a (what should be) impossible execution point is reached.
+ */
#ifndef _di_fll_fss_basic_read_
- /**
- * read an fss-0000 object and then content.
- */
extern f_return_status fll_fss_basic_read(f_string_dynamic *buffer, f_string_location *input, f_fss_objects *objects, f_fss_contents *contents);
#endif // _di_fll_fss_basic_read_
+/**
+ * Write a single object string and content string to a buffer, using fss-0000 format.
+ *
+ * @param object
+ * A string representing the object.
+ * @param contents
+ * An array of strings representing multiple content to write.
+ * @param buffer
+ * The buffer to write to.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
#ifndef _di_fll_fss_basic_write_
- /**
- * write an fss-0000 object and then content.
- */
extern f_return_status fll_fss_basic_write(const f_string_dynamic object, const f_string_dynamics contents, f_string_dynamic *buffer);
#endif // _di_fll_fss_basic_write_
extern "C" {
#endif
+/**
+ * Read a buffer expected to be in fss-0002 format, getting all objects and their respective content.
+ *
+ * @param buffer
+ * 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.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_no_data_on_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing).
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ * f_unknown (with error bit) if a (what should be) impossible execution point is reached.
+ */
#ifndef _di_fll_fss_basic_list_read_
- /**
- * read an fss-0002 object and then content.
- */
extern f_return_status fll_fss_basic_list_read(f_string_dynamic *buffer, f_string_location *input, f_fss_objects *objects, f_fss_contents *contents);
#endif // _di_fll_fss_basic_list_read_
+/**
+ * Write a single object string and content string to a buffer, using fss-0002 format.
+ *
+ * @param object
+ * A string representing the object.
+ * @param contents
+ * An array of strings representing multiple content to write.
+ * @param buffer
+ * The buffer to write to.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
#ifndef _di_fll_fss_basic_list_write_
- /**
- * write an fss-0000 object and then content.
- */
extern f_return_status fll_fss_basic_list_write(const f_string_dynamic object, const f_string_dynamics contents, f_string_dynamic *buffer);
#endif // _di_fll_fss_basic_list_write_
// if at least some valid object was found, then return f_none equivelents
if (objects->used > initial_used) {
- if (status == f_no_data_on_eos) return f_none_on_eos;
+ if (status == f_no_data_on_eos) return f_none_on_eos;
if (status == f_no_data_on_stop) return f_none_on_stop;
}
return status;
- } else if (status != fl_fss_found_object && status != fl_fss_found_content && status != fl_fss_found_no_content && status != fl_fss_found_object_no_content) {
+ }
+ else if (status != fl_fss_found_object && status != fl_fss_found_content && status != fl_fss_found_no_content && status != fl_fss_found_object_no_content) {
return status;
}
// when content is found, the input->start is incremented, if content is found at input->stop, then input->start will be > input.stop
contents->used++;
} while (f_true);
- return f_unknown;
+ return f_status_is_error(f_unknown);
}
#endif // _di_fll_fss_extended_read_
extern "C" {
#endif
+/**
+ * Read a buffer expected to be in fss-0001 format, getting all objects and their respective content.
+ *
+ * @param buffer
+ * 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.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_no_data_on_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing).
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ * f_unknown (with error bit) if a (what should be) impossible execution point is reached.
+ */
#ifndef _di_fll_fss_extended_read_
- /**
- * read an fss-0001 object and then content.
- */
extern f_return_status fll_fss_extended_read(f_string_dynamic *buffer, f_string_location *input, f_fss_objects *objects, f_fss_contents *contents);
#endif // _di_fll_fss_extended_read_
+/**
+ * Write a single object string and content string to a buffer, using fss-0001 format.
+ *
+ * @param object
+ * A string representing the object.
+ * @param contents
+ * An array of strings representing multiple content to write.
+ * @param buffer
+ * The buffer to write to.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
#ifndef _di_fll_fss_extended_write_
- /**
- * write an fss-0000 object and then content.
- */
extern f_return_status fll_fss_extended_write(const f_string_dynamic object, const f_string_dynamics contents, f_string_dynamic *buffer);
#endif // _di_fll_fss_extended_write_
--- /dev/null
+#include <level_2/fss_extended_list.h>
+
+#ifdef __cplusplus
+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) {
+ #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);
+ #endif // _di_level_3_parameter_checking_
+
+ f_status status = f_none;
+ f_string_length initial_used = objects->used;
+ f_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;
+ }
+
+ f_macro_fss_content_nests_resize(status, (*contents), contents->used + f_fss_default_allocation_step);
+
+ if (f_status_is_error(status)) {
+ return status;
+ }
+ }
+
+ do {
+ status = fl_fss_extended_list_object_read(buffer, input, &objects->array[objects->used]);
+
+ 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++;
+
+ return fl_fss_found_object_no_content;
+ }
+
+ if (found_data) {
+ if (input->start >= buffer->used) {
+ 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_stop;
+ }
+ }
+
+ if (status == fl_fss_found_object) {
+ found_data = f_true;
+ status = fl_fss_extended_list_content_read(buffer, input, &contents->array[contents->used]);
+
+ 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) {
+ 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;
+ }
+ }
+
+ break;
+ }
+ } 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++;
+ 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 (status == f_no_data_on_eos) return f_none_on_eos;
+ if (status == f_no_data_on_stop) return f_none_on_stop;
+ }
+
+ return status;
+ }
+ else if (status != fl_fss_found_object && status != fl_fss_found_content && status != fl_fss_found_no_content && status != fl_fss_found_object_no_content) {
+ return status;
+ }
+ // 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++;
+ }
+
+ if (input->start >= buffer->used) {
+ return f_none_on_eos;
+ }
+
+ return f_none_on_stop;
+ }
+
+ objects->used++;
+ contents->used++;
+ } while (f_true);
+
+ return f_status_is_error(f_unknown);
+ }
+#endif // _di_fll_fss_extended_list_read_
+
+/*
+#ifndef _di_fll_fss_extended_list_write_
+ f_return_status fll_fss_extended_list_write(const f_string_dynamic object, const f_string_dynamics contents, f_string_dynamic *buffer) {
+ #ifndef _di_level_3_parameter_checking_
+ if (buffer == 0) return f_status_set_error(f_invalid_parameter);
+ if (contents.used > contents.size) return f_status_set_error(f_invalid_parameter);
+ #endif // _di_level_3_parameter_checking_
+
+ f_status status = 0;
+ f_array_length current = 0;
+ f_string_location location = f_string_location_initialize;
+
+ location.start = 0;
+ location.stop = object.used - 1;
+
+ status = fl_fss_extended_list_object_write(object, &location, buffer);
+
+ if (f_status_is_error(status) || status == f_no_data_on_stop || status == f_no_data_on_eos) {
+ return status;
+ }
+
+ if (status == f_none || status == f_none_on_stop || status == f_none_on_eos || status == f_none_on_eol) {
+ if (contents.used > 0) {
+ location.start = 0;
+ location.stop = contents.array[0].used - 1;
+ status = fl_fss_extended_list_content_write(contents.array[0], &location, buffer);
+
+ if (f_status_is_error(status) || status == f_no_data_on_stop || status == f_no_data_on_eos) {
+ return status;
+ }
+ }
+ else {
+ if (buffer->used >= buffer->size) {
+ f_macro_string_dynamic_resize(status, (*buffer), buffer->size + f_fss_default_allocation_step_string);
+ if (f_status_is_error(status)) return status;
+ }
+
+ buffer->string[buffer->used] = f_string_eol;
+ buffer->used++;
+ }
+ }
+
+ return f_none;
+ }
+#endif // _di_fll_fss_extended_list_write_
+*/
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: FSS
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * This is the fss-0003 implementation.
+ */
+#ifndef _FLL_fss_extended_list_h
+#define _FLL_fss_extended_list_h
+
+// fll-0 includes
+#include <level_0/status.h>
+#include <level_0/fss.h>
+#include <level_0/memory.h>
+#include <level_0/string.h>
+#include <level_0/type.h>
+
+// fll-1 includes
+#include <level_1/fss.h>
+#include <level_1/fss_extended_list.h>
+#include <level_1/fss_status.h>
+#include <level_1/fss_macro.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Read a buffer expected to be in fss-0003 format, getting all objects and their respective content.
+ *
+ * @param buffer
+ * 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.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_no_data_on_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing).
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ * f_unknown (with error bit) if a (what should be) impossible execution point 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);
+#endif // _di_fll_fss_extended_list_read_
+
+/**
+ * Write a single object string and content string to a buffer, using fss-0003 format.
+ *
+ * @param object
+ * A string representing the object.
+ * @param contents
+ * An array of strings representing multiple content to write.
+ * @param buffer
+ * The buffer to write to.
+ *
+ * @return
+ * f_none on success.
+ * f_none_on_stop on success after reaching stopping point .
+ * f_none_on_eos on success after reaching the end of the buffer.
+ * f_no_data_on_stop no data to write due start location being greater than stop location.
+ * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size.
+ * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
+ * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ * f_reallocation_error (with error bit) on reallocation error.
+ * f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fll_fss_extended_list_write_
+ //extern f_return_status fll_fss_extended_list_write(const f_string_dynamic object, const f_string_dynamics contents, f_string_dynamic *buffer);
+#endif // _di_fll_fss_extended_list_write_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FLL_fss_extended_list_h
build_linker ar
build_libraries -lc
build_libraries_fll -lfl_string -lfl_status -lfl_fss -lf_file -lf_utf -lf_conversion -lf_memory
-build_sources_library fss_basic.c fss_basic_list.c fss_extended.c fss_status.c
+build_sources_library fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c
build_sources_program
-build_sources_headers fss_basic.h fss_basic_list.h fss_extended.h fss_status.h
+build_sources_headers fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h
build_sources_bash
build_sources_settings
build_shared yes
-/**
- * Private source file for firewall.c.
- */
#include <level_3/byte_dump.h>
#include "private-byte_dump.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef _di_byte_dump_file_
f_return_status byte_dump_file(const byte_dump_data data, const f_string file_name, f_file file) {
f_status status = f_none;
fl_color_print_line(f_standard_error, context.error, context.reset, "'.");
}
#endif // _di_byte_dump_print_file_error_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
#include <level_3/firewall.h>
#include "private-firewall.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
f_return_status firewall_perform_commands(const firewall_local_data local, const firewall_data data) {
f_status status = f_none;
f_status status2 = f_none;
return f_none;
}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
#include <level_3/fss_basic_list_read.h>
#include "private-fss_basic_list_read.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef _di_fss_basic_list_read_main_process_file_
f_return_status fss_basic_list_read_main_process_file(const f_console_arguments arguments, fss_basic_list_read_data *data, const f_string filename, const f_string_length target) {
f_status status = f_none;
return f_none;
}
#endif // _di_fss_basic_list_read_main_process_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
#include <level_3/fss_basic_read.h>
#include "private-fss_basic_read.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef _di_fss_basic_read_main_process_file_
f_return_status fss_basic_read_main_process_file(const f_console_arguments arguments, fss_basic_read_data *data, const f_string filename, const f_string_length target) {
f_status status = f_none;
return f_none;
}
#endif // _di_fss_basic_read_main_process_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+#include <level_3/fss_extended_list_read.h>
+#include "private-fss_extended_list_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_extended_list_read_print_help_
+ f_return_status fss_extended_list_read_print_help(const fss_extended_list_read_data data) {
+ fll_program_print_help_header(data.context, fss_extended_list_read_name_long, fss_extended_list_read_version);
+
+ fll_program_print_help_option(data.context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message.");
+ fll_program_print_help_option(data.context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds.");
+ fll_program_print_help_option(data.context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds.");
+ fll_program_print_help_option(data.context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color.");
+ fll_program_print_help_option(data.context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number.");
+
+ printf("%c", f_string_eol);
+
+ 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, " Find and print content from this object name.");
+ fll_program_print_help_option(data.context, fss_extended_list_read_short_count, fss_extended_list_read_long_count, f_console_symbol_short_enable, f_console_symbol_long_enable, " Find a specific occurrence of the object.");
+ 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 in this file.");
+ 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_size, fss_extended_list_read_long_size, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print total lines in the given content.");
+ 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_usage(data.context, fss_extended_list_read_name, "filename(s)");
+
+ return f_none;
+ }
+#endif // _di_fss_extended_list_read_print_help_
+
+#ifndef _di_fss_extended_list_read_main_
+ f_return_status fss_extended_list_read_main(const f_console_arguments arguments, fss_extended_list_read_data *data) {
+ f_status status = f_none;
+
+ {
+ f_console_parameters parameters = { data->parameters, fss_extended_list_read_total_parameters };
+ f_console_parameter_id ids[3] = { fss_extended_list_read_parameter_no_color, fss_extended_list_read_parameter_light, fss_extended_list_read_parameter_dark };
+ f_console_parameter_ids choices = { ids, 3 };
+
+ status = fll_program_process_parameters(arguments, parameters, choices, &data->remaining, &data->context);
+ }
+
+ if (f_status_is_error(status)) {
+ fss_extended_list_read_delete_data(data);
+ return f_status_set_error(status);
+ }
+
+ f_status status2 = f_none;
+ status = f_none;
+
+ // execute parameter results
+ if (data->parameters[fss_extended_list_read_parameter_help].result == f_console_result_found) {
+ fss_extended_list_read_print_help(*data);
+ }
+ else if (data->parameters[fss_extended_list_read_parameter_version].result == f_console_result_found) {
+ fll_program_print_version(fss_extended_list_read_version);
+ }
+ else if (data->remaining.used > 0 || data->process_pipe) {
+ 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_count].result == f_console_result_additional) {
+ target = (f_string_length) atoll(arguments.argv[data->parameters[fss_extended_list_read_parameter_count].additional.array[0]]);
+ }
+
+ if (data->process_pipe) {
+ f_file file = f_file_initialize;
+
+ file.address = f_pipe;
+
+ status = fl_file_read_fifo(file, &data->buffer);
+
+ 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 f_file_open()");
+ }
+ else if (status == f_file_not_found) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to find the file '%s'", "-");
+ }
+ else if (status == f_file_open_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to open the file '%s'", "-");
+ }
+ else if (status == f_file_descriptor_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: File descriptor error while trying to open the file '%s'", "-");
+ }
+ else {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", f_status_set_error(status));
+ }
+
+ fss_extended_list_read_delete_data(data);
+ return status;
+ }
+
+ status = fss_extended_list_read_main_process_file(arguments, data, "-", target);
+
+ if (f_status_is_error(status)) {
+ 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);
+ }
+
+ for (; counter < data->remaining.used; counter++) {
+ f_file file = f_file_initialize;
+
+ status = f_file_open(&file, arguments.argv[data->remaining.array[counter]]);
+
+ data->file_position.total_elements = original_size;
+
+ 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 f_file_open()");
+ }
+ else if (status == f_file_not_found) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to find the file '%s'", arguments.argv[data->remaining.array[counter]]);
+ }
+ else if (status == f_file_open_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Unable to open the file '%s'", arguments.argv[data->remaining.array[counter]]);
+ }
+ else if (status == f_file_descriptor_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: File descriptor error while trying to open the file '%s'", arguments.argv[data->remaining.array[counter]]);
+ }
+ else {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", f_status_set_error(status));
+ }
+
+ fss_extended_list_read_delete_data(data);
+ return f_status_set_error(status);
+ }
+
+ if (data->file_position.total_elements == 0) {
+ fseek(file.address, 0, SEEK_END);
+
+ data->file_position.total_elements = ftell(file.address);
+
+ // skip past empty files
+ if (data->file_position.total_elements == 0) {
+ f_file_close(&file);
+ continue;
+ }
+
+ fseek(file.address, 0, SEEK_SET);
+ }
+
+ status = fl_file_read(file, data->file_position, &data->buffer);
+
+ f_file_close(&file);
+
+ 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 fl_file_read()");
+ }
+ else if (status == f_overflow) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", arguments.argv[data->remaining.array[counter]]);
+ }
+ else if (status == f_file_not_open) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: The file '%s' is no longer open", arguments.argv[data->remaining.array[counter]]);
+ }
+ else if (status == f_file_seek_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A seek error occurred while accessing the file '%s'", arguments.argv[data->remaining.array[counter]]);
+ }
+ else if (status == f_file_read_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: A read error occurred while accessing the file '%s'", arguments.argv[data->remaining.array[counter]]);
+ }
+ else if (status == f_allocation_error || status == f_reallocation_error) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
+ }
+ else {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", f_status_set_error(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]], target);
+
+ if (f_status_is_error(status)) {
+ return status;
+ }
+
+ // clear buffers before repeating the loop
+ f_macro_fss_contents_delete(status2, data->contents);
+ f_macro_fss_objects_delete(status2, data->objects);
+ f_macro_string_dynamic_delete(status2, data->buffer);
+ } // for
+ }
+ else {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files");
+ status = f_status_set_error(f_invalid_parameter);
+ }
+
+ fss_extended_list_read_delete_data(data);
+ return status;
+ }
+#endif // _di_fss_extended_list_read_main_
+
+#ifndef _di_fss_extended_list_read_delete_data_
+ f_return_status fss_extended_list_read_delete_data(fss_extended_list_read_data *data) {
+ f_status status = f_none;
+ f_string_length i = 0;
+
+ while (i < fss_extended_list_read_total_parameters) {
+ f_macro_string_lengths_delete(status, data->parameters[i].additional);
+ i++;
+ } // while
+
+ f_macro_fss_contents_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);
+
+ fl_macro_color_context_delete(status, data->context);
+
+ return f_none;
+ }
+#endif // _di_fss_extended_list_read_delete_data_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * This is the FSS Basic List Read program
+ * This program utilizes the Featureless Linux Library.
+ * This program processes files or other input in fss format and stores the results in the fss_extended_list_read_data.
+ */
+#ifndef _fss_extended_list_read_h
+
+// libc includes
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// fll-0 includes
+#include <level_0/console.h>
+#include <level_0/file.h>
+#include <level_0/pipe.h>
+#include <level_0/print.h>
+#include <level_0/string.h>
+#include <level_0/type.h>
+
+// fll-1 includes
+#include <level_1/color.h>
+#include <level_1/console.h>
+#include <level_1/directory.h>
+#include <level_1/file.h>
+#include <level_1/string.h>
+
+// fll-2 includes
+#include <level_2/execute.h>
+#include <level_2/fss_extended_list.h>
+#include <level_2/program.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_extended_list_read_version_
+ #define fss_extended_list_read_major_version "0"
+ #define fss_extended_list_read_minor_version "5"
+ #define fss_extended_list_read_micro_version "0"
+ #define fss_extended_list_read_version fss_extended_list_read_major_version "." fss_extended_list_read_minor_version "." fss_extended_list_read_micro_version
+#endif // _di_fss_extended_list_read_version_
+
+#ifndef _di_fss_extended_list_read_name_
+ #define fss_extended_list_read_name "fss_extended_list_read"
+ #define fss_extended_list_read_name_long "FSS Extended List Read"
+#endif // _di_fss_extended_list_read_name_
+
+#ifndef _di_fss_extended_list_read_defines_
+ #define fss_extended_list_read_short_name "n"
+ #define fss_extended_list_read_short_count "c"
+ #define fss_extended_list_read_short_total "t"
+ #define fss_extended_list_read_short_object "o"
+ #define fss_extended_list_read_short_size "s"
+ #define fss_extended_list_read_short_line "l"
+
+ #define fss_extended_list_read_long_name "name"
+ #define fss_extended_list_read_long_count "count"
+ #define fss_extended_list_read_long_total "total"
+ #define fss_extended_list_read_long_object "object"
+ #define fss_extended_list_read_long_size "size"
+ #define fss_extended_list_read_long_line "line"
+
+ enum {
+ fss_extended_list_read_parameter_help,
+ fss_extended_list_read_parameter_light,
+ fss_extended_list_read_parameter_dark,
+ fss_extended_list_read_parameter_no_color,
+ fss_extended_list_read_parameter_version,
+
+ fss_extended_list_read_parameter_name,
+ fss_extended_list_read_parameter_count,
+ fss_extended_list_read_parameter_total,
+ fss_extended_list_read_parameter_object,
+ fss_extended_list_read_parameter_size,
+ fss_extended_list_read_parameter_line,
+ };
+
+ #define f_console_parameter_initialize_fss_extended_list_read \
+ { \
+ f_console_parameter_initialize(f_console_standard_short_help, f_console_standard_long_help, 0, f_false, f_console_type_normal), \
+ f_console_parameter_initialize(f_console_standard_short_light, f_console_standard_long_light, 0, f_false, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, f_false, f_console_type_inverse), \
+ f_console_parameter_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, f_false, f_console_type_inverse), \
+ 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_name, fss_extended_list_read_long_name, 0, f_true, f_console_type_normal), \
+ f_console_parameter_initialize(fss_extended_list_read_short_count, fss_extended_list_read_long_count, 0, f_true, f_console_type_normal), \
+ f_console_parameter_initialize(fss_extended_list_read_short_total, fss_extended_list_read_long_total, 0, f_false, 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), \
+ f_console_parameter_initialize(fss_extended_list_read_short_size, fss_extended_list_read_long_size, 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), \
+ }
+
+ #define fss_extended_list_read_total_parameters 11
+#endif // _di_fss_extended_list_read_defines_
+
+#ifndef _di_fss_extended_list_read_data_
+ typedef struct {
+ f_console_parameter parameters[fss_extended_list_read_total_parameters];
+
+ f_string_dynamic buffer;
+ f_fss_objects objects;
+ f_fss_content_nests contents;
+ f_file_position file_position;
+ f_string_lengths remaining;
+ f_bool process_pipe;
+
+ fl_color_context context;
+ } fss_extended_list_read_data;
+
+ #define fss_extended_list_read_data_initialize \
+ { \
+ f_console_parameter_initialize_fss_extended_list_read, \
+ f_string_dynamic_initialize, \
+ f_fss_objects_initialize, \
+ f_fss_content_nests_initialize, \
+ f_file_position_initialize, \
+ f_string_lengths_initialize, \
+ f_false, \
+ fl_color_context_initialize, \
+ }
+#endif // _di_fss_extended_list_read_data_
+
+/**
+ * Print help to standard output.
+ *
+ * @param data
+ * The program data.
+ *
+ * @return
+ * f_none on success.
+ */
+#ifndef _di_fss_extended_list_read_print_help_
+ extern f_return_status fss_extended_list_read_print_help(const fss_extended_list_read_data data);
+#endif // _di_fss_extended_list_read_print_help_
+
+/**
+ * Execute main program.
+ *
+ * Be sure to call fss_extended_list_read_delete_data() after executing this.
+ *
+ * @param arguments
+ * The parameters passed to the process.
+ * @param data
+ * The program data.
+ *
+ * @return
+ * f_none on success.
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see fss_extended_list_read_delete_data()
+ */
+#ifndef _di_fss_extended_list_read_main_
+ extern f_return_status fss_extended_list_read_main(const f_console_arguments arguments, fss_extended_list_read_data *data);
+#endif // _di_fss_extended_list_read_main_
+
+/**
+ * Deallocate data.
+ *
+ * Be sure to call this after executing fss_extended_list_read_main().
+ *
+ * @param data
+ * The program data.
+ *
+ * @return
+ * f_none on success.
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see fss_extended_list_read_main()
+ */
+#ifndef _di_fss_extended_list_read_delete_data_
+ extern f_return_status fss_extended_list_read_delete_data(fss_extended_list_read_data *data);
+#endif // _di_fss_extended_list_read_delete_data_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_extended_list_read_h
--- /dev/null
+#include <level_3/fss_extended_list_read.h>
+
+int main(const unsigned long argc, const f_string *argv) {
+ const f_console_arguments arguments = { argc, argv };
+ fss_extended_list_read_data data = fss_extended_list_read_data_initialize;
+
+ if (f_pipe_exists()) {
+ data.process_pipe = f_true;
+ }
+
+ f_status status = fss_extended_list_read_main(arguments, &data);
+
+ if (f_status_is_error(status)) {
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+#include <level_3/fss_extended_list_read.h>
+#include "private-fss_extended_list_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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_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;
+
+ status = fll_fss_extended_list_read(&data->buffer, &input, &data->objects, &data->contents);
+
+ 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);
+ }
+ else if (status == f_allocation_error || status == f_reallocation_error) {
+ 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 occured on invalid UTF-8 character at stop position (at %d).", input.start);
+ }
+ else if (status == f_incomplete_utf_on_eos) {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start);
+ }
+ else {
+ fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_list_read() for the file '%s'", f_status_set_error(status), filename);
+ }
+
+ 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);
+
+ 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, "%u\n", (unsigned int) data->objects.used);
+ }
+ 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_count].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_count].result == f_console_result_additional && found == target)) {
+
+ 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;
+
+ for (; counter <= data->contents.array[current].array[0].range.stop; counter++) {
+ if (data->buffer.string[counter] == f_string_eol) size++;
+ } // for
+
+ // the last newline is never present
+ size++;
+
+ 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->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");
+ }
+ }
+ }
+
+ if (data->parameters[fss_extended_list_read_parameter_count].result == f_console_result_additional) {
+ if (found == target) {
+ break;
+ }
+ else {
+ found++;
+ }
+ }
+ } // for
+ }
+ else {
+ for (; current < data->objects.used; current++) {
+ if (data->parameters[fss_extended_list_read_parameter_count].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_count].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_count].result == f_console_result_additional) {
+ if (found == target) {
+ break;
+ }
+ else {
+ found++;
+ }
+ }
+ } // for
+ }
+ }
+ else {
+ current = 0;
+
+ f_string_length total = 0;
+ f_string_length name_length = 0;
+ f_string_length argv_length = 0;
+
+ 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]]);
+
+ 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;
+
+ 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 (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;
+
+ for (; counter <= data->contents.array[current].array[0].range.stop; counter++) {
+ if (data->buffer.string[counter] == f_string_eol) size++;
+ } // for
+
+ // the last newline is never present
+ size++;
+
+ 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_count].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_count].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");
+ }
+ }
+ }
+ }
+
+ if (data->parameters[fss_extended_list_read_parameter_count].result == f_console_result_additional) {
+ if (found == target) {
+ break;
+ }
+ else {
+ found++;
+ }
+ }
+ }
+ }
+ } // for
+
+ if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_extended_list_read_parameter_count].result == f_console_result_none) {
+ fprintf(f_standard_output, f_string_length_printf "\n", total);
+ }
+ }
+ 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_count].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_count].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_count].result == f_console_result_additional) {
+ if (found == target) {
+ break;
+ }
+ else {
+ found++;
+ }
+ }
+ }
+ }
+ }
+ } // for
+ }
+ }
+ }
+ }
+
+ return f_none;
+ }
+#endif // _di_fss_extended_list_read_main_process_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#ifndef _PRIVATE_fss_extended_list_read_h
+#define _PRIVATE_fss_extended_list_read_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#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;
+#endif // _di_fss_extended_list_read_main_process_file_
+
+#endif // _PRIVATE_fss_extended_list_read_h
--- /dev/null
+f_type
+f_status
+f_memory
+f_string
+f_console
+f_fss
+f_pipe
+f_print
+fl_color
+fl_console
+fl_directory
+fl_file
+fl_fss
+fl_status
+fl_string
+fll_execute
+fll_fss
+fll_program
--- /dev/null
+# fss-0000
+
+project_name fss_extended_list_read
+project_level 3
+
+version_major 0
+version_minor 5
+version_micro 0
+
+build_compiler gcc
+build_linker ar
+build_libraries -lc
+build_libraries_fll -lfll_program -lfll_fss -lfll_execute -lfl_string -lfl_status -lfl_fss -lf_conversion -lfl_file -lfl_directory -lfl_console -lf_utf -lfl_color -lf_file -lf_print -lf_pipe -lf_console -lf_memory
+#build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
+#build_libraries_fll-monolithic -lfll
+build_sources_library fss_extended_list_read.c private-fss_extended_list_read.c
+build_sources_program main.c
+build_sources_headers fss_extended_list_read.h
+build_sources_bash
+build_sources_settings
+build_shared yes
+build_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE -lfss_extended_list_read
i++;
} // while
- f_macro_fss_contents_delete(status, data->contents);
+ 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);
#include <level_3/fss_extended_read.h>
#include "private-fss_extended_read.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef _di_fss_extended_read_main_process_file_
f_return_status fss_extended_read_main_process_file(const f_console_arguments arguments, fss_extended_read_data *data, const f_string filename, const f_string_length target, const f_string_length select) {
f_status status = f_none;
return f_none;
}
#endif // _di_fss_extended_read_main_process_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
* This is the Kevux Operating System Init program.
* This program utilizes the Featureless Linux Library.
*
- * This init program is designed to run with certain paths and if they do not exist, it will attemp to create them.
- * This expects the kevux path permissions structure and naming, so a valid /etc/group file should exist.
+ * This init program is designed to run with certain paths and if they do not exist, it will attempt to create them.
+ * This expects the Kevux path permissions structure and naming, so a valid /etc/group file should exist.
*
* This is designed to have different threads handling the following actions:
- * Thread Group 1 (Signals and Output)
+ * Thread Group 1 (Signals and Control)
* - (parent process) handles/blocks all signals for init program and handles children accordingly.
+ * - runs as root.
*
* Thread Group 2 (Services)
* - Handles starting and stopping of individual services.
* - New thread created for each user.
+ * - Runs as root.
+ * - Each individual thread runs as a specified user.
*
- * Thread Group 3 (Reporting)
+ * Thread Group 3 (Reporting and Output)
* - Handles output to the terminal or any other supported devices.
* - No child threads.
+ * - Runs as init user.
*
- * Thread Group 4 (Commands: Time)
- * - Handles time based processing.
- * - This is a cron system.
- * - 2 Child threads:
- * 1) Cron-style behavior.
- * 2) Anacron-style behavior.
- *
- * Thread Group 5 (Commands: Socket File)
+ * Thread Group 4 (Commands: Socket File)
* - If socket file is enabled, then this thread is created to listen on the socket file and process received commands.
* - No child threads.
+ * - Runs as init user.
*
- * Thread Group 6 (Commands: Socket Port)
+ * Thread Group 5 (Commands: Socket Port)
* - If socket port is enabled, then this thread is created to listen on the socket port and process received commands.
* - No child threads.
- *
- *
- * Time based (aka: cron) functionality is being implemented here because cron jobs often need to run as specific users.
- * The init program is already root and can already switch users, so give it control.
- * This avoids having yet another program that must have root privileges.
+ * - Runs as init user.
*
* It would be nice to be able to start the init program as a non-root user who has elevated privileges similar to root.
* - That is, have ability to su to any user (except root).
#define init_paths_init_socket "/run/init/socket/"
#define init_paths_init_process "/run/init/process/"
#define init_paths_init_log "/log/init/"
+ #define init_paths_init_log "/tmp/init/"
#define init_paths_log "/log/"
#endif // _di_init_paths_
#define init_group_init_socket "d_init_socket"
#define init_group_init_process "d_init_process"
#define init_group_init_log "d_log"
+ #define init_group_init_tmp "d_init"
#define init_group_process_null "p_null"
#define init_group_process_zero "p_zero"
#define init_group_process_console "p_terminal"
fl_color_context context;
} init_data;
- #define init_argument_initialize \
+ #define init_data_initialize \
{ \
f_console_parameter_initialize_init, \
f_string_lengths_initialize, \
f_false, \
fl_color_context_initialize, \
}
+
+ typedef struct {
+ uint8_t todo_placeholder;
+ } init_data_thread_control;
+
+ #define init_data_thread_control_initialize \
+ { \
+ 0 \
+ }
+
+ typedef struct {
+ uint8_t todo_placeholder;
+ } init_data_thread_service;
+
+ #define init_data_thread_service_initialize \
+ { \
+ 0 \
+ }
+
+ typedef struct {
+ uint8_t todo_placeholder;
+ } init_data_thread_socket_file;
+
+ #define init_data_thread_socket_file_initialize \
+ { \
+ 0 \
+ }
+
+ typedef struct {
+ uint8_t todo_placeholder;
+ } init_data_thread_socket_port;
+
+ #define init_data_thread_socket_port_initialize \
+ { \
+ 0 \
+ }
#endif // _di_init_data_
#ifndef _di_init_print_version_
extern f_return_status init_main(const f_console_arguments arguments, init_data *data);
#endif // _di_init_main_
+/**
+ * Execute main program.
+ *
+ * @param arguments
+ * The parameters passed to the process.
+ * @param data
+ * The program data.
+ *
+ * @return
+ * f_none on success.
+ * Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_init_main_
+ extern f_return_status init_thread_control(const init_data *data);
+#endif // _di_init_main_
+
#ifdef __cplusplus
} // extern "C"
#endif
int main(const unsigned long argc, const f_string *argv) {
const f_console_arguments arguments = { argc, argv };
- init_data data = init_argument_initialize;
+ init_data data = init_data_initialize;
if (f_pipe_exists()) {
data.process_pipe = f_true;
init_rule main_failsafe;
} init_setting;
- #define init_data_initialize \
+ #define init_setting_initialize \
{ \
f_string_initialize, \
0, \
0, \
0, \
0, \
- init_argument_initialize, \
init_data_initialize, \
+ init_setting_initialize, \
}
// custom settings to prepare the init process.