* The standard FSS character header is: "# fss-0000\n\0", which is 10 characters + newline + EOS = 12.
*
* The UTF-8 BOM is not supported because it is not an actual thing (only a suggestion according to rfc3629).
- * The UTF-8 BOM sequence is actually a different character called "zero-width non breaking space".
- * Because it already has use, this project considers the existence of UTF-8 BOM bad practice in all cases.
+ * The UTF-8 BOM sequence is actually a different character called "zero-width non-breaking space".
+ * Because it already has a use, this project considers the existence of UTF-8 BOM bad practice in all cases.
* After all, if your file begins with a "zero-width non breaking space", you may want to actually use a space and not a "BOM".
*/
#ifndef _di_f_fss_max_header_length_
#define f_macro_fss_contents_adjust(status, contents, new_length) f_macro_memory_structures_resize(status, contents, f_fss_content, new_length, f_array_length)
#endif // _di_f_fss_contents_
+/**
+ * This holds a object and its associated 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.
+ * content: The content associated with the object.
+ * parent: A location referencing a parrent object or content that this object content is nested under.
+ */
+#ifndef _di_fss_content_child_
+ typedef struct {
+ f_fss_object object;
+ f_fss_content content;
+ f_array_length parent;
+ } f_fss_content_child;
+
+ #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)
+
+ #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_
+
+/**
+ * This holds an array of fss_content_child.
+ *
+ * This is designed to be used as a part of f_fss_content_nest.
+ * Range represents the full range of the particular content set.
+ * Range can exist before the first child and after the last child to represent unnested data within the content.
+ *
+ * For example:
+ * object {
+ * fss_basic_content before nested content.
+ * nested_1 {
+ * Nested content one.
+ * }
+ *
+ * More content in between.
+ *
+ * nested_2 {
+ * Nested content two.
+ * nested_3 {
+ * Nested content three.
+ * }
+ * }
+ *
+ * More content after.
+ * }
+ *
+ * range: A location range representing the full start/stop locations of the entire set.
+ * array: The array of objectm their associated content, and their associated parent.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
+ */
+#ifndef _di_fss_content_childs_
+ typedef struct {
+ f_string_location range;
+ f_fss_content_child *array;
+ f_array_length size;
+ f_array_length used;
+ } f_fss_content_childs;
+
+ #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)
+#endif // _di_fss_content_childs_
+
+/**
+ * This holds an array of f_fss_content_childs.
+ *
+ * Each array row represents the nesting depth.
+ * The top-level will not have any parent, so "parent" must be ignored on anything at index 0.
+ * The parent identifier is expected to reference a position in the nesting depth immediately above it.
+ *
+ * array: an array of child objects.
+ * size: Total amount of allocated space.
+ * used: Total number of allocated spaces used.
+ */
+#ifndef _di_fss_content_nest_
+ typedef struct {
+ f_fss_content_childs *array;
+ f_array_length size;
+ f_array_length used;
+ } f_fss_content_nest;
+
+ #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)
+#endif // _di_fss_content_nest_
+
#ifdef __cplusplus
} // extern "C"
#endif
f_status status = f_none;
- // delimits must only be applied once a valid object is found
+ // delimits must only be applied once a valid object is found.
f_string_lengths delimits = f_string_lengths_initialize;
fl_fss_skip_past_whitespace(*buffer, location);
fl_macro_fss_object_return_on_overflow((*buffer), (*location), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
- // return found nothing if this line only contains whitespace and delimit placeholders
+ // return found nothing if this line only contains whitespace and delimit placeholders.
if (buffer->string[location->start] == f_string_eol) {
status = fl_fss_increment_buffer(*buffer, location, 1);
if (f_status_is_error(status)) return status;
return fl_fss_found_no_object;
}
- // begin the search
+ // begin the search.
found->start = location->start;
- // ignore all comment lines
+ // ignore all comment lines.
if (buffer->string[location->start] == f_fss_comment) {
fl_macro_fss_object_seek_till_newline((*buffer), (*location), delimits, f_no_data_on_eos, f_no_data_on_stop)
return fl_fss_found_no_object;
}
- // identify where the object ends
+ // identify where the object ends.
while (location->start < buffer->used && location->start <= location->stop && buffer->string[location->start] != f_string_eol) {
if (buffer->string[location->start] == f_fss_delimit_slash) {
f_string_length first_slash = location->start;
fl_macro_fss_object_return_on_overflow((*buffer), (*location), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
if (buffer->string[location->start] == f_string_eol) {
- f_string_length length = location->start;
+ f_string_length start = location->start;
location->start = first_slash;
fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
found->stop = stop_point;
- location->start = length + 1;
+ location->start = start + 1;
return fl_fss_found_object;
}
- location->start = length + 1;
+ location->start = start + 1;
return fl_fss_found_no_object;
}
}
if (f_status_is_error(status)) return status;
} // while
- // seek to the end of the line when no valid object is found
+ // seek to the end of the line when no valid object is found.
while (location->start < buffer->used && location->start <= location->stop && buffer->string[location->start] != f_string_eol) {
status = fl_fss_increment_buffer(*buffer, location, 1);
if (f_status_is_error(status)) return status;
#endif // _di_fl_fss_extended_list_object_read_
#ifndef _di_fl_fss_extended_list_content_read_
- f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_location *location, f_fss_content *found) {
+ f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_location *location, f_fss_content_nest *found) {
#ifndef _di_level_1_parameter_checking_
if (buffer == 0) return f_status_set_error(f_invalid_parameter);
if (location == 0) return f_status_set_error(f_invalid_parameter);
f_status status = f_none;
- // delimits must only be applied once a valid object is found
+ // delimits must only be applied once a valid object is found.
f_string_lengths delimits = f_string_lengths_initialize;
fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*location))
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_bool found_newline = f_false;
+ f_fss_object object = f_fss_object_initialize;
+
+ f_macro_string_lengths_new(status, positions_start, f_fss_default_allocation_step);
+ if (f_status_is_error(status)) {
+ f_macro_string_lengths_delete(status, delimits);
+
+ return status;
+ }
+
+ // initialize depth 0 start position.
+ // positions_start.used is used as a max depth (such that positions_start.used == max depth + 1).
+ positions_start.array[0] = location->start;
+ positions_start.used = 1;
- // identify where the content ends
while (location->start < buffer->used && location->start <= location->stop) {
if (buffer->string[location->start] == f_string_eol) {
- found_newline = f_true;
last_newline = location->start;
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
- fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
+ }
+ else {
+ fl_macro_fss_content_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop)
+ }
continue;
}
if (buffer->string[location->start] == f_fss_delimit_slash) {
- f_string_length first_slash = location->start;
+ f_string_length slash_first = location->start;
+ f_string_length slash_last = location->start;
f_string_length slash_count = 1;
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
- while (location->start < buffer->used && location->start <= location->stop && (buffer->string[location->start] == f_fss_delimit_placeholder || buffer->string[location->start] == f_fss_delimit_slash)) {
- if (buffer->string[location->start] == f_fss_delimit_slash) {
- slash_count++;
- }
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+ return status;
+ }
+
+ while (location->start < buffer->used && location->start <= location->stop && (buffer->string[location->start] == f_fss_delimit_placeholder || buffer->string[location->start] == f_fss_delimit_slash)) {
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ if (buffer->string[location->start] == f_fss_delimit_slash) {
+ slash_last = location->start;
+ slash_count++;
+ }
+
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
} // while
- if (found_newline) {
- fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
}
else {
- fl_macro_fss_content_return_on_overflow((*buffer), (*location), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop)
}
- if (buffer->string[location->start] == f_fss_extended_list_open) {
- f_string_length stop_point = location->start - 1;
+ // All slashes for an open are delimited (because it could represent a slash in the object name).
+ // for example 'object {' = valid open, name 'object', 'object \{' represents 'object {', 'object \\{' = valid open, name 'object \', 'object \\\{' represents 'object \{', etc..
+ // Only the first slash before a close is delimited, all others are maintained.
+ // for example '}' = valid close, '\}' represents '}', '\\}' represents '\}', '\\\}' represents '\\}', '\\\\}' represents '\\\}', and so on..
+ // When slash is odd and a (delimited) valid open/close is found, then save delimited positions and continue.
+ if (buffer->string[location->start] == f_string_eol) {
+ last_newline = location->start;
+ position_previous = location->start;
+ location->start++;
+ }
+ else if (buffer->string[location->start] == f_fss_extended_list_open || buffer->string[location->start] == f_fss_extended_list_close) {
+ f_bool is_open = f_false;
- status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (buffer->string[location->start] == f_fss_extended_list_open) {
+ is_open = f_true;
+ }
+
+ position_previous = location->start;
+ location->start++;
while (location->start < buffer->used && location->start <= location->stop) {
- if (buffer->string[location->start] == f_string_eol || (status = fl_fss_is_graph(*buffer, *location)) == f_true) {
+ if (buffer->string[location->start] == f_string_eol) {
break;
}
- if (f_status_is_error(status)) return status;
+ if (buffer->string[location->start] != f_fss_delimit_placeholder && (status = fl_fss_is_space(*buffer, *location)) == f_false) {
+ break;
+ }
+
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+ return status;
+ }
+
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
} // while
- if (found_newline) {
- fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
}
else {
- fl_macro_fss_content_return_on_overflow((*buffer), (*location), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop)
}
+ // this is a valid object open/close that has been delimited, save the slash delimit positions.
if (buffer->string[location->start] == f_string_eol) {
- f_string_length length = location->start;
- location->start = first_slash;
+ if (is_open) {
+ f_bool is_object = f_false;
+ f_string_location location_newline = location->start;
- if (slash_count % 2 == 0) {
- // FIXME: apply delimits??
- if (found_newline) {
- fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
+ if (slash_count % 2 == 0) {
+ is_object = f_true;
+ }
+
+ location->start = slash_first;
+
+ if (delimits.used + (slash_count / 2) >= delimits.size) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_resize(allocation_status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step);
- found->array[found->used].stop = last_newline;
- location->start = last_newline + 1;
- found->used++;
+ if (f_status_is_error(allocation_status)) {
+ f_macro_string_lengths_delete(status, delimits);
+ f_macro_string_lengths_delete(status, positions_start);
- return fl_fss_found_content;
+ return allocation_status;
+ }
}
- return fl_fss_found_no_content;
- }
+ // apply slash delimits, only slashes and placeholders should be present.
+ while (slash_count > 0) {
+ if (buffer->string[location->start] == f_fss_delimit_slash) {
+ if (slash_count % 2 != 0) {
+ delimits.array[delimits.used] = location->start;
+ delimits.used++;
+ }
- if (delimits.used + (slash_count / 2) >= delimits.size) {
- f_status allocation_status = f_none;
+ slash_count--;
+ }
- f_macro_string_lengths_resize(allocation_status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step);
+ // Delimit slashes and placeholders are required to be in the ASCII range.
+ location->start++;
+ } // while
- if (f_status_is_error(allocation_status)) {
- f_macro_string_lengths_delete(allocation_status, delimits);
- return allocation_status;
+ // when slashes are even, the object is valid and needs to be processed.
+ if (is_object) {
+ depth++;
+
+ if (depth >= positions_start.size) {
+ f_macro_string_lengths_resize(status, (*positions_start), positions_start.size + f_fss_default_allocation_step);
+
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ }
+
+ if (positions_start.used <= depth) {
+ positions_start.used = depth + 1;
+ }
+
+ positions_start.array[depth] = location_newline + 1;
+
+ object.start = last_newline + 1;
+ object.stop = position_previous;
}
+
+ last_newline = location_newline;
}
+ else {
+ last_newline = location->start;
+ location->start = slash_last;
- while (slash_count > 0) {
- if (buffer->string[location->start] == f_fss_delimit_slash) {
- if (slash_count % 2 != 0) {
- delimits.array[delimits.used] = location->start;
- delimits.used++;
- }
+ if (delimits.used + 1 >= delimits.size) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_resize(allocation_status, delimits, delimits.size + f_fss_default_allocation_step);
- slash_count--;
+ if (f_status_is_error(allocation_status)) {
+ f_macro_string_lengths_delete(status, delimits);
+ f_macro_string_lengths_delete(status, positions_start);
+
+ return allocation_status;
+ }
}
- status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
- } // while
+ delimits.array[delimits.used] = slash_last;
+ delimits.used++;
+ }
- found_newline = f_true;
- location->start = length + 1;
+ location->start = last_newline;
}
}
-
- continue;
}
else if (buffer->string[location->start] == f_fss_extended_list_open) {
+ f_string_length location_open = location->start;
+
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
while (location->start < buffer->used && location->start <= location->stop) {
- if (buffer->string[location->start] == f_string_eol || (status = fl_fss_is_graph(*buffer, *location)) == f_true) {
+ if (buffer->string[location->start] == f_string_eol) {
break;
}
- if (f_status_is_error(status)) return status;
+ if (buffer->string[location->start] != f_fss_delimit_placeholder && (status = fl_fss_is_space(*buffer, *location)) == f_false) {
+ break;
+ }
+
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+ return status;
+ }
+
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
} // while
- if (found_newline) {
- fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
}
else {
- fl_macro_fss_content_return_on_overflow((*buffer), (*location), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop)
}
if (buffer->string[location->start] == f_string_eol) {
- if (found_newline) {
- fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
+ depth++;
- found->array[found->used].stop = last_newline;
- location->start = last_newline + 1;
- found->used++;
+ if (depth >= positions_start.size) {
+ f_macro_string_lengths_resize(status, (*positions_start), positions_start.size + f_fss_default_allocation_step);
- return fl_fss_found_content;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
}
- if (!found_newline) {
- location->start = last_newline;
+ if (positions_start.used <= depth) {
+ positions_start.used = depth + 1;
}
- return fl_fss_found_no_content;
+ positions_start.array[depth] = location->start + 1;
+
+ object.start = last_newline + 1;
+ object.stop = position_previous;
}
+ // No valid object open found, seek until EOL.
+ else {
+ while (location->start < buffer->used && location->start <= location->stop) {
+ if (buffer->string[location->start] == f_string_eol) {
+ break;
+ }
- continue;
+ position_previous = location->start;
+ status = fl_fss_increment_buffer(*buffer, location, 1);
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ } // while
+
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
+ }
+ else {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop)
+ }
+ }
+
+ last_newline = location->start;
}
+ else if (buffer->string[location->start] == f_fss_extended_list_close) {
+ position_previous = location->start;
+ status = fl_fss_increment_buffer(*buffer, location, 1);
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+
+ while (location->start < buffer->used && location->start <= location->stop) {
+ if (buffer->string[location->start] == f_string_eol) {
+ break;
+ }
+
+ if (buffer->string[location->start] != f_fss_delimit_placeholder && (status = fl_fss_is_space(*buffer, *location)) == f_false) {
+ break;
+ }
+
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+ return status;
+ }
+
+ position_previous = location->start;
+ status = fl_fss_increment_buffer(*buffer, location, 1);
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ } // while
+
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
+ }
+ else {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop)
+ }
+
+ if (buffer->string[location->start] == f_string_eol) {
+ if (found->used >= found->size) {
+ f_macro_fss_content_nest_resize(status, (*found), found->size + f_fss_default_allocation_step);
+
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ }
+
+ 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_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ }
+
+ 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 (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ }
+
+ 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->used = positions_start.used;
+
+ if (depth == 0) {
+ last_newline = location->start;
+ break;
+ }
+
+ depth--;
+ }
+ // No valid object close found, seek until EOL.
+ else {
+ while (location->start < buffer->used && location->start <= location->stop) {
+ if (buffer->string[location->start] == f_string_eol) {
+ break;
+ }
+
+ position_previous = location->start;
+ status = fl_fss_increment_buffer(*buffer, location, 1);
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
+ } // while
+
+ if (depth > 0) {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop)
+ }
+ else {
+ fl_macro_fss_content_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop)
+ }
+ }
+
+ last_newline = location->start;
+ }
+
+ position_previous = location->start;
status = fl_fss_increment_buffer(*buffer, location, 1);
- if (f_status_is_error(status)) return status;
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
+
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
+
+ return status;
+ }
} // while
- if (found_newline) {
- fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
+ fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
- found->array[found->used].stop = last_newline - 1;
- location->start = last_newline + 1;
- found->used++;
+ location->start = last_newline;
+ status = fl_fss_decrement_buffer(*buffer, location, 1);
+ if (f_status_is_error(status)) {
+ f_status allocation_status = f_none;
- fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop)
+ f_macro_string_lengths_delete(allocation_status, delimits);
+ f_macro_string_lengths_delete(allocation_status, positions_start);
- return fl_fss_found_content;
+ return status;
}
- fl_macro_fss_content_return_on_overflow((*buffer), (*location), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
+ 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)
+
+ f_macro_string_lengths_delete(status, delimits);
+ f_macro_string_lengths_delete(status, positions_start);
- return fl_fss_found_no_content;
+ return fl_fss_found_content;
}
#endif // _di_fl_fss_extended_list_content_read_
while (location->start <= location->stop && location->start < object.used) {
if (object.string[location->start] == f_fss_comment) {
// comments are not allowed and this format has no way of "wrapping" a comment.
- return f_status_set_error(f_invalid_data);
+ return f_status_set_error(fl_fss_found_comment);
}
else if ((status = fl_fss_is_graph(object, *location)) == f_true) {
break;
}
}
else if (object.string[location->start] == f_string_eol) {
- // @todo: review what this is doing.
if (buffer_position.stop == buffer_position.start) {
return f_no_data_on_eol;
}
} // while
if (content.string[location->start] == f_fss_extended_list_open) {
- f_string_length length = location->start;
+ f_string_length start = location->start;
status = fl_fss_increment_buffer(content, location, 1);
if (f_status_is_error(status)) return status;
buffer->string[buffer_position.stop] = f_fss_extended_list_open;
buffer_position.stop++;
- location->start = length + 1;
+ location->start = start + 1;
continue;
}
}
else if (content.string[location->start] == f_fss_extended_list_open && !is_comment) {
- f_string_length length = location->start;
+ f_string_length start = location->start;
has_graph = f_true;
buffer->string[buffer_position.stop] = f_fss_extended_list_open;
buffer_position.stop++;
- location->start = length + 1;
+ location->start = start + 1;
continue;
}
else if (content.string[location->start] == f_fss_comment && !has_graph) {