From 2dbd61b6cac15929d1286aae127b5306c7f2648a Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 22 Jun 2020 21:25:27 -0500 Subject: [PATCH] Bugfix: iki didn't handle all cases I forgot to review the delimit cases and when I did I found the implementation a bit sloppy. I also found some ways to improve the code. The content slash total should start at 0 and not 1 because it increments it later on. The fl_ik_read() needs to check the range. --- level_0/f_iki/c/iki-common.h | 34 +++++------- level_0/f_iki/c/iki.c | 129 +++++++++++++++++++++---------------------- level_1/fl_iki/c/iki.c | 4 +- 3 files changed, 80 insertions(+), 87 deletions(-) diff --git a/level_0/f_iki/c/iki-common.h b/level_0/f_iki/c/iki-common.h index 67000ff..fc65b61 100644 --- a/level_0/f_iki/c/iki-common.h +++ b/level_0/f_iki/c/iki-common.h @@ -256,39 +256,33 @@ extern "C" { width_max = buffer->used - range->start; \ } #endif // _di_f_macro_iki_determine_width_max_ + /** - * Seek until whitespace is found. + * Seek until whitespace is found or not found. * - * status: The return status to use. - * buffer: (A pointer) The buffer to seek through. - * range: (A pointer) The range within that buffer to seek through. + * This will ignore the delimit placeholder. + * + * status: The return status to use. + * buffer: (A pointer) The buffer to seek through. + * range: (A pointer) The range within that buffer to seek through. + * condition: Set to TRUE to seek until whitespace is found and FALSE to seek until non-whitespace. */ #ifndef _di_f_macro_iki_seek_whitespace_ - #define f_macro_iki_seek_whitespace(status, buffer, range, width_max) \ + #define f_macro_iki_seek_whitespace(status, buffer, range, width_max, condition) \ while (range->start <= range->stop && range->start < buffer->used) { \ + if (buffer->string[range->start] == f_iki_syntax_placeholder) { \ + range->start++; \ + continue; \ + } \ f_macro_iki_determine_width_max(buffer, range, width_max); \ status = f_utf_is_whitespace(buffer->string + range->start, width_max); \ - if (status == F_true) break; \ + if (status == condition) break; \ else if (F_status_is_error(status)) break; \ status = f_utf_buffer_increment(*buffer, range, 1); \ if (F_status_is_error(status)) break; \ } #endif // _di_f_macro_iki_seek_whitespace_ -/** - * Skip past all delimit placeholders. - * - * status: The return status to use. - * buffer: (A pointer) The buffer to skip through. - * range: (A pointer) The range within that buffer to skip through. - */ -#ifndef _di_f_macro_iki_skip_past_delimit_placeholders_ - #define f_macro_iki_skip_past_delimit_placeholders(status, buffer, range) \ - do { \ - status = f_utf_buffer_increment(*buffer, range, 1); \ - } while (F_status_is_fine(status) && buffer->string[range->start] == f_iki_syntax_placeholder); -#endif // _di_f_macro_iki_skip_past_delimit_placeholders_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_iki/c/iki.c b/level_0/f_iki/c/iki.c index 0c5c766..1533031 100644 --- a/level_0/f_iki/c/iki.c +++ b/level_0/f_iki/c/iki.c @@ -27,17 +27,22 @@ extern "C" { // skip past all initial non-word, non-dash, and non-plus. while (range->start <= range->stop && range->start < buffer->used) { + if (buffer->string[range->start] == f_iki_syntax_placeholder) { + range->start++; + continue; + } + + f_macro_iki_determine_width_max(buffer, range, width_max); - if (buffer->string[range->start] != f_iki_syntax_placeholder) { - f_macro_iki_determine_width_max(buffer, range, width_max); + status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max); + if (F_status_is_error(status)) return status; - status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max); - if (F_status_is_error(status)) return status; + if (status == F_true) break; - if (status == F_true) break; - } + f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_true); + if (F_status_is_error(status)) return status; - status = f_utf_buffer_increment(*buffer, range, 1); + f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_false); if (F_status_is_error(status)) return status; } // while @@ -58,6 +63,7 @@ extern "C" { uint8_t quote = 0; bool vocabulary_delimited = F_false; + bool find_next = F_false; // delimits must only be applied once a valid object is found. f_string_lengths delimits = f_string_lengths_initialize; @@ -84,7 +90,10 @@ extern "C" { vocabulary_delimited = F_false; found_vocabulary.stop = range->start - 1; - f_macro_iki_skip_past_delimit_placeholders(status, buffer, range); + do { + status = f_utf_buffer_increment(*buffer, range, 1); + } while (F_status_is_fine(status) && buffer->string[range->start] == f_iki_syntax_placeholder); + if (F_status_is_error(status)) { f_macro_string_lengths_delete(status, delimits); return status; @@ -98,7 +107,7 @@ extern "C" { } // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass. - f_macro_iki_seek_whitespace(status, buffer, range, width_max); + f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_true); if (F_status_is_error(status)) { f_macro_string_lengths_delete(status, delimits); return status; @@ -113,6 +122,7 @@ extern "C" { // the slash only needs to be delimited if it were to otherwise be a valid vocabulary name. while (range->start <= range->stop && range->start < buffer->used) { + if (buffer->string[range->start] == f_iki_syntax_placeholder) { range->start++; continue; @@ -127,31 +137,15 @@ extern "C" { break; } else { - range->start = vocabulary_slash_first; - - // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass. - f_macro_iki_seek_whitespace(status, buffer, range, width_max); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete(status, delimits); - return status; - } - + find_next = F_true; break; } } else if (buffer->string[range->start] == f_iki_syntax_separator) { separator_found = F_true; } - else { - range->start = vocabulary_slash_first; - - // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass. - f_macro_iki_seek_whitespace(status, buffer, range, width_max); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete(status, delimits); - return status; - } - + else if (buffer->string[range->start] != f_iki_syntax_slash) { + find_next = F_true; break; } @@ -161,6 +155,8 @@ extern "C" { return status; } } // while + + break; } else { f_macro_iki_determine_width_max(buffer, range, width_max); @@ -178,6 +174,7 @@ extern "C" { return status; } + find_next = F_true; break; } } @@ -200,6 +197,7 @@ extern "C" { } if (buffer->string[range->start] == quote) { + // this is a valid vocabulary name and content, but if it is delimited, save the delimit and ignore. if (vocabulary_delimited) { f_macro_iki_allocate_delimits_if_necessary(status, delimits); @@ -211,36 +209,12 @@ extern "C" { delimits.array[delimits.used] = vocabulary_slash_first; delimits.used++; + find_next = F_true; vocabulary_delimited = F_false; quote = 0; range->start++; - - // skip past all initial non-word, non-dash, and non-plus. - while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_iki_syntax_placeholder) { - range->start++; - continue; - } - - f_macro_iki_determine_width_max(buffer, range, width_max); - - status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete(status, delimits); - return status; - } - - if (status == F_true) break; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete(status, delimits); - return status; - } - } // while - - found_vocabulary.start = range->start; + break; } else { f_macro_iki_allocate_ranges_if_necessary(status, (*variable)); @@ -292,7 +266,7 @@ extern "C" { } else if (buffer->string[range->start] == f_iki_syntax_slash) { f_string_length content_slash_first = range->start; - f_array_length content_slash_total = 1; + f_array_length content_slash_total = 0; while (range->start <= range->stop && range->start < buffer->used) { if (buffer->string[range->start] == f_iki_syntax_placeholder) { @@ -387,18 +361,25 @@ extern "C" { found_vocabulary.start = range->start; } else { - f_macro_iki_allocate_ranges_if_necessary(status, (*vocabulary)); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete(status, delimits); - return status; + f_macro_iki_allocate_ranges_if_necessary(status, (*variable)); + + if (F_status_is_fine(status)) { + f_macro_iki_allocate_ranges_if_necessary(status, (*vocabulary)); + } + + if (F_status_is_fine(status)) { + f_macro_iki_allocate_ranges_if_necessary(status, (*content)); } - f_macro_iki_allocate_ranges_if_necessary(status, (*content)); if (F_status_is_error(status)) { f_macro_string_lengths_delete(status, delimits); return status; } + variable->array[variable->used].start = found_vocabulary.start; + variable->array[variable->used].stop = range->start; + variable->used++; + vocabulary->array[vocabulary->used].start = found_vocabulary.start; vocabulary->array[vocabulary->used].stop = found_vocabulary.stop; vocabulary->used++; @@ -431,7 +412,6 @@ extern "C" { break; } else if (buffer->string[range->start] != f_iki_syntax_slash) { - range->start++; break; } @@ -453,13 +433,31 @@ extern "C" { } // while } else { + + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete(status, delimits); + return status; + } + vocabulary_delimited = F_false; + find_next = F_true; + } + + if (find_next) { - // skip past all initial non-word, non-dash, and non-plus. while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_iki_syntax_placeholder) { - range->start++; - continue; + + f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_true); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete(status, delimits); + return status; + } + + f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_false); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete(status, delimits); + return status; } f_macro_iki_determine_width_max(buffer, range, width_max); @@ -480,6 +478,7 @@ extern "C" { } // while found_vocabulary.start = range->start; + find_next = F_false; } } while (range->start <= range->stop && range->start < buffer->used); diff --git a/level_1/fl_iki/c/iki.c b/level_1/fl_iki/c/iki.c index c9c4ea4..506acf8 100644 --- a/level_1/fl_iki/c/iki.c +++ b/level_1/fl_iki/c/iki.c @@ -8,7 +8,7 @@ extern "C" { f_return_status fl_iki_read(f_string_static *buffer, f_string_range *range, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content) { f_status status = F_none; - for (;;) { + do { status = f_iki_read(buffer, range, variable, vocabulary, content); if (F_status_is_error(status)) return status; @@ -19,7 +19,7 @@ extern "C" { if (status == F_none_eos || status == F_none_stop) { return status; } - } // for + } while (range->start <= range->stop && range->start < buffer->used); return F_none; } -- 1.8.3.1