#define ___fl_flag_as_object___ 0x1
- #define ___fl_flag_do_handle___ 0x1
- #define ___fl_flag_has_combining___ 0x2
- #define ___fl_flag_has_combining_joiner___ 0xa
- #define ___fl_flag_has_increased___ 0x4
- #define ___fl_flag_has_joiner___ 0x8
- #define ___fl_flag_is_quoted___ 0x10
- #define ___fl_flag_is_commented___ 0x20
- #define ___fl_flag_save_partial___ 0x40
+ #define ___fl_flag_has_combining___ 0x1
+ #define ___fl_flag_has_combining_joiner___ 0x5
+ #define ___fl_flag_has_increased___ 0x2
+ #define ___fl_flag_has_joiner___ 0x4
+ #define ___fl_flag_is_quoted___ 0x8
+ #define ___fl_flag_is_commented___ 0x10
+ #define ___fl_flag_save_character___ 0x20
+ #define ___fl_flag_save_comment___ 0x40
+ #define ___fl_flag_save_normal___ 0x80
+ #define ___fl_flag_save_partial___ 0x100
+ #define ___fl_flag_save_quote___ 0x200
+ #define ___fl_flag_save_quote_character___ 0x220
+ #define ___fl_flag_save_slash___ 0x400
+ #define ___fl_flag_save_slash_quote___ 0x600
const f_number_unsigned_t input_start = range->start;
const f_number_unsigned_t used_start = destination->used;
- uint8_t commented = F_false;
uint8_t width = 0;
uint8_t flag_fl = 0x0;
if (F_status_is_error_not(state->status)) {
partial.stop = range->start;
+ // (partial.stop - partial.start) + 1 (range), 2 (for both open and close quotes), 1 (for terminating NULL).
state->status = f_memory_array_increase_by((partial.stop - partial.start) + 4, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
}
if (F_status_set_fine(state->status) == F_interrupt) break;
}
- flag_fl |= ___fl_flag_do_handle___;
+ flag_fl |= ___fl_flag_save_normal___;
if (object.string[range->start] == f_fss_slash_s.string[0]) {
item_first = partial.start = range->start++;
// End of string or end of buffer can only happen when only slashes and delimit place holders are found.
if (range->start > range->stop || range->start >= object.used) {
- partial.stop = range->start;
- flag_fl |= ___fl_flag_save_partial___;
- // Slashes at end of line must be escaped when there is a quote.
+ // Slashes at end of line must be escaped when there is a leading quote.
if (flag_fl & ___fl_flag_is_quoted___) {
item_total *= 2;
}
+ flag_fl |= ___fl_flag_save_slash___;
+
break;
}
}
}
- if (F_status_is_error(state->status) || range->start > range->stop || range->start >= object.used) break;
+ if (F_status_is_error(state->status)) break;
+
+ if (range->start > range->stop || range->start >= object.used) {
+ flag_fl |= ___fl_flag_save_slash___;
+
+ if (object.string[partial.stop] == quote_char) {
+ flag_fl |= ___fl_flag_save_quote___;
+ }
+ else if (object.string[partial.stop] == f_fss_comment_s.string[0]) {
+ flag_fl |= ___fl_flag_save_comment___;
+ }
+
+ break;
+ }
range->start = partial.stop;
else if (object.string[range->start] == quote_char) {
++range->start;
+ flag_fl |= ___fl_flag_save_quote___;
+
f_fss_skip_past_delimit(object, range, state);
if (F_status_is_error(state->status)) break;
if (range->start > range->stop || range->start >= object.used) {
- state->status = f_memory_array_increase_by(item_total + 3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
- if (F_status_is_error(state->status)) break;
- for (i = 0; i < item_total; ++i) { // TODO: what is the correct number of slashes?
- destination->string[destination->used++] = f_fss_slash_s.string[0];
- } // for
+ // Slashes before a closing quote must escaped when there is a leading quote.
+ if (flag_fl & ___fl_flag_is_quoted___ && item_total) {
+ item_total *= 2;
+ }
- destination->string[destination->used++] = quote_char;
- item_total = 0;
+ flag_fl |= ___fl_flag_save_slash___;
break;
}
// If any space is found after a quote after a slash, then this must be delimited and quote.
if (f_fss_is_space(object, *range, state) == F_false) {
if (F_status_is_error(state->status)) break;
+
+ item_total = 0;
}
else {
- // TODO: Verify no combining joiners following.
if (object.string[range->start] == f_fss_eol_s.string[0]) {
+ // TODO: add flag or ending on eol with this status.
+ // TODO: is this really an error?
+ // TODO: set flag_fl |= ___fl_flag_save_slash_quote___; appropriately here.
state->status = F_status_set_error(F_okay_eol);
break;
}
+ // TODO: Verify no combining joiners following space.
flag_fl |= ___fl_flag_is_quoted___;
-
- state->status = f_memory_array_increase_by(item_total + 3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
- if (F_status_is_error(state->status)) break;
-
- // Add the slashes that delimit the slashes.
- if (item_first == input_start) {
- destination->string[destination->used++] = f_fss_slash_s.string[0];
- }
- else {
- for (i = 0; i < item_total; ++i) {
- destination->string[destination->used++] = f_fss_slash_s.string[0];
- } // for
- }
}
- width = macro_f_utf_byte_width(object.string[range->start]);
-
- state->status = f_memory_array_increase_by(item_total + width + 3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
- if (F_status_is_error(state->status)) break;
-
- for (i = 0; i < item_total; ++i) {
- destination->string[destination->used++] = f_fss_slash_s.string[0];
- } // for
-
- destination->string[destination->used++] = quote_char;
-
- memcpy(destination->string + destination->used, object.string + range->start, width);
-
- destination->used += width;
- item_total = 0;
+ flag_fl |= ___fl_flag_save_character___;
}
- else if ((flag & ___fl_flag_as_object___) && object.string[range->start] == f_fss_comment_s.string[0]) {
+ else if (!(flag_fl & ___fl_flag_is_quoted___) && (flag & ___fl_flag_as_object___) && object.string[range->start] == f_fss_comment_s.string[0]) { // TODO: monitor if first character is found and if so, then skip over comment entirely.
// TODO: Verify no combining joiners following.
+ // FIXME: this block looks incorrect. Shouldn't comment b escaped?
// Only the first slash needs to be escaped for a comment, and then only if not quote.
if (item_first == input_start) {
- commented = F_true;
+ flag_fl |= ___fl_flag_is_commented___;
}
+ // item_total (slashes), 2 (for both open and close quotes), 1 (for terminating NULL).
state->status = f_memory_array_increase_by(item_total + 3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
if (F_status_is_error(state->status)) break;
}
else {
// TODO: combining joiner check against space.
+ // TODO: handle EOL just like above.
if (object.string[range->start] == f_fss_eol_s.string[0]) {
state->status = F_status_set_error(F_okay_eol);
flag_fl |= ___fl_flag_is_quoted___;
}
+ flag_fl |= ___fl_flag_save_character___;
+ }
+
+ if (flag_fl & ___fl_flag_save_character___) {
width = macro_f_utf_byte_width(object.string[range->start]);
+ if ((flag_fl & ___fl_flag_is_quoted___) && item_total) {
+ item_total *= 2;
+ }
+
+ // item_total (slashes), width (current character), 2 (for both open and close quotes), 1 (for terminating NULL).
state->status = f_memory_array_increase_by(item_total + width + 3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
if (F_status_is_error(state->status)) break;
- // There is nothing to delimit, so all slashes should be printed as is.
- for (i = 0; i < item_total; ++i) {
- destination->string[destination->used++] = f_fss_slash_s.string[0];
- } // for
+ if (item_total) {
+ memset(destination->string + destination->used, f_fss_slash_s.string[0], item_total);
+
+ destination->used += item_total;
+ }
+
+ if (flag_fl & ___fl_flag_save_quote___) {
+ destination->string[destination->used++] = quote_char;
+ }
memcpy(destination->string + destination->used, object.string + range->start, width);
destination->used += width;
item_total = 0;
+ flag_fl &= ~___fl_flag_save_quote_character___;
}
- flag_fl &= ~___fl_flag_do_handle___;
+ flag_fl &= ~___fl_flag_save_normal___;
}
else if (object.string[range->start] == quote_char) {
// TODO: Verify no combining joiners following.
}
else {
if (object.string[range->start] == f_fss_eol_s.string[0]) {
+ // TODO: same as above EOL cases.
state->status = F_status_set_error(F_okay_eol);
break;
destination->used += width;
- flag_fl &= ~___fl_flag_do_handle___;
+ flag_fl &= ~___fl_flag_save_normal___;
}
else if (object.string[range->start] == f_fss_eol_s.string[0]) {
state->status = F_status_set_error(F_okay_eol);
if (F_status_is_error(state->status)) break;
}
}
- else if ((flag_fl & ___fl_flag_do_handle___) && object.string[range->start] != f_fss_placeholder_s.string[0]) {
+ else if ((flag_fl & ___fl_flag_save_normal___) && object.string[range->start] != f_fss_placeholder_s.string[0]) {
if (!(flag_fl & ___fl_flag_is_quoted___)) {
if (object.string[range->start] == f_string_ascii_quote_double_s.string[0] || object.string[range->start] == f_string_ascii_quote_single_s.string[0] || object.string[range->start] == f_string_ascii_grave_s.string[0]) {
// TODO: Verify no combining joiners following.
if (F_status_is_error(state->status)) break;
} // for
- if (F_status_is_error_not(state->status) && (flag_fl & ___fl_flag_save_partial___)) {
- if (range->start > range->stop || range->start >= object.used) {
- if (partial.start <= partial.stop) {
- state->status = f_memory_array_increase_by((partial.stop - partial.start) + 4, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
+ if (F_status_is_error_not(state->status)) {
+ if (flag_fl & ___fl_flag_save_partial___) {
+ if (range->start > range->stop || range->start >= object.used) {
+ if (partial.start <= partial.stop) {
+ state->status = f_memory_array_increase_by((partial.stop - partial.start) + 4, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
- if (F_status_is_error_not(state->status)) {
- flag_fl |= ___fl_flag_has_increased___;
+ if (F_status_is_error_not(state->status)) {
+ flag_fl |= ___fl_flag_has_increased___;
- state->status = f_string_dynamic_partial_append_nulless(object, partial, destination);
+ state->status = f_string_dynamic_partial_append_nulless(object, partial, destination);
+ }
+ }
+ }
+ }
+ else if (flag_fl & ___fl_flag_save_slash___) {
+
+ // item_total (slashes), width (current character), 2 (for both open and close quotes or one for comment), 1 (for terminating NULL).
+ state->status = f_memory_array_increase_by(item_total + 3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size);
+
+ if (F_status_is_error_not(state->status)) {
+ if (item_total) {
+ memset(destination->string + destination->used, f_fss_slash_s.string[0], item_total);
+
+ destination->used += item_total;
+ }
+
+ if (flag_fl & ___fl_flag_save_quote___) {
+ destination->string[destination->used++] = quote_char;
+ }
+ else if (flag_fl & ___fl_flag_save_comment___) {
+ destination->string[destination->used++] = f_fss_comment_s.string[0];
}
}
}
} // for
// Only when followed by a space must the start quote be delimited.
+ // TODO: is this logic now redundant/irrelevant?
if (i <= range->stop && i < object.used) {
f_range_t range_i = *range;
range_i.start = i;
if (f_fss_is_space(object, range_i, state) == F_false) { // TODO: Verify no combining joiners following.
- if (F_status_is_error(state->status)) {
- destination->used = used_start;
-
- return;
- }
-
destination->string[used_start + 1] = f_fss_placeholder_s.string[0];
}
- else {
- if (object.string[i] == f_fss_eol_s.string[0]) {
- destination->used = used_start;
+ else if (object.string[i] == f_fss_eol_s.string[0]) {
+ state->status = F_status_set_error(F_okay_eol);
+ }
- state->status = F_status_set_error(F_okay_eol);
+ if (F_status_is_error(state->status)) {
+ destination->used = used_start;
- return;
- }
+ return;
}
}
}
}
- else if (commented) {
+ else if (flag_fl & ___fl_flag_is_commented___) {
destination->string[used_start] = f_fss_slash_s.string[0];
}
#undef ___fl_flag_as_object___
- #undef ___fl_flag_do_handle___
#undef ___fl_flag_has_combining___
#undef ___fl_flag_has_combining_joiner___
#undef ___fl_flag_has_increased___
#undef ___fl_flag_has_joiner___
#undef ___fl_flag_is_quoted___
#undef ___fl_flag_is_commented___
+ #undef ___fl_flag_save_character___
+ #undef ___fl_flag_save_comment___
+ #undef ___fl_flag_save_normal___
#undef ___fl_flag_save_partial___
+ #undef ___fl_flag_save_quote___
+ #undef ___fl_flag_save_quote_character___
+ #undef ___fl_flag_save_slash___
}
#endif // !defined(_di_fl_fss_basic_content_read_) || !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_read_) || !defined(_di_fl_fss_extended_content_write_) || !defined(_di_fl_fss_payload_header_map_)