From: Kevin Day Date: Sun, 17 Nov 2024 23:22:29 +0000 (-0600) Subject: Feature: Implement EKI at level_0. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=60d4e0c667860574659e9a7966ac0c591054f61a;p=fll Feature: Implement EKI at level_0. This provides the initial eki implementation and unit testing. I had to choose between making an f_eki compliment of f_iki or appending EKI into f_iki. I ended up choosing the latter because it is simpler and will require fewer cross-dependencies when using higher levels. There is enough overlap in functionality to justify this. These are almost completely identical specifications. Add additional unit tests to catch more problems and implement these same unit tests in f_iki for consistency purposes. This includes some code clean up. The `wrapped` is changed to use `0x0` and `0x1` rather than `F_false` and `F_true`. These are functionally identical but the code is more consistent when having `0x0`, `0x1`, and `0x2` instead of `F_false`, `F_true`, and `0x2`. --- diff --git a/build/level_0/settings b/build/level_0/settings index 5dc2c86..d68f489 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -51,7 +51,7 @@ build_sources_library environment.c build_sources_library execute.c build_sources_library file.c private-file.c file/common.c file/stream.c build_sources_library fss.c fss/common.c fss/item.c fss/named.c fss/nest.c fss/payload.c fss/quote.c fss/set.c fss/set_quote.c fss/simple_packet.c -build_sources_library iki.c iki/common.c iki/data.c private-iki.c iki/private-data.c +build_sources_library iki.c iki/common.c iki/data.c iki/eki.c private-iki.c iki/private-data.c iki/private-eki.c build_sources_library limit.c limit/set.c limit/value.c build_sources_library memory.c memory/array.c memory/arrays.c build_sources_library private-memory.c memory/private-array.c @@ -100,7 +100,7 @@ build_sources_headers environment.h environment/common.h build_sources_headers execute.h execute/common.h build_sources_headers file.h file/common.h file/stream.h build_sources_headers fss.h fss/common.h fss/item.h fss/named.h fss/nest.h fss/payload.h fss/quote.h fss/set.h fss/set_quote.h fss/simple_packet.h -build_sources_headers iki.h iki/common.h iki/data.h +build_sources_headers iki.h iki/common.h iki/data.h iki/eki.h build_sources_headers limit.h limit/set.h limit/value.h build_sources_headers memory.h memory/array.h memory/arrays.h memory/common.h build_sources_headers network.h network/common.h diff --git a/build/monolithic/settings b/build/monolithic/settings index 396ea17..50e9763 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -51,7 +51,7 @@ build_sources_library level_0/environment.c build_sources_library level_0/execute.c build_sources_library level_0/file.c level_0/private-file.c level_0/file/common.c level_0/file/stream.c build_sources_library level_0/fss.c level_0/fss/common.c level_0/fss/item.c level_0/fss/named.c level_0/fss/nest.c level_0/fss/payload.c level_0/fss/quote.c level_0/fss/set.c level_0/fss/set_quote.c level_0/fss/simple_packet.c -build_sources_library level_0/iki.c level_0/iki/common.c level_0/iki/data.c level_0/private-iki.c level_0/iki/private-data.c +build_sources_library level_0/iki.c level_0/iki/common.c level_0/iki/data.c level_0/iki/eki.c level_0/private-iki.c level_0/iki/private-data.c level_0/iki/private-eki.c build_sources_library level_0/limit.c level_0/limit/set.c level_0/limit/value.c build_sources_library level_0/memory.c level_0/memory/array.c level_0/memory/arrays.c build_sources_library level_0/private-memory.c level_0/memory/private-array.c @@ -121,7 +121,7 @@ build_sources_headers level_0/environment.h level_0/environment/common.h build_sources_headers level_0/execute.h level_0/execute/common.h build_sources_headers level_0/file.h level_0/file/common.h level_0/file/stream.h build_sources_headers level_0/fss.h level_0/fss/common.h level_0/fss/item.h level_0/fss/named.h level_0/fss/nest.h level_0/fss/payload.h level_0/fss/quote.h level_0/fss/set.h level_0/fss/set_quote.h level_0/fss/simple_packet.h -build_sources_headers level_0/iki.h level_0/iki/common.h level_0/iki/data.h +build_sources_headers level_0/iki.h level_0/iki/common.h level_0/iki/data.h level_0/iki/eki.h build_sources_headers level_0/limit.h level_0/limit/set.h level_0/limit/value.h build_sources_headers level_0/memory.h level_0/memory/array.h level_0/memory/arrays.h level_0/memory/common.h build_sources_headers level_0/network.h level_0/network/common.h diff --git a/level_0/f_iki/c/iki.c b/level_0/f_iki/c/iki.c index db637ba..54ab886 100644 --- a/level_0/f_iki/c/iki.c +++ b/level_0/f_iki/c/iki.c @@ -33,6 +33,611 @@ extern "C" { } #endif // _di_f_iki_content_partial_is_ +#ifndef _di_f_iki_eki_read_ + void f_iki_eki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_eki_t * const data, f_state_t * const state) { + #ifndef _di_level_0_parameter_checking_ + if (!state) return; + + if (!buffer || !range || !data) { + state->status = F_status_set_error(F_parameter); + + return; + } + #endif // _di_level_0_parameter_checking_ + + if (!buffer->used) { + state->status = F_data_not; + + return; + } + + if (range->start > range->stop) { + state->status = F_data_not_stop; + + return; + } + + if (range->start >= buffer->used) { + state->status = F_data_not_eos; + + return; + } + + f_number_unsigned_t width_max = 0; + + if (width_max > buffer->used - range->start) { + width_max = buffer->used - range->start; + } + + f_range_t content_range = f_range_t_initialize; + f_range_t found_vocabulary = f_range_t_initialize; + f_number_unsigned_t i = 0; + f_number_unsigned_t content_slash_delimits = 0; + f_number_unsigned_t content_slash_first = 0; + f_number_unsigned_t content_slash_total = 0; + f_number_unsigned_t found_content = 0; + f_number_unsigned_t vocabulary_count = 0; + f_number_unsigned_t vocabulary_slash_first = 0; + const f_number_unsigned_t delimits_used = data->delimits.used; + + uint8_t mode = 0x0; // 0x0 = nothing, 0x1 = separator found, 0x2 = possible multiple vocabulary names, 0x4 = completed multiple vocabulary names. + uint8_t quote = 0; + uint8_t wrapped = 0x0; // 0x0 = not wrapped, 0x1 = wrapped, 0x2 = valid wrapped. + + do { + + // Find the start of the vocabulary name. + while (range->start <= range->stop && range->start < buffer->used) { + + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + width_max = buffer->used - range->start; + + state->status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max, F_false); + + if (F_status_is_error(state->status)) { + if (F_status_set_fine(state->status) == F_utf_fragment || F_status_set_fine(state->status) == F_complete_not_utf) { + if (state->flag & f_iki_state_flag_utf_fail_on_valid_not_e) break; + + state->status = F_false; + } + else { + break; + } + } + + if (state->status == F_true) { + if (!wrapped) { + found_vocabulary.start = range->start; + found_vocabulary.stop = range->start; + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + + state->status = F_true; + + break; + } + + // Wrapped must be followed by a valid vocabulary name. + if (buffer->string[range->start] == f_iki_syntax_wrap_open_s.string[0]) { + found_vocabulary.start = range->start; + found_vocabulary.stop = range->start; + + wrapped = 0x1; + } + else if (wrapped) { + wrapped = 0x0; + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + } // while + + // Find the end of the vocabulary name. + while (F_status_is_error_not(state->status) && range->start <= range->stop && range->start < buffer->used) { + + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { + ++range->start; + + continue; + } + + if (buffer->string[range->start] == f_iki_syntax_separator_s.string[0]) { + do { + state->status = f_utf_buffer_increment(*buffer, range, 1); + } while (F_status_is_error_not(state->status) && range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]); + + if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used) break; + + // Found a valid vocabulary name. + if (buffer->string[range->start] == f_iki_syntax_quote_single_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_double_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_grave_s.string[0]) { + state->status = F_true; + quote = buffer->string[range->start]; + vocabulary_count = 1; + } + else { + mode &= ~0x6; + vocabulary_count = 0; + + do { + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { + ++range->start; + + continue; + } + + if (buffer->string[range->start] == f_iki_syntax_quote_single_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_double_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_grave_s.string[0]) { + if ((mode & 0x6) && (!wrapped || wrapped == 0x2)) { + if (mode & 0x4) { + mode &= ~0x2; + } + else { + mode |= 0x4; + } + + state->status = F_true; + quote = buffer->string[range->start]; + ++vocabulary_count; + } + else { + state->status = F_next; + mode &= ~0x6; + } + + break; + } + + if (buffer->string[range->start] == f_iki_syntax_slash_s.string[0]) { + mode &= ~0x1; + vocabulary_slash_first = range->start; + + // 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 (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { + ++range->start; + + continue; + } + + if (mode & 0x1) { + + // Save delimit for a would-be valid IKI that is now delimited. + if (buffer->string[range->start] == f_iki_syntax_quote_single_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_double_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_grave_s.string[0]) { + state->status = f_memory_array_increase(state->step_small, sizeof(f_number_unsigned_t), (void **) &data->delimits.array, &data->delimits.used, &data->delimits.size); + if (F_status_is_error(state->status)) break; + + data->delimits.array[data->delimits.used++] = vocabulary_slash_first; + + ++range->start; + } + + state->status = F_next; + + break; + } + + if (buffer->string[range->start] == f_iki_syntax_separator_s.string[0]) { + mode |= 0x1; + } + else if (buffer->string[range->start] != f_iki_syntax_slash_s.string[0]) { + state->status = F_next; + + break; + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + } // while + + if (state->status == F_true) break; + if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used || state->status == F_next) break; + } + else if (buffer->string[range->start] == f_iki_syntax_separator_s.string[0]) { + if (!(mode & 0x2)) { + mode &= ~0x6; + + break; + } + + ++range->start; + ++vocabulary_count; + mode &= ~0x2; + mode |= 0x4; + + continue; + } + else if (buffer->string[range->start] == f_iki_syntax_wrap_close_s.string[0]) { + if (wrapped == 0x1) { + wrapped = 0x2; + found_vocabulary.stop = range->start; + } + else { + state->status = F_next; + mode &= ~0x6; + + break; + } + } + else { + width_max = buffer->used - range->start; + + state->status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max, F_false); + + if (F_status_is_error_not(state->status)) { + if (state->status != F_true) { + state->status = F_next; + + break; + } + } + + if (state->status == F_true) { + mode |= 0x2; + found_vocabulary.stop = range->start; + } + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + + } while (F_status_is_error_not(state->status) && range->start <= range->stop && range->start < buffer->used); + } + + break; + } + + if (buffer->string[range->start] == f_iki_syntax_slash_s.string[0]) { + mode &= ~0x1; + vocabulary_slash_first = range->start; + + // 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 (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { + ++range->start; + + continue; + } + + if (mode & 0x1) { + + // Save delimit for a would-be valid IKI that is now delimited. + if (buffer->string[range->start] == f_iki_syntax_quote_single_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_double_s.string[0] || buffer->string[range->start] == f_iki_syntax_quote_grave_s.string[0]) { + state->status = f_memory_array_increase(state->step_small, sizeof(f_number_unsigned_t), (void **) &data->delimits.array, &data->delimits.used, &data->delimits.size); + if (F_status_is_error(state->status)) break; + + data->delimits.array[data->delimits.used++] = vocabulary_slash_first; + + ++range->start; + } + + state->status = F_next; + + break; + } + + if (buffer->string[range->start] == f_iki_syntax_separator_s.string[0]) { + mode |= 0x1; + } + else if (buffer->string[range->start] != f_iki_syntax_slash_s.string[0]) { + state->status = F_next; + + break; + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + } // while + + if (state->status == F_true) break; + if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used || state->status == F_next) break; + } + else if (buffer->string[range->start] == f_iki_syntax_wrap_open_s.string[0]) { + state->status = F_next; + + break; + } + else if (wrapped == 0x1 && buffer->string[range->start] == f_iki_syntax_wrap_close_s.string[0]) { + wrapped = 0x2; + found_vocabulary.stop = range->start; + } + else if (wrapped == 0x2) { + + // Wrapped close must be immediately before a separator (ignoring any placeholders in between). + state->status = F_next; + + break; + } + else { + width_max = buffer->used - range->start; + + state->status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max, F_false); + + if (F_status_is_error(state->status)) { + if (F_status_set_fine(state->status) == F_utf_fragment || F_status_set_fine(state->status) == F_complete_not_utf) { + if (state->flag & f_iki_state_flag_utf_fail_on_valid_not_e) break; + + state->status = F_false; + } + else { + break; + } + } + + if (state->status == F_true) { + found_vocabulary.stop = range->start; + } + else { + + // Not a valid IKI vocabulary name. + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + + state->status = F_next; + + break; + } + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + } // while + + if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used) break; + + if (state->status == F_next) { + quote = 0; + wrapped = 0x0; + + continue; + } + + // Process potentially valid content. + if (quote) { + found_content = ++range->start; + + while (range->start <= range->stop && range->start < buffer->used) { + + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { + ++range->start; + + continue; + } + + if (buffer->string[range->start] == quote) { + state->status = f_memory_array_increase(state->step_small, sizeof(f_range_t), (void **) &data->variable.array, &data->variable.used, &data->variable.size); + if (F_status_is_error(state->status)) break; + + state->status = f_memory_array_increase(state->step_small, sizeof(f_ranges_t), (void **) &data->vocabularys.array, &data->vocabularys.used, &data->vocabularys.size); + if (F_status_is_error(state->status)) break; + + state->status = f_memory_array_increase_by(vocabulary_count, sizeof(f_range_t), (void **) &data->vocabularys.array[data->vocabularys.used].array, &data->vocabularys.array[data->vocabularys.used].used, &data->vocabularys.array[data->vocabularys.used].size); + if (F_status_is_error(state->status)) break; + + state->status = f_memory_array_increase(state->step_small, sizeof(f_range_t), (void **) &data->content.array, &data->content.used, &data->content.size); + if (F_status_is_error(state->status)) break; + + data->variable.array[data->variable.used].start = found_vocabulary.start; + data->variable.array[data->variable.used++].stop = range->start; + + i = wrapped ? found_vocabulary.start + f_iki_syntax_wrap_open_s.used : found_vocabulary.start; + + for (data->vocabularys.array[data->vocabularys.used].used = 0; data->vocabularys.array[data->vocabularys.used].used < vocabulary_count; ) { + + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + data->vocabularys.array[data->vocabularys.used].array[data->vocabularys.array[data->vocabularys.used].used].start = i; + + while (i <= found_vocabulary.stop && buffer->string[i] != f_iki_syntax_separator_s.string[0] && buffer->string[i] != f_iki_syntax_wrap_close_s.string[0]) ++i; + + data->vocabularys.array[data->vocabularys.used].array[data->vocabularys.array[data->vocabularys.used].used++].stop = (buffer->string[i] == f_iki_syntax_separator_s.string[0] || buffer->string[i] == f_iki_syntax_wrap_close_s.string[0]) ? i - 1 : i; + + if (i <= found_vocabulary.stop && buffer->string[i] == f_iki_syntax_separator_s.string[0]) { + if (i == found_vocabulary.stop) break; + + ++i; + } + } // for + + ++data->vocabularys.used; + + data->content.array[data->content.used].start = found_content; + data->content.array[data->content.used++].stop = range->start - 1; + + if (++range->start > range->stop) { + state->status = F_okay_stop; + } + else if (range->start >= buffer->used) { + state->status = F_okay_eos; + } + else { + state->status = F_okay; + } + + return; + } + + if (buffer->string[range->start] == f_iki_syntax_slash_s.string[0]) { + content_slash_first = range->start; + content_slash_total = 0; + + while (range->start <= range->stop && range->start < buffer->used) { + + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { + ++range->start; + + continue; + } + + if (buffer->string[range->start] == quote) { + content_slash_delimits = content_slash_total / 2; + content_range.start = 1; + content_range.stop = 0; + + if (content_slash_total % 2) { + ++content_slash_delimits; + } + + state->status = f_memory_array_increase_by(content_slash_delimits, sizeof(f_number_unsigned_t), (void **) &data->delimits.array, &data->delimits.used, &data->delimits.size); + if (F_status_is_error(state->status)) break; + + content_range.start = content_slash_first; + content_range.stop = range->stop; + + for (i = 0; i < content_slash_delimits; ) { + + if (buffer->string[content_range.start] == f_iki_syntax_slash_s.string[0]) { + data->delimits.array[data->delimits.used++] = content_range.start; + ++i; + } + + state->status = f_utf_buffer_increment(*buffer, (&content_range), 1); + if (F_status_is_error(state->status)) break; + } // for + + if (F_status_is_error(state->status)) break; + + // Valid content's ending quote is not delimited, save and return. + if (content_slash_total % 2 == 0) { + state->status = f_memory_array_increase(state->step_small, sizeof(f_range_t), (void **) &data->variable.array, &data->variable.used, &data->variable.size); + if (F_status_is_error(state->status)) break; + + state->status = f_memory_array_increase(state->step_small, sizeof(f_ranges_t), (void **) &data->vocabularys.array, &data->vocabularys.used, &data->vocabularys.size); + if (F_status_is_error(state->status)) break; + + state->status = f_memory_array_increase(vocabulary_count, sizeof(f_range_t), (void **) &data->vocabularys.array[data->vocabularys.used].array, &data->vocabularys.array[data->vocabularys.used].used, &data->vocabularys.array[data->vocabularys.used].size); + if (F_status_is_error(state->status)) break; + + state->status = f_memory_array_increase(state->step_small, sizeof(f_range_t), (void **) &data->content.array, &data->content.used, &data->content.size); + if (F_status_is_error(state->status)) break; + + data->variable.array[data->variable.used].start = found_vocabulary.start; + data->variable.array[data->variable.used++].stop = range->start; + + i = wrapped ? found_vocabulary.start + f_iki_syntax_wrap_open_s.used : found_vocabulary.start; + + for (data->vocabularys.array[data->vocabularys.used].used = 0; data->vocabularys.array[data->vocabularys.used].used < vocabulary_count; ) { + + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + + data->vocabularys.array[data->vocabularys.used].array[data->vocabularys.array[data->vocabularys.used].used].start = i; + + while (i <= found_vocabulary.stop && buffer->string[i] != f_iki_syntax_separator_s.string[0] && buffer->string[i] != f_iki_syntax_wrap_close_s.string[0]) ++i; + + data->vocabularys.array[data->vocabularys.used].array[data->vocabularys.array[data->vocabularys.used].used++].stop = (buffer->string[i] == f_iki_syntax_separator_s.string[0] || buffer->string[i] == f_iki_syntax_wrap_close_s.string[0]) ? i - 1 : i; + + if (i <= found_vocabulary.stop && buffer->string[i] == f_iki_syntax_separator_s.string[0]) { + if (i == found_vocabulary.stop) break; + + ++i; + } + } // for + + ++data->vocabularys.used; + + data->content.array[data->content.used].start = found_content; + data->content.array[data->content.used++].stop = range->start - 1; + + if (++range->start > range->stop) { + state->status = F_okay_stop; + } + else if (range->start >= buffer->used) { + state->status = F_okay_eos; + } + else { + state->status = F_okay; + } + + return; + } + + break; + } + + if (buffer->string[range->start] != f_iki_syntax_slash_s.string[0]) break; + + ++content_slash_total; + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + } // while + + if (F_status_is_error(state->status)) break; + } + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + } // while + + quote = 0; + wrapped = 0x0; + } + + if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used) break; + + state->status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(state->status)) break; + + } while (range->start <= range->stop && range->start < buffer->used); + + if (F_status_set_fine(state->status) == F_complete_not_utf_eos || F_status_set_fine(state->status) == F_complete_not_utf_stop) { + if (!(state->flag & f_iki_state_flag_utf_fail_on_valid_not_e)) { + state->status = F_status_set_fine(state->status); + } + } + + if (F_status_is_error(state->status)) { + data->delimits.used = delimits_used; + + return; + } + + state->status = (range->start > range->stop) ? F_data_not_stop : F_data_not_eos; + } +#endif // _di_f_iki_eki_read_ + #ifndef _di_f_iki_object_is_ f_status_t f_iki_object_is(const f_string_static_t object) { @@ -89,13 +694,20 @@ extern "C" { width_max = buffer->used - range->start; } + f_range_t content_range = f_range_t_initialize; f_range_t found_vocabulary = f_range_t_initialize; + f_number_unsigned_t i = 0; + f_number_unsigned_t content_slash_delimits = 0; + f_number_unsigned_t content_slash_first = 0; + f_number_unsigned_t content_slash_total = 0; f_number_unsigned_t found_content = 0; f_number_unsigned_t vocabulary_slash_first = 0; const f_number_unsigned_t delimits_used = data->delimits.used; + uint8_t quote = 0; - uint8_t wrapped = F_false; // 0x0 (false) = not wapped, 0x1 (true) = wrapped, 0x2 = valid wrapped. + uint8_t separator_found = F_false; + uint8_t wrapped = 0x0; // 0x0 (false) = not wrapped, 0x1 (true) = wrapped, 0x2 = valid wrapped. do { @@ -141,10 +753,10 @@ extern "C" { found_vocabulary.start = range->start; found_vocabulary.stop = range->start; - wrapped = F_true; + wrapped = 0x1; } else if (wrapped) { - wrapped = F_false; + wrapped = 0x0; } state->status = f_utf_buffer_increment(*buffer, range, 1); @@ -167,8 +779,8 @@ extern "C" { if (buffer->string[range->start] == f_iki_syntax_separator_s.string[0]) { - // Wrapped must close in a wrap close before the seperator. - if (wrapped == F_true) { + // Wrapped must close in a "wrap close" before the separator is matched. + if (wrapped == 0x1) { state->status = F_next; break; @@ -176,7 +788,7 @@ extern "C" { do { state->status = f_utf_buffer_increment(*buffer, range, 1); - } while (F_status_is_fine(state->status) && buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0] && range->start <= range->stop && range->start < buffer->used); + } while (F_status_is_error_not(state->status) && range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]); if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used) break; @@ -193,8 +805,7 @@ extern "C" { } if (buffer->string[range->start] == f_iki_syntax_slash_s.string[0]) { - bool separator_found = F_false; - + separator_found = F_false; vocabulary_slash_first = range->start; // The slash only needs to be delimited if it were to otherwise be a valid vocabulary name. @@ -249,7 +860,7 @@ extern "C" { break; } - else if (wrapped == F_true && buffer->string[range->start] == f_iki_syntax_wrap_close_s.string[0]) { + else if (wrapped == 0x1 && buffer->string[range->start] == f_iki_syntax_wrap_close_s.string[0]) { wrapped = 0x2; found_vocabulary.stop = range->start; } @@ -299,7 +910,7 @@ extern "C" { if (state->status == F_next) { quote = 0; - wrapped = F_false; + wrapped = 0x0; continue; } @@ -354,11 +965,16 @@ extern "C" { } if (buffer->string[range->start] == f_iki_syntax_slash_s.string[0]) { - f_number_unsigned_t content_slash_first = range->start; - f_number_unsigned_t content_slash_total = 0; + content_slash_first = range->start; + content_slash_total = 0; while (range->start <= range->stop && range->start < buffer->used) { + if (state->interrupt) { + state->interrupt((void * const) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) break; + } + if (buffer->string[range->start] == f_iki_syntax_placeholder_s.string[0]) { ++range->start; @@ -366,9 +982,9 @@ extern "C" { } if (buffer->string[range->start] == quote) { - f_number_unsigned_t content_slash_delimits = content_slash_total / 2; - f_range_t content_range = f_range_t_initialize; - f_number_unsigned_t i = 0; + content_slash_delimits = content_slash_total / 2; + content_range.start = 1; + content_range.stop = 0; if (content_slash_total % 2) { ++content_slash_delimits; @@ -380,7 +996,7 @@ extern "C" { content_range.start = content_slash_first; content_range.stop = range->stop; - while (i < content_slash_delimits) { + for (i = 0; i < content_slash_delimits; ) { if (buffer->string[content_range.start] == f_iki_syntax_slash_s.string[0]) { data->delimits.array[data->delimits.used++] = content_range.start; @@ -389,7 +1005,7 @@ extern "C" { state->status = f_utf_buffer_increment(*buffer, (&content_range), 1); if (F_status_is_error(state->status)) break; - } // while + } // for if (F_status_is_error(state->status)) break; @@ -445,7 +1061,7 @@ extern "C" { } // while quote = 0; - wrapped = F_false; + wrapped = 0x0; } if (F_status_is_error(state->status) || range->start > range->stop || range->start >= buffer->used) break; diff --git a/level_0/f_iki/c/iki.h b/level_0/f_iki/c/iki.h index a109ea2..09c6510 100644 --- a/level_0/f_iki/c/iki.h +++ b/level_0/f_iki/c/iki.h @@ -7,8 +7,11 @@ * * Provides a Wiki-Like syntax meant to be much simpler. * - * This simpler Wiki-Like syntax, called Iki, focuses just on simply adding context. + * This simpler Wiki-Like syntax, called IKI, focuses just on simply adding context. * The context itself is not explicitly defined but a few common standards are provided. + * + * This includes support for EKI format, which is just an extended form of IKI. + * Many of the IKI functions can be used for EKI, except for vocabulary related and anything directly operating with f_iki_eki_t related. */ #ifndef _F_iki_h #define _F_iki_h @@ -28,6 +31,7 @@ // FLL-0 iki includes. #include #include +#include #ifdef __cplusplus extern "C" { @@ -82,6 +86,60 @@ extern "C" { #endif // _di_f_iki_content_partial_is_ /** + * Read a single EKI Vocabulary and Content. + * + * This does not verify if the vocabulary name is known. + * This only finds a complete vocabulary name and content. + * + * This will increment the range after the end of any valud vocabulary and content set. + * + * This will update the buffer at the given range with any placeholders to escaped data. + * Calling this more than once on the same buffer range could result in multiple escaping. + * + * @param buffer + * The string to process. + * @param range + * The start/stop location within the buffer to be processed. + * The start location will be updated as the buffer is being processed. + * The start location will represent where the read stopped on return. + * A start location past the stop location or buffer used means that the entire range was processed. + * @param data + * The EKI variable data. + * @param state + * A state for providing flags and handling interrupts during long running operations. + * There is no state.handle(). + * There is no "callbacks" structure. + * There is no data structure passed to these functions. + * This must not be NULL. + * + * When state.interrupt() returns, only F_interrupt and F_interrupt_not are processed. + * Error bit designates an error but must be passed along with F_interrupt. + * All other statuses are ignored. + * + * This alters state.status: + * F_okay on success and an IKI vocabulary name was found. + * F_okay_eos on success and an IKI vocabulary name was found and end of string was reached. + * F_okay_stop on success and an IKI vocabulary name was found and stop point was reached. + * F_complete_not_utf_eos on success but string ended on incomplete UTF-8 and f_iki_state_flag_utf_fail_on_valid_not_e is not set. + * F_complete_not_utf_stop on success but stop point reached on incomplete UTF-8 and f_iki_state_flag_utf_fail_on_valid_not_e is not set. + * F_data_not on success, but there were no IKI vocabulary names found. + * F_data_not_eos on success and EOS was reached, but there were no IKI vocabulary names found. + * F_data_not_stop on success and stop point was reached, but there were no IKI vocabulary names found. + * + * F_complete_not_utf_eos (with error bit) on success but string ended on incomplete UTF-8 and f_iki_state_flag_utf_fail_on_valid_not_e is set. + * F_complete_not_utf_stop (with error bit) on success but stop point reached on incomplete UTF-8 and f_iki_state_flag_utf_fail_on_valid_not_e is set. + * F_interrupt (with error bit) if stopping due to an interrupt. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if a string length is too large to store in the buffer. + * + * @see f_memory_array_increase_by() + */ +#ifndef _di_f_iki_eki_read_ + extern void f_iki_eki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_eki_t * const data, f_state_t * const state); +#endif // _di_f_iki_eki_read_ + +/** * Determine if an object is a valid IKI object name. * * @param object @@ -124,7 +182,7 @@ extern "C" { #endif // _di_f_iki_object_partial_is_ /** - * Read a single iki Vocabulary and Content. + * Read a single IKI Vocabulary and Content. * * This does not verify if the vocabulary name is known. * This only finds a complete vocabulary name and content. diff --git a/level_0/f_iki/c/iki/common.h b/level_0/f_iki/c/iki/common.h index eee3076..92a2b4c 100644 --- a/level_0/f_iki/c/iki/common.h +++ b/level_0/f_iki/c/iki/common.h @@ -192,7 +192,7 @@ extern "C" { #endif // _di_f_iki_vocabulary_0002_s_ /** - * This containg all of the IKI data. + * This containing all of the IKI data. * * Properties: * - content: A set of ranges representing the content (variable value) list to store the content associated with the found vocabulary name. @@ -268,6 +268,83 @@ extern "C" { #define macro_f_iki_datass_t_initialize_2(array, length) { array, length, length } #endif // _di_f_iki_datass_t_ +/** + * This containing all of the EKI data (extended IKI data). + * + * Properties: + * - content: A set of ranges representing the content (variable value) list to store the content associated with the found vocabulary name. + * - delimits: A delimits array representing where delimits exist within the buffer. + * - variable: A set of ranges representing the entire vocabulary (variable name), content, and the syntax. + * - vocabularys: A set of ranges representing the vocabularies (variable names) list to store each found vocabulary name. + */ +#ifndef _di_f_iki_eki_t_ + typedef struct { + f_ranges_t content; + f_number_unsigneds_t delimits; + f_ranges_t variable; + f_rangess_t vocabularys; + } f_iki_eki_t; + + #define f_iki_eki_t_initialize { \ + f_ranges_t_initialize, \ + f_number_unsigneds_t_initialize, \ + f_ranges_t_initialize, \ + f_rangess_t_initialize, \ + } + + #define macro_f_iki_eki_t_initialize_1(content, delimits, variable, vocabularys) { content, delimits, variable, vocabularys } + + #define macro_f_iki_eki_t_clear(data) \ + f_ranges_t_clear(data.content) \ + f_number_unsigneds_t_clear(data.delimits) \ + f_ranges_t_clear(data.variable) \ + f_ranges_t_clear(data.vocabulary) +#endif // _di_f_iki_eki_t_ + +/** + * An array of f_iki_eki_t. + * + * Properties: + * - array: The array of IKI EKI. + * - size: Total amount of allocated space. + * - used: Total number of allocated spaces used. + */ +#ifndef _di_f_iki_ekis_t_ + typedef struct { + f_iki_eki_t *array; + + f_number_unsigned_t size; + f_number_unsigned_t used; + } f_iki_ekis_t; + + #define f_iki_ekis_t_initialize { 0, 0, 0 } + + #define macro_f_iki_ekis_t_initialize_1(content, size, used) { array, size, used } + #define macro_f_iki_ekis_t_initialize_2(array, length) { array, length, length } +#endif // _di_f_iki_ekis_t_ + +/** + * An array of f_iki_ekis_t. + * + * Properties: + * - array: The array of IKI EKIs. + * - size: Total amount of allocated space. + * - used: Total number of allocated spaces used. + */ +#ifndef _di_f_iki_ekiss_t_ + typedef struct { + f_iki_ekis_t *array; + + f_number_unsigned_t size; + f_number_unsigned_t used; + } f_iki_ekiss_t; + + #define f_iki_ekiss_t_initialize { 0, 0, 0 } + + #define macro_f_iki_ekiss_t_initialize_1(content, size, used) { array, size, used } + #define macro_f_iki_ekiss_t_initialize_2(array, length) { array, length, length } +#endif // _di_f_iki_ekiss_t_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_iki/c/iki/data.c b/level_0/f_iki/c/iki/data.c index e5e7d73..95d5322 100644 --- a/level_0/f_iki/c/iki/data.c +++ b/level_0/f_iki/c/iki/data.c @@ -1,5 +1,4 @@ #include "../iki.h" -#include "data.h" #include "private-data.h" #ifdef __cplusplus diff --git a/level_0/f_iki/c/iki/data.h b/level_0/f_iki/c/iki/data.h index 3d2e0f6..3c685d9 100644 --- a/level_0/f_iki/c/iki/data.h +++ b/level_0/f_iki/c/iki/data.h @@ -130,7 +130,6 @@ extern "C" { * Errors (with error bit) from: f_memory_array_resize(). * * @see f_memory_array_resize() - * @see f_memory_arrays_resize() */ #ifndef _di_f_iki_datas_delete_callback_ extern f_status_t f_iki_datas_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); diff --git a/level_0/f_iki/c/iki/eki.c b/level_0/f_iki/c/iki/eki.c new file mode 100644 index 0000000..163fefc --- /dev/null +++ b/level_0/f_iki/c/iki/eki.c @@ -0,0 +1,342 @@ +#include "../iki.h" +#include "private-eki.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_iki_eki_delete_ + f_status_t f_iki_eki_delete(f_iki_eki_t * const data) { + #ifndef _di_level_0_parameter_checking_ + if (!data) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + { + f_status_t status = F_okay; + + if (data->content.size && data->content.array) { + status = f_memory_array_resize(0, sizeof(f_range_t), (void **) &data->content.array, &data->content.used, &data->content.size); + if (F_status_is_error(status)) return status; + } + + if (data->delimits.size && data->delimits.array) { + status = f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &data->delimits.array, &data->delimits.used, &data->delimits.size); + if (F_status_is_error(status)) return status; + } + + if (data->variable.size && data->variable.array) { + status = f_memory_array_resize(0, sizeof(f_range_t), (void **) &data->variable.array, &data->variable.used, &data->variable.size); + if (F_status_is_error(status)) return status; + } + + if (data->vocabularys.size && data->vocabularys.array) { + status = f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &data->vocabularys.array, &data->vocabularys.used, &data->vocabularys.size, &f_rangess_delete_callback); + if (F_status_is_error(status)) return status; + } + } + + return F_okay; + } +#endif // _di_f_iki_eki_delete_ + +#ifndef _di_f_iki_eki_destroy_ + f_status_t f_iki_eki_destroy(f_iki_eki_t * const data) { + #ifndef _di_level_0_parameter_checking_ + if (!data) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + { + f_status_t status = F_okay; + + if (data->content.size && data->content.array) { + status = f_memory_array_adjust(0, sizeof(f_range_t), (void **) &data->content.array, &data->content.used, &data->content.size); + if (F_status_is_error(status)) return status; + } + + if (data->delimits.size && data->delimits.array) { + status = f_memory_array_adjust(0, sizeof(f_number_unsigned_t), (void **) &data->delimits.array, &data->delimits.used, &data->delimits.size); + if (F_status_is_error(status)) return status; + } + + if (data->variable.size && data->variable.array) { + status = f_memory_array_adjust(0, sizeof(f_range_t), (void **) &data->variable.array, &data->variable.used, &data->variable.size); + if (F_status_is_error(status)) return status; + } + + if (data->vocabularys.size && data->vocabularys.array) { + status = f_memory_arrays_adjust(0, sizeof(f_ranges_t), (void **) &data->vocabularys.array, &data->vocabularys.used, &data->vocabularys.size, &f_rangess_destroy_callback); + if (F_status_is_error(status)) return status; + } + } + + return F_okay; + } +#endif // _di_f_iki_eki_destroy_ + +#ifndef _di_f_iki_ekis_append_ + f_status_t f_iki_ekis_append(const f_iki_eki_t source, f_iki_ekis_t * const destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + { + f_status_t status = f_memory_array_increase(F_iki_default_allocation_small_d, sizeof(f_iki_eki_t), (void **) &destination->array, &destination->used, &destination->size); + if (F_status_is_error(status)) return status; + + destination->array[destination->used].content.used = 0; + destination->array[destination->used].delimits.used = 0; + destination->array[destination->used].variable.used = 0; + destination->array[destination->used].vocabularys.used = 0; + + if (source.content.used) { + status = f_ranges_append_all(source.content, &destination->array[destination->used].content); + if (F_status_is_error(status)) return status; + } + + if (source.delimits.used) { + for (f_number_unsigned_t i = 0; i < source.delimits.used; ++i) { + + status = f_memory_array_append(source.delimits.array + i, sizeof(f_number_unsigned_t), (void **) &destination->array[destination->used].delimits.array, &destination->array[destination->used].delimits.used, &destination->array[destination->used].delimits.size); + if (F_status_is_error(status)) return status; + } // for + } + + if (source.variable.used) { + status = f_ranges_append_all(source.variable, &destination->array[destination->used].variable); + if (F_status_is_error(status)) return status; + } + + if (source.vocabularys.used) { + status = f_rangess_append_all(source.vocabularys, &destination->array[destination->used].vocabularys); + if (F_status_is_error(status)) return status; + } + } + + ++destination->used; + + return F_okay; + } +#endif // _di_f_iki_ekis_append_ + +#ifndef _di_f_iki_ekis_append_all_ + f_status_t f_iki_ekis_append_all(const f_iki_ekis_t source, f_iki_ekis_t * const destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + return private_f_iki_ekis_append_all(source, destination); + } +#endif // _di_f_iki_ekis_append_all_ + +#ifndef _di_f_iki_ekis_delete_callback_ + f_status_t f_iki_ekis_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_iki_eki_t * const array = (f_iki_eki_t *) void_array; + f_status_t status = F_okay; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + if (array[i].content.size && array[i].content.array) { + status = f_memory_array_resize(0, sizeof(f_range_t), (void **) &array[i].content.array, &array[i].content.used, &array[i].content.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].delimits.size && array[i].delimits.array) { + status = f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &array[i].delimits.array, &array[i].delimits.used, &array[i].delimits.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].variable.size && array[i].variable.array) { + status = f_memory_array_resize(0, sizeof(f_range_t), (void **) &array[i].variable.array, &array[i].variable.used, &array[i].variable.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].vocabularys.size && array[i].vocabularys.array) { + status = f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &array[i].vocabularys.array, &array[i].vocabularys.used, &array[i].vocabularys.size, &f_rangess_delete_callback); + if (F_status_is_error(status)) return status; + } + } // for + } + + return F_okay; + } +#endif // _di_f_iki_ekis_delete_callback_ + +#ifndef _di_f_iki_ekis_destroy_callback_ + f_status_t f_iki_ekis_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_iki_eki_t * const array = (f_iki_eki_t *) void_array; + f_status_t status = F_okay; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + if (array[i].content.size && array[i].content.array) { + status = f_memory_array_adjust(0, sizeof(f_range_t), (void **) &array[i].content.array, &array[i].content.used, &array[i].content.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].delimits.size && array[i].delimits.array) { + status = f_memory_array_adjust(0, sizeof(f_number_unsigned_t), (void **) &array[i].delimits.array, &array[i].delimits.used, &array[i].delimits.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].variable.size && array[i].variable.array) { + status = f_memory_array_adjust(0, sizeof(f_range_t), (void **) &array[i].variable.array, &array[i].variable.used, &array[i].variable.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].vocabularys.size && array[i].vocabularys.array) { + status = f_memory_arrays_adjust(0, sizeof(f_ranges_t), (void **) &array[i].vocabularys.array, &array[i].vocabularys.used, &array[i].vocabularys.size, &f_rangess_destroy_callback); + if (F_status_is_error(status)) return status; + } + } // for + } + + return F_okay; + } +#endif // _di_f_iki_ekis_destroy_callback_ + +#ifndef _di_f_iki_ekiss_append_ + f_status_t f_iki_ekiss_append(const f_iki_ekis_t source, f_iki_ekiss_t * const destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + { + f_status_t status = f_memory_array_increase(F_memory_default_allocation_small_d, sizeof(f_iki_ekis_t), (void **) &destination->array, &destination->used, &destination->size); + if (F_status_is_error(status)) return status; + + status = private_f_iki_ekis_append_all(source, &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + } + + ++destination->used; + + return F_okay; + } +#endif // _di_f_iki_ekiss_append_ + +#ifndef _di_f_iki_ekiss_append_all_ + f_status_t f_iki_ekiss_append_all(const f_iki_ekiss_t source, f_iki_ekiss_t * const destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + { + f_status_t status = f_memory_array_increase_by(source.used, sizeof(f_iki_ekis_t), (void **) &destination->array, &destination->used, &destination->size); + if (F_status_is_error(status)) return status; + + for (f_number_unsigned_t i = 0; i < source.used; ++i, ++destination->used) { + + destination->array[destination->used].used = 0; + + if (source.array[i].used) { + status = private_f_iki_ekis_append_all(source.array[i], &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + } + } // for + } + + return F_okay; + } +#endif // _di_f_iki_ekiss_append_all_ + +#ifndef _di_f_iki_ekiss_delete_callback_ + f_status_t f_iki_ekiss_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_iki_ekis_t * const array = (f_iki_ekis_t *) void_array; + f_status_t status = F_okay; + f_number_unsigned_t j = 0; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + for (j = 0; j < array[i].size; ++j) { + + if (array[i].array[j].content.size && array[i].array[j].content.array) { + status = f_memory_array_resize(0, sizeof(f_range_t), (void **) &array[i].array[j].content.array, &array[i].array[j].content.used, &array[i].array[j].content.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].array[j].delimits.size && array[i].array[j].delimits.array) { + status = f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &array[i].array[j].delimits.array, &array[i].array[j].delimits.used, &array[i].array[j].delimits.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].array[j].variable.size && array[i].array[j].variable.array) { + status = f_memory_array_resize(0, sizeof(f_range_t), (void **) &array[i].array[j].variable.array, &array[i].array[j].variable.used, &array[i].array[j].variable.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].array[j].vocabularys.size && array[i].array[j].vocabularys.array) { + status = f_memory_arrays_resize(0, sizeof(f_ranges_t), (void **) &array[i].array[j].vocabularys.array, &array[i].array[j].vocabularys.used, &array[i].array[j].vocabularys.size, &f_rangess_delete_callback); + if (F_status_is_error(status)) return status; + } + } // for + + if (array[i].size && array[i].array) { + status = f_memory_array_resize(0, sizeof(f_iki_eki_t), (void **) &array[i].array, &array[i].used, &array[i].size); + if (F_status_is_error(status)) return status; + } + } // for + } + + return F_okay; + } +#endif // _di_f_iki_ekiss_delete_callback_ + +#ifndef _di_f_iki_ekiss_destroy_callback_ + f_status_t f_iki_ekiss_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_iki_ekis_t * const array = (f_iki_ekis_t *) void_array; + f_status_t status = F_okay; + f_number_unsigned_t j = 0; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + for (j = 0; j < array[i].size; ++j) { + + if (array[i].array[j].content.size && array[i].array[j].content.array) { + status = f_memory_array_adjust(0, sizeof(f_range_t), (void **) &array[i].array[j].content.array, &array[i].array[j].content.used, &array[i].array[j].content.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].array[j].delimits.size && array[i].array[j].delimits.array) { + status = f_memory_array_adjust(0, sizeof(f_number_unsigned_t), (void **) &array[i].array[j].delimits.array, &array[i].array[j].delimits.used, &array[i].array[j].delimits.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].array[j].variable.size && array[i].array[j].variable.array) { + status = f_memory_array_adjust(0, sizeof(f_range_t), (void **) &array[i].array[j].variable.array, &array[i].array[j].variable.used, &array[i].array[j].variable.size); + if (F_status_is_error(status)) return status; + } + + if (array[i].array[j].vocabularys.size && array[i].array[j].vocabularys.array) { + status = f_memory_arrays_adjust(0, sizeof(f_ranges_t), (void **) &array[i].array[j].vocabularys.array, &array[i].array[j].vocabularys.used, &array[i].array[j].vocabularys.size, &f_rangess_destroy_callback); + if (F_status_is_error(status)) return status; + } + } // for + + if (array[i].size && array[i].array) { + status = f_memory_array_adjust(0, sizeof(f_iki_eki_t), (void **) &array[i].array, &array[i].used, &array[i].size); + if (F_status_is_error(status)) return status; + } + } // for + } + + return F_okay; + } +#endif // _di_f_iki_ekiss_destroy_callback_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/c/iki/eki.h b/level_0/f_iki/c/iki/eki.h new file mode 100644 index 0000000..5e5196e --- /dev/null +++ b/level_0/f_iki/c/iki/eki.h @@ -0,0 +1,293 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Defines data to be used for/by iki related functionality. + * + * This is auto-included by iki.h and should not need to be explicitly included. + */ +#ifndef _F_iki_eki_h +#define _F_iki_eki_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Delete the IKI EKI data. + * + * @param data + * The IKI EKI data to delete. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_resize(). + * Errors (with error bit) from: f_memory_arrays_resize(). + * + * @see f_memory_array_resize() + * @see f_memory_arrays_resize() + */ +#ifndef _di_f_iki_eki_delete_ + extern f_status_t f_iki_eki_delete(f_iki_eki_t * const data); +#endif // _di_f_iki_eki_delete_ + +/** + * Destroy the IKI EKI data. + * + * @param data + * The IKI EKI data to destroy. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_adjust(). + * Errors (with error bit) from: f_memory_arrays_adjust(). + * + * @see f_memory_array_adjust() + * @see f_memory_arrays_adjust() + */ +#ifndef _di_f_iki_eki_destroy_ + extern f_status_t f_iki_eki_destroy(f_iki_eki_t * const data); +#endif // _di_f_iki_eki_destroy_ + +/** + * Append the single source iki_eki onto the destination. + * + * @param source + * The source iki_eki to append. + * @param destination + * The destination iki_ekis the source is appended onto. + * + * @return + * F_okay on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_append(). + * Errors (with error bit) from: f_memory_array_increase(). + * Errors (with error bit) from: f_ranges_append_all(). + * Errors (with error bit) from: f_rangess_append_all(). + * + * @see f_memory_array_append() + * @see f_memory_array_increase() + * @see f_ranges_append_all() + * @see f_rangess_append_all() + */ +#ifndef _di_f_iki_ekis_append_ + extern f_status_t f_iki_ekis_append(const f_iki_eki_t source, f_iki_ekis_t * const destination); +#endif // _di_f_iki_ekis_append_ + +/** + * Append the source iki_ekis onto the destination. + * + * @param source + * The source iki_ekis to append. + * @param destination + * The destination iki_ekis the source is appended onto. + * + * @return + * F_okay on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_append(). + * Errors (with error bit) from: f_memory_array_increase_by(). + * Errors (with error bit) from: f_ranges_append_all(). + * Errors (with error bit) from: f_rangess_append_all(). + * + * @see f_memory_array_append() + * @see f_memory_array_increase_by() + * @see f_ranges_append_all() + * @see f_rangess_append_all() + */ +#ifndef _di_f_iki_ekis_append_all_ + extern f_status_t f_iki_ekis_append_all(const f_iki_ekis_t source, f_iki_ekis_t * const destination); +#endif // _di_f_iki_ekis_append_all_ + +/** + * A callback intended to be passed to f_memory_arrays_resize() for an f_iki_ekis_t structure. + * + * This is only called when shrinking the array and generally should perform deallocations. + * + * This does not do parameter checking. + * + * @param start + * The inclusive start position in the array to start deleting. + * @param stop + * The exclusive stop position in the array to stop deleting. + * @param array + * The array structure to delete all values of. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_resize(). + * Errors (with error bit) from: f_memory_arrays_resize(). + * + * @see f_memory_array_resize() + * @see f_memory_arrays_resize() + */ +#ifndef _di_f_iki_ekis_delete_callback_ + extern f_status_t f_iki_ekis_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_iki_ekis_delete_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_adjust() for an f_iki_ekis_t structure. + * + * This is only called when shrinking the array and generally should perform deallocations. + * + * This does not do parameter checking. + * + * @param start + * The inclusive start position in the array to start deleting. + * @param stop + * The exclusive stop position in the array to stop deleting. + * @param array + * The array structure to delete all values of. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_adjust(). + * Errors (with error bit) from: f_memory_arrays_adjust(). + * + * @see f_memory_array_adjust() + * @see f_memory_arrays_adjust() + */ +#ifndef _di_f_iki_ekis_destroy_callback_ + extern f_status_t f_iki_ekis_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_iki_ekis_destroy_callback_ + +/** + * Append the single source iki_ekis onto the destination. + * + * @param source + * The source iki_ekis to append. + * @param destination + * The destination ranges the source is appended onto. + * + * @return + * F_okay on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_increase(). + * Errors (with error bit) from: f_memory_array_resize(). + * + * @see f_memory_array_increase() + * @see f_memory_array_resize() + */ +#ifndef _di_f_iki_ekiss_append_ + extern f_status_t f_iki_ekiss_append(const f_iki_ekis_t source, f_iki_ekiss_t * const destination); +#endif // _di_f_iki_ekiss_append_ + +/** + * Append the source iki_ekiss onto the destination. + * + * @param source + * The source iki_ekiss to append. + * @param destination + * The destination ranges the source is appended onto. + * + * @return + * F_okay on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_increase_by(). + * Errors (with error bit) from: f_memory_array_resize(). + * + * @see f_memory_array_increase_by() + * @see f_memory_array_resize() + */ +#ifndef _di_f_iki_ekiss_append_all_ + extern f_status_t f_iki_ekiss_append_all(const f_iki_ekiss_t source, f_iki_ekiss_t * const destination); +#endif // _di_f_iki_ekiss_append_all_ + +/** + * A callback intended to be passed to f_memory_arrays_resize() for an f_iki_ekiss_t structure. + * + * This is only called when shrinking the array and generally should perform deallocations. + * + * This does not do parameter checking. + * + * @param start + * The inclusive start position in the array to start deleting. + * @param stop + * The exclusive stop position in the array to stop deleting. + * @param array + * The array structure to delete all values of. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_resize(). + * Errors (with error bit) from: f_memory_arrays_resize(). + * + * @see f_memory_array_resize() + * @see f_memory_arrays_resize() + */ +#ifndef _di_f_iki_ekiss_delete_callback_ + extern f_status_t f_iki_ekiss_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_iki_ekiss_delete_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_adjust() for an f_iki_ekiss_t structure. + * + * This is only called when shrinking the array and generally should perform deallocations. + * + * This does not do parameter checking. + * + * @param start + * The inclusive start position in the array to start deleting. + * @param stop + * The exclusive stop position in the array to stop deleting. + * @param array + * The array structure to delete all values of. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_array_adjust(). + * Errors (with error bit) from: f_memory_arrays_adjust(). + * + * @see f_memory_array_adjust() + * @see f_memory_arrays_adjust() + */ +#ifndef _di_f_iki_ekiss_destroy_callback_ + extern f_status_t f_iki_ekiss_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_iki_ekiss_destroy_callback_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_iki_eki_h diff --git a/level_0/f_iki/c/iki/private-eki.c b/level_0/f_iki/c/iki/private-eki.c new file mode 100644 index 0000000..fd200c9 --- /dev/null +++ b/level_0/f_iki/c/iki/private-eki.c @@ -0,0 +1,53 @@ +#include "../iki.h" +#include "private-eki.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_iki_ekis_append_) || !defined(_di_f_iki_ekis_append_all_) || !defined(_di_f_iki_ekiss_append_all_) + extern f_status_t private_f_iki_ekis_append_all(const f_iki_ekis_t source, f_iki_ekis_t * const destination) { + + f_status_t status = f_memory_array_increase_by(source.used, sizeof(f_iki_eki_t), (void **) &destination->array, &destination->used, &destination->size); + if (F_status_is_error(status)) return status; + + { + f_number_unsigned_t j = 0; + + for (f_number_unsigned_t i = 0; i < source.used; ++i, ++destination->used) { + + destination->array[destination->used].content.used = 0; + destination->array[destination->used].delimits.used = 0; + destination->array[destination->used].variable.used = 0; + destination->array[destination->used].vocabularys.used = 0; + + if (source.array[i].content.used) { + status = f_ranges_append_all(source.array[i].content, &destination->array[destination->used].content); + if (F_status_is_error(status)) return status; + } + + for (j = 0; j < source.array[i].delimits.used; ++j) { + + status = f_memory_array_append(source.array[i].delimits.array + j, sizeof(f_number_unsigned_t), (void **) &destination->array[destination->used].delimits.array, &destination->array[destination->used].delimits.used, &destination->array[destination->used].delimits.size); + if (F_status_is_error(status)) return status; + } // for + + if (source.array[i].variable.used) { + status = f_ranges_append_all(source.array[i].variable, &destination->array[destination->used].variable); + if (F_status_is_error(status)) return status; + } + + if (source.array[i].vocabularys.used) { + status = f_rangess_append_all(source.array[i].vocabularys, &destination->array[destination->used].vocabularys); + if (F_status_is_error(status)) return status; + } + } // for + } + + return F_okay; + } +#endif // !defined(_di_f_iki_ekis_append_) || !defined(_di_f_iki_ekis_append_all_) || !defined(_di_f_iki_ekiss_append_all_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/c/iki/private-eki.h b/level_0/f_iki/c/iki/private-eki.h new file mode 100644 index 0000000..e6ee0ff --- /dev/null +++ b/level_0/f_iki/c/iki/private-eki.h @@ -0,0 +1,52 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_F_iki_eki_h +#define _PRIVATE_F_iki_eki_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation for appending the iki_eki array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source iki_ekis to append. + * @param destination + * The iki_ekis array the source is appended onto. + * + * @return + * F_okay on success. + * + * Errors (with error bit) from: f_memory_array_append(). + * Errors (with error bit) from: f_memory_array_increase_by(). + * Errors (with error bit) from: f_ranges_append_all(). + * Errors (with error bit) from: f_rangess_append_all(). + * + * @see f_memory_array_append() + * @see f_memory_array_increase_by() + * @see f_ranges_append_all() + * @see f_rangess_append_all() + * + * @see f_iki_ekiss_append() + * @see f_iki_ekiss_append_all() + */ +#if !defined(_di_f_iki_ekis_append_) || !defined(_di_f_iki_ekis_append_all_) || !defined(_di_f_iki_ekiss_append_all_) + extern f_status_t private_f_iki_ekis_append_all(const f_iki_ekis_t source, f_iki_ekis_t * const destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_iki_ekis_append_) || !defined(_di_f_iki_ekis_append_all_) || !defined(_di_f_iki_ekiss_append_all_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_iki_eki_h diff --git a/level_0/f_iki/data/build/settings b/level_0/f_iki/data/build/settings index 3ccad07..05102e6 100644 --- a/level_0/f_iki/data/build/settings +++ b/level_0/f_iki/data/build/settings @@ -36,9 +36,9 @@ build_language c build_libraries -lc build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_utf -build_sources_library iki.c private-iki.c iki/common.c iki/private-data.c iki/data.c +build_sources_library iki.c private-iki.c iki/common.c iki/private-data.c iki/private-eki.c iki/data.c iki/eki.c -build_sources_headers iki.h iki/common.h iki/data.h +build_sources_headers iki.h iki/common.h iki/data.h iki/eki.h build_script yes build_shared yes diff --git a/level_0/f_iki/data/build/settings-mocks b/level_0/f_iki/data/build/settings-mocks index 8dc12b6..5b68063 100644 --- a/level_0/f_iki/data/build/settings-mocks +++ b/level_0/f_iki/data/build/settings-mocks @@ -30,10 +30,10 @@ build_language c build_libraries -lc build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_utf -build_sources_library iki.c private-iki.c iki/common.c iki/private-data.c iki/data.c +build_sources_library iki.c private-iki.c iki/common.c iki/private-data.c iki/private-eki.c iki/data.c iki/eki.c build_sources_library ../../tests/unit/c/mock-iki.c -build_sources_headers iki.h iki/common.h iki/data.h +build_sources_headers iki.h iki/common.h iki/data.h iki/eki.h build_script yes build_shared yes @@ -70,3 +70,5 @@ flags_library -fPIC # Inject mocks. flags -Wl,--wrap=f_memory_array_adjust flags -Wl,--wrap=f_memory_array_resize +flags -Wl,--wrap=f_memory_arrays_adjust +flags -Wl,--wrap=f_memory_arrays_resize diff --git a/level_0/f_iki/data/build/settings-tests b/level_0/f_iki/data/build/settings-tests index 14311d2..294b995 100644 --- a/level_0/f_iki/data/build/settings-tests +++ b/level_0/f_iki/data/build/settings-tests @@ -25,9 +25,11 @@ build_language c build_libraries -lc -lcmocka build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_utf -lf_iki -build_sources_program test-iki-content_is.c test-iki-content_partial_is.c test-iki-object_is.c test-iki-object_partial_is.c test-iki-read.c +build_sources_program test-iki-content_is.c test-iki-content_partial_is.c test-iki-eki_read.c test-iki-object_is.c test-iki-object_partial_is.c test-iki-read.c build_sources_program test-iki-datas_append.c test-iki-datas_append_all.c test-iki-datass_append.c test-iki-datass_append_all.c build_sources_program test-iki-datas_delete_callback.c test-iki-datas_destroy_callback.c test-iki-datass_delete_callback.c test-iki-datass_destroy_callback.c +build_sources_program test-iki-ekis_append.c test-iki-ekis_append_all.c test-iki-ekiss_append.c test-iki-ekiss_append_all.c +build_sources_program test-iki-ekis_delete_callback.c test-iki-ekis_destroy_callback.c test-iki-ekiss_delete_callback.c test-iki-ekiss_destroy_callback.c build_sources_program test-iki.c build_script no diff --git a/level_0/f_iki/tests/unit/c/mock-iki.c b/level_0/f_iki/tests/unit/c/mock-iki.c index f524333..7032378 100644 --- a/level_0/f_iki/tests/unit/c/mock-iki.c +++ b/level_0/f_iki/tests/unit/c/mock-iki.c @@ -24,6 +24,23 @@ f_status_t __wrap_f_memory_array_adjust(const f_number_unsigned_t length, const return mock_type(f_status_t); } +f_status_t __wrap_f_memory_arrays_adjust(const f_number_unsigned_t length, const size_t width, void ** const array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { + + if (mock_unwrap_f_memory) { + return __real_f_memory_arrays_adjust(length, width, array, used, size); + } + + if (!array || !used || !size) return F_status_set_error(F_parameter_not); + + const bool failure = mock_type(bool); + + if (failure) return mock_type(f_status_t); + + *size = length; + + return mock_type(f_status_t); +} + f_status_t __wrap_f_memory_array_resize(const f_number_unsigned_t length, const size_t width, void ** const array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { if (mock_unwrap_f_memory) { @@ -41,6 +58,23 @@ f_status_t __wrap_f_memory_array_resize(const f_number_unsigned_t length, const return mock_type(f_status_t); } +f_status_t __wrap_f_memory_arrays_resize(const f_number_unsigned_t length, const size_t width, void ** const array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { + + if (mock_unwrap_f_memory) { + return __real_f_memory_arrays_resize(length, width, array, used, size); + } + + if (!array || !used || !size) return F_status_set_error(F_parameter_not); + + const bool failure = mock_type(bool); + + if (failure) return mock_type(f_status_t); + + *size = length; + + return mock_type(f_status_t); +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_iki/tests/unit/c/mock-iki.h b/level_0/f_iki/tests/unit/c/mock-iki.h index 9946ea2..1f035d3 100644 --- a/level_0/f_iki/tests/unit/c/mock-iki.h +++ b/level_0/f_iki/tests/unit/c/mock-iki.h @@ -35,9 +35,15 @@ extern int mock_unwrap_f_memory; extern f_status_t __real_f_memory_array_adjust(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); extern f_status_t __real_f_memory_array_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); +extern f_status_t __real_f_memory_arrays_adjust(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); +extern f_status_t __real_f_memory_arrays_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); + extern f_status_t __wrap_f_memory_array_adjust(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); extern f_status_t __wrap_f_memory_array_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); +extern f_status_t __wrap_f_memory_arrays_adjust(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); +extern f_status_t __wrap_f_memory_arrays_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-eki_read.c b/level_0/f_iki/tests/unit/c/test-iki-eki_read.c new file mode 100644 index 0000000..bde259b --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-eki_read.c @@ -0,0 +1,465 @@ +#include "test-iki.h" +#include "test-iki-eki_read.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_eki_read__parameter_checking(void **state) { + + f_state_t state_data = f_state_t_initialize; + f_string_static_t empty = macro_f_string_static_t_initialize_1(f_string_empty_s.string, f_string_empty_s.size, f_string_empty_s.used); + + { + f_range_t range = f_range_t_initialize; + f_iki_eki_t eki = f_iki_eki_t_initialize; + + f_iki_eki_read(0, &range, &eki, &state_data); + + assert_int_equal(state_data.status, F_status_set_error(F_parameter)); + } + + { + f_iki_eki_t eki = f_iki_eki_t_initialize; + + f_iki_eki_read(&empty, 0, &eki, &state_data); + + assert_int_equal(state_data.status, F_status_set_error(F_parameter)); + } + + { + f_range_t range = f_range_t_initialize; + + f_iki_eki_read(&empty, &range, 0, &state_data); + + assert_int_equal(state_data.status, F_status_set_error(F_parameter)); + } +} + +void test__f_iki_eki_read__returns_data_not(void **state) { + + f_state_t state_data = f_state_t_initialize; + f_string_static_t empty = macro_f_string_static_t_initialize_1(f_string_empty_s.string, f_string_empty_s.size, f_string_empty_s.used); + + { + f_range_t range = f_range_t_initialize; + f_iki_eki_t eki = f_iki_eki_t_initialize; + + f_iki_eki_read(&empty, &range, &eki, &state_data); + + assert_int_equal(F_status_set_fine(state_data.status), F_data_not); + } +} + +void test__f_iki_eki_read__returns_data_not_eos(void **state) { + + f_state_t state_data = f_state_t_initialize; + f_string_static_t ascii_a = macro_f_string_static_t_initialize_1(f_string_ascii_a_s.string, f_string_ascii_a_s.size, f_string_ascii_a_s.used); + + { + f_range_t range = macro_f_range_t_initialize_1(f_string_ascii_a_s.used, f_string_ascii_a_s.used); + f_iki_eki_t eki = f_iki_eki_t_initialize; + + f_iki_eki_read(&ascii_a, &range, &eki, &state_data); + + assert_int_equal(F_status_set_fine(state_data.status), F_data_not_eos); + } +} + +void test__f_iki_eki_read__returns_data_not_stop(void **state) { + + f_state_t state_data = f_state_t_initialize; + f_string_static_t ascii_a = macro_f_string_static_t_initialize_1(f_string_ascii_a_s.string, f_string_ascii_a_s.size, f_string_ascii_a_s.used); + + { + f_range_t range = f_range_t_initialize; + f_iki_eki_t eki = f_iki_eki_t_initialize; + + f_iki_eki_read(&ascii_a, &range, &eki, &state_data); + + assert_int_equal(F_status_set_fine(state_data.status), F_data_not_stop); + } +} + +void test__f_iki_eki_read__works(void **state) { + + mock_unwrap = 1; + + f_state_t state_data = f_state_t_initialize; + f_string_static_t empty = macro_f_string_static_t_initialize_1(f_string_empty_s.string, f_string_empty_s.size, f_string_empty_s.used); + f_string_static_t ascii_a = macro_f_string_static_t_initialize_1(f_string_ascii_a_s.string, f_string_ascii_a_s.size, f_string_ascii_a_s.used); + + #define _inline_macro_total_rows 34 + + f_string_static_t buffers[] = { + empty, + ascii_a, + macro_f_string_static_t_initialize_1("iki:'one'", 0, 9), + macro_f_string_static_t_initialize_1("Has iki:'one' two:'iki and spaces'.", 0, 35), + macro_f_string_static_t_initialize_1("iki:\"one\"", 0, 9), + macro_f_string_static_t_initialize_1("Has iki:\"one\" two:\"iki and spaces\".", 0, 35), + macro_f_string_static_t_initialize_1("export PATH=\"/bin:/sbin:some:'A_PATH'\"", 0, 38), + macro_f_string_static_t_initialize_1("export PATH=\"/bin:/sbin:some:\"A_PATH\"\"", 0, 38), + macro_f_string_static_t_initialize_1("This wor_ks:'hopefully'!", 0, 24), + macro_f_string_static_t_initialize_1("This work-s:'hopefully'!", 0, 24), + macro_f_string_static_t_initialize_1("This wor++ks:'hopefully'!", 0, 25), + macro_f_string_static_t_initialize_1("This w_-+s:'hopefully'!", 0, 23), + macro_f_string_static_t_initialize_1("This wor_ks:\"hopefully\"!", 0, 24), + macro_f_string_static_t_initialize_1("This work-s:\"hopefully\"!", 0, 24), + macro_f_string_static_t_initialize_1("This wor++ks:\"hopefully\"!", 0, 25), + macro_f_string_static_t_initialize_1("This w_-+s:\"hopefully\"!", 0, 23), + macro_f_string_static_t_initialize_1("IKI Content:'May have spaces\\' and quotes.'", 0, 43), + macro_f_string_static_t_initialize_1("IKI Content:\"May have spaces\\\" and quotes.\"", 0, 43), + macro_f_string_static_t_initialize_1("IKI Content:'May have spaces\\' and\" quotes.'", 0, 44), + macro_f_string_static_t_initialize_1("IKI Content:\"May have spaces\\\" and' quotes.\"", 0, 44), + macro_f_string_static_t_initialize_1("url:'https://localhost/fake-0.7.0.tar.gz?query=xx¶meter=yyy%20' end.", 0, 72), + macro_f_string_static_t_initialize_1("url:\"https://localhost/fake-0.7.0.tar.gz?query=xx¶meter=yyy%20\" end.", 0, 72), + macro_f_string_static_t_initialize_1("url:`https://localhost/fake-0.7.0.tar.gz?query=xx¶meter=yyy%20` end.", 0, 72), + macro_f_string_static_t_initialize_1("iki:'\"`' iki:'`\"'", 0, 17), + macro_f_string_static_t_initialize_1("[iki]:\"one\"", 0, 11), + macro_f_string_static_t_initialize_1("[iki]\\:\"none\"", 0, 13), + macro_f_string_static_t_initialize_1("[eki:iki]:\"one\"", 0, 15), + macro_f_string_static_t_initialize_1("[[iki]]:\"none\"", 0, 14), + macro_f_string_static_t_initialize_1("[[iki]]:`none`", 0, 14), + macro_f_string_static_t_initialize_1("[iki]:`one`", 0, 11), + macro_f_string_static_t_initialize_1("[iki]\\:'not'", 0, 12), + macro_f_string_static_t_initialize_1("iki\\:'not'", 0, 10), + macro_f_string_static_t_initialize_1("an:iki\\:'not'", 0, 13), + macro_f_string_static_t_initialize_1("an:iki:'is!'", 0, 12), + }; + + const f_number_unsigned_t matches_total[] = { + 0, + 0, + 1, + 2, + 1, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + }; + + const f_number_unsigned_t matches_set[] = { + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + }; + + const f_number_unsigned_t matches_each[][_inline_macro_total_rows] = { + { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 0 }, + { 1, 0 }, + { 2, 0 }, + { 1, 1 }, + { 1, 1 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 1, 0 }, + { 2, 0 }, + { 1, 0 }, + { 0, 0 }, + { 1, 0 }, + { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 1, 1 }, + }; + + const f_status_t statuss[] = { + F_data_not, + F_data_not_stop, + F_okay_stop, + F_okay, + F_okay_stop, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay_stop, + F_okay_stop, + F_okay_stop, + F_okay_stop, + F_okay, + F_okay, + F_okay, + F_okay, + F_okay_stop, + F_data_not_stop, + F_okay_stop, + F_data_not_stop, + F_data_not_stop, + F_okay_stop, + F_data_not_stop, + F_data_not_stop, + F_data_not_stop, + F_okay_stop, + }; + + const f_range_t variables[][_inline_macro_total_rows] = { + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 8), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 12), macro_f_range_t_initialize_1(14, 33) }, + { macro_f_range_t_initialize_1(0, 8), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 12), macro_f_range_t_initialize_1(14, 33) }, + { macro_f_range_t_initialize_1(19, 36), f_range_t_initialize }, + { macro_f_range_t_initialize_1(19, 36), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 22), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 22), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 23), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 21), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 22), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 22), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 23), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 21), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 42), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 42), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 43), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 43), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 66), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 66), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 66), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 7), macro_f_range_t_initialize_1(9, 16) }, + { macro_f_range_t_initialize_1(0, 10), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 14), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 10), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 11), f_range_t_initialize }, + }; + + const f_range_t vocabularys[][_inline_macro_total_rows] = { + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 6), macro_f_range_t_initialize_1(14, 16) }, + { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 6), macro_f_range_t_initialize_1(14, 16) }, + { macro_f_range_t_initialize_1(19, 22), macro_f_range_t_initialize_1(24, 27) }, + { macro_f_range_t_initialize_1(19, 22), macro_f_range_t_initialize_1(24, 27) }, + { macro_f_range_t_initialize_1(5, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 11), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 9), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 11), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 9), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(4, 10), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 2), macro_f_range_t_initialize_1(9, 11) }, + { macro_f_range_t_initialize_1(1, 3), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(1, 3), macro_f_range_t_initialize_1(5, 7) }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(1, 3), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 1), macro_f_range_t_initialize_1(3, 5) }, + }; + + const f_range_t contents[][_inline_macro_total_rows] = { + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 7), f_range_t_initialize }, + { macro_f_range_t_initialize_1(9, 11), macro_f_range_t_initialize_1(19, 32) }, + { macro_f_range_t_initialize_1(5, 7), f_range_t_initialize }, + { macro_f_range_t_initialize_1(9, 11), macro_f_range_t_initialize_1(19, 32) }, + { macro_f_range_t_initialize_1(30, 35), f_range_t_initialize }, + { macro_f_range_t_initialize_1(30, 35), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 21), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 21), f_range_t_initialize }, + { macro_f_range_t_initialize_1(14, 22), f_range_t_initialize }, + { macro_f_range_t_initialize_1(12, 20), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 21), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 21), f_range_t_initialize }, + { macro_f_range_t_initialize_1(14, 22), f_range_t_initialize }, + { macro_f_range_t_initialize_1(12, 20), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 41), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 41), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 42), f_range_t_initialize }, + { macro_f_range_t_initialize_1(13, 42), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 65), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 65), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 65), f_range_t_initialize }, + { macro_f_range_t_initialize_1(5, 6), macro_f_range_t_initialize_1(14, 15) }, + { macro_f_range_t_initialize_1(7, 9), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(11, 13), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(7, 9), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(8, 10), f_range_t_initialize }, + }; + + for (uint8_t i = 0; i < _inline_macro_total_rows; ++i) { + + f_range_t range = macro_f_range_t_initialize_2(buffers[i].used); + f_iki_eki_t eki = f_iki_eki_t_initialize; + f_number_unsigned_t j = 0; + + f_iki_eki_read(&buffers[i], &range, &eki, &state_data); + + assert_int_equal(state_data.status, statuss[i]); + + if (matches_set[i]) { + if (matches_each[i][0] == 2) { + f_iki_eki_read(&buffers[i], &range, &eki, &state_data); + + assert_int_equal(F_status_is_error_not(state_data.status) ? 0 : 1, 0); + } + + if (matches_set[i] > 1) { + if (matches_each[i][1] == 2) { + f_iki_eki_read(&buffers[i], &range, &eki, &state_data); + + assert_int_equal(F_status_is_error_not(state_data.status) ? 0 : 1, 0); + } + } + } + + if (matches_set[i]) { + assert_int_equal(eki.variable.used, matches_total[i]); + assert_int_equal(eki.vocabularys.used, matches_total[i]); + assert_int_equal(eki.content.used, matches_total[i]); + + if (matches_each[i][0]) { + assert_int_equal(eki.variable.array[0].start, variables[i][0].start); + assert_int_equal(eki.variable.array[0].stop, variables[i][0].stop); + + assert_int_equal(eki.vocabularys.array[0].array[0].start, vocabularys[i][j].start); + assert_int_equal(eki.vocabularys.array[0].array[0].stop, vocabularys[i][j].stop); + ++j; + + if (matches_each[i][0] > 1) { + assert_int_equal(eki.vocabularys.array[1].array[0].start, vocabularys[i][j].start); + assert_int_equal(eki.vocabularys.array[1].array[0].stop, vocabularys[i][j].stop); + ++j; + } + + if (matches_set[i] > 1 && matches_each[i][1]) { + assert_int_equal(eki.vocabularys.array[0].array[1].start, vocabularys[i][j].start); + assert_int_equal(eki.vocabularys.array[0].array[1].stop, vocabularys[i][j].stop); + ++j; + + if (matches_each[i][1] > 1) { + assert_int_equal(eki.vocabularys.array[1].array[1].start, vocabularys[i][j].start); + assert_int_equal(eki.vocabularys.array[1].array[1].stop, vocabularys[i][j].stop); + ++j; + } + } + + assert_int_equal(eki.content.array[0].start, contents[i][0].start); + assert_int_equal(eki.content.array[0].stop, contents[i][0].stop); + } + } + + f_iki_eki_delete(&eki); + + eki.variable.used = 0; + eki.vocabularys.used = 0; + eki.content.used = 0; + eki.delimits.used = 0; + } // for + + #undef _inline_macro_total_rows +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-eki_read.h b/level_0/f_iki/tests/unit/c/test-iki-eki_read.h new file mode 100644 index 0000000..cc53cca --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-eki_read.h @@ -0,0 +1,48 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the iki project. + */ +#ifndef _TEST__F_iki_eki_read_h +#define _TEST__F_iki_eki_read_h + +/** + * Test that parameter checking works as expected. + * + * @see f_iki_eki_read() + */ +extern void test__f_iki_eki_read__parameter_checking(void **state); + +/** + * Test that function returns F_data_not. + * + * @see f_iki_eki_read() + */ +extern void test__f_iki_eki_read__returns_data_not(void **state); + +/** + * Test that function returns F_data_not_eos. + * + * @see f_iki_eki_read() + */ +extern void test__f_iki_eki_read__returns_data_not_eos(void **state); + +/** + * Test that function returns F_data_not_stop. + * + * @see f_iki_eki_read() + */ +extern void test__f_iki_eki_read__returns_data_not_stop(void **state); + +/** + * Test that function works. + * + * @see f_iki_eki_read() + */ +extern void test__f_iki_eki_read__works(void **state); + +#endif // _TEST__F_iki_eki_read_h diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_append.c b/level_0/f_iki/tests/unit/c/test-iki-ekis_append.c new file mode 100644 index 0000000..f8155af --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_append.c @@ -0,0 +1,130 @@ +#include "test-iki.h" +#include "test-iki-ekis_append.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekis_append__works(void **state) { + + const f_number_unsigned_t length = 5; + f_iki_eki_t source = f_iki_eki_t_initialize; + f_iki_ekis_t destination = f_iki_ekis_t_initialize; + + { + f_number_unsigned_t i = 1; + + f_status_t status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.content.array, &source.content.used, &source.content.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.content.size, length); + + status = f_memory_array_resize(length, sizeof(f_number_unsigned_t), (void **) &source.delimits.array, &source.delimits.used, &source.delimits.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.delimits.size, length); + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.variable.array, &source.variable.used, &source.variable.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.variable.size, length); + + status = f_memory_arrays_resize(length, sizeof(f_ranges_t), (void **) &source.vocabularys.array, &source.vocabularys.used, &source.vocabularys.size, &f_rangess_delete_callback); + + assert_int_equal(status, F_okay); + assert_int_equal(source.vocabularys.size, length); + + for (; source.content.used < length; ++i) { + + source.content.array[source.content.used].start = i - 1; + source.content.array[source.content.used++].stop = i; + } // for + + for (; source.delimits.used < length; ++i) { + source.delimits.array[source.delimits.used++] = i; + } // for + + for (; source.variable.used < length; ++i) { + + source.variable.array[source.variable.used].start = i - 1; + source.variable.array[source.variable.used++].stop = i; + } // for + + for (; source.vocabularys.used < length; ++i) { + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &source.vocabularys.array[source.vocabularys.used].array, &source.vocabularys.array[source.vocabularys.used].used, &source.vocabularys.array[source.vocabularys.used].size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.vocabularys.array[source.vocabularys.used].size, 1); + + // The used property must be set to ensure append works for child elements to be appended. + source.vocabularys.array[source.vocabularys.used].used = 1; + source.vocabularys.array[source.vocabularys.used].array[0].start = i - 1; + source.vocabularys.array[source.vocabularys.used++].array[0].stop = i; + } // for + } + + { + const f_status_t status = f_iki_ekis_append(source, &destination); + + assert_int_equal(status, F_okay); + assert_int_equal(destination.used, 1); + assert_int_equal(destination.array[0].content.used, source.content.used); + assert_int_equal(destination.array[0].delimits.used, source.delimits.used); + assert_int_equal(destination.array[0].variable.used, source.variable.used); + assert_int_equal(destination.array[0].vocabularys.used, source.vocabularys.used); + + for (f_number_unsigned_t i = 0; i < length; ++i) { + + assert_int_equal(destination.array[0].content.array[i].start, source.content.array[i].start); + assert_int_equal(destination.array[0].content.array[i].stop, source.content.array[i].stop); + + assert_int_equal(destination.array[0].delimits.array[i], source.delimits.array[i]); + + assert_int_equal(destination.array[0].variable.array[i].start, source.variable.array[i].start); + assert_int_equal(destination.array[0].variable.array[i].stop, source.variable.array[i].stop); + + assert_int_equal(destination.array[0].vocabularys.array[i].used, 1); + + assert_int_equal(destination.array[0].vocabularys.array[i].array[0].start, source.vocabularys.array[i].array[0].start); + assert_int_equal(destination.array[0].vocabularys.array[i].array[0].stop, source.vocabularys.array[i].array[0].stop); + } // for + } + + free((void *) source.content.array); + free((void *) source.delimits.array); + free((void *) source.variable.array); + + for (f_number_unsigned_t i = 0; i < source.vocabularys.used; ++i) { + free((void *) source.vocabularys.array[i].array); + } // for + + free((void *) source.vocabularys.array); + + free((void *) destination.array[0].content.array); + free((void *) destination.array[0].delimits.array); + free((void *) destination.array[0].variable.array); + + for (f_number_unsigned_t i = 0; i < destination.array[0].vocabularys.used; ++i) { + free((void *) destination.array[0].vocabularys.array[i].array); + } // for + + free((void *) destination.array[0].vocabularys.array); + + free((void *) destination.array); +} + +void test__f_iki_ekis_append__parameter_checking(void **state) { + + const f_iki_eki_t data = f_iki_eki_t_initialize; + + { + const f_status_t status = f_iki_ekis_append(data, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_append.h b/level_0/f_iki/tests/unit/c/test-iki-ekis_append.h new file mode 100644 index 0000000..01a8243 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_append.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki_ekis_append_h +#define _TEST__F_iki_ekis_append_h + +/** + * Test that the function works. + * + * @see f_iki_ekis_append() + */ +extern void test__f_iki_ekis_append__works(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_iki_ekis_append() + */ +extern void test__f_iki_ekis_append__parameter_checking(void **state); + +#endif // _TEST__F_iki_ekis_append_h diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_append_all.c b/level_0/f_iki/tests/unit/c/test-iki-ekis_append_all.c new file mode 100644 index 0000000..2459a2d --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_append_all.c @@ -0,0 +1,180 @@ +#include "test-iki.h" +#include "test-iki-ekis_append_all.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekis_append_all__returns_data_not(void **state) { + + const int length = 5; + f_iki_ekis_t source = f_iki_ekis_t_initialize; + f_iki_ekis_t destination = f_iki_ekis_t_initialize; + + { + const f_status_t status = f_memory_array_resize(length, sizeof(f_iki_eki_t), (void **) &source.array, &source.used, &source.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.used, 0); + assert_int_equal(source.size, length); + } + + { + const f_status_t status = f_iki_ekis_append_all(source, &destination); + + assert_int_equal(status, F_data_not); + assert_int_equal(destination.used, 0); + assert_int_equal(destination.size, 0); + assert_null(destination.array); + } + + free((void *) source.array); +} + +void test__f_iki_ekis_append_all__parameter_checking(void **state) { + + const f_iki_ekis_t data = f_iki_ekis_t_initialize; + + { + const f_status_t status = f_iki_ekis_append_all(data, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_iki_ekis_append_all__works(void **state) { + + const int length = 5; + f_iki_ekis_t source = f_iki_ekis_t_initialize; + f_iki_ekis_t destination = f_iki_ekis_t_initialize; + + { + f_status_t status = f_memory_array_resize(2, sizeof(f_iki_eki_t), (void **) &source.array, &source.used, &source.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.size, 2); + + f_number_unsigned_t i = 1; + f_number_unsigned_t j = 0; + + for (; j < 2; ++j) { + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.array[j].content.array, &source.array[j].content.used, &source.array[j].content.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].content.size, length); + + status = f_memory_array_resize(length, sizeof(f_number_unsigned_t), (void **) &source.array[j].delimits.array, &source.array[j].delimits.used, &source.array[j].delimits.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].delimits.size, length); + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.array[j].variable.array, &source.array[j].variable.used, &source.array[j].variable.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].variable.size, length); + + status = f_memory_arrays_resize(length, sizeof(f_ranges_t), (void **) &source.array[j].vocabularys.array, &source.array[j].vocabularys.used, &source.array[j].vocabularys.size, &f_rangess_delete_callback); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].vocabularys.size, length); + + for (; source.array[j].content.used < length; ++i) { + + source.array[j].content.array[source.array[j].content.used].start = i - 1; + source.array[j].content.array[source.array[j].content.used++].stop = i; + } // for + + for (; source.array[j].delimits.used < length; ++i) { + + source.array[j].delimits.array[source.array[j].delimits.used++] = i; + } // for + + for (; source.array[j].variable.used < length; ++i) { + + source.array[j].variable.array[source.array[j].variable.used].start = i - 1; + source.array[j].variable.array[source.array[j].variable.used++].stop = i; + } // for + + for (; source.array[j].vocabularys.used < length; ++i) { + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &source.array[j].vocabularys.array[source.array[j].vocabularys.used].array, &source.array[j].vocabularys.array[source.array[j].vocabularys.used].used, &source.array[j].vocabularys.array[source.array[j].vocabularys.used].size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].vocabularys.array[source.array[j].vocabularys.used].size, 1); + + // The used property must be set to ensure append works for child elements to be appended. + source.array[j].vocabularys.array[source.array[j].vocabularys.used].used = 1; + source.array[j].vocabularys.array[source.array[j].vocabularys.used].array[0].start = i - 1; + source.array[j].vocabularys.array[source.array[j].vocabularys.used++].array[0].stop = i; + } // for + } // for + + source.used = 2; + } + + { + const f_status_t status = f_iki_ekis_append_all(source, &destination); + + assert_int_equal(status, F_okay); + assert_int_equal(destination.used, source.used); + assert_int_equal(destination.size, source.used); + + for (f_number_unsigned_t j = 0; j < 2; ++j) { + + assert_int_equal(destination.array[j].content.used, source.array[j].content.used); + assert_int_equal(destination.array[j].delimits.used, source.array[j].delimits.used); + assert_int_equal(destination.array[j].variable.used, source.array[j].variable.used); + assert_int_equal(destination.array[j].vocabularys.used, source.array[j].vocabularys.used); + + for (f_number_unsigned_t i = 0; i < length; ++i) { + + assert_int_equal(destination.array[j].content.array[i].start, source.array[j].content.array[i].start); + assert_int_equal(destination.array[j].content.array[i].stop, source.array[j].content.array[i].stop); + + assert_int_equal(destination.array[j].delimits.array[i], source.array[j].delimits.array[i]); + + assert_int_equal(destination.array[j].variable.array[i].start, source.array[j].variable.array[i].start); + assert_int_equal(destination.array[j].variable.array[i].stop, source.array[j].variable.array[i].stop); + + assert_int_equal(destination.array[j].vocabularys.array[i].used, 1); + + assert_int_equal(destination.array[j].vocabularys.array[i].array[0].start, source.array[j].vocabularys.array[i].array[0].start); + assert_int_equal(destination.array[j].vocabularys.array[i].array[0].stop, source.array[j].vocabularys.array[i].array[0].stop); + } // for + } // for + } + + for (f_number_unsigned_t i = 0; i < source.used; ++i) { + + free((void *) source.array[i].content.array); + free((void *) source.array[i].delimits.array); + free((void *) source.array[i].variable.array); + + for (f_number_unsigned_t j = 0; j < source.array[i].vocabularys.used; ++j) { + free((void *) source.array[i].vocabularys.array[j].array); + } // for + + free((void *) source.array[i].vocabularys.array); + } // for + + for (f_number_unsigned_t i = 0; i < destination.used; ++i) { + + free((void *) destination.array[i].content.array); + free((void *) destination.array[i].delimits.array); + free((void *) destination.array[i].variable.array); + + for (f_number_unsigned_t j = 0; j < destination.array[i].vocabularys.used; ++j) { + free((void *) destination.array[i].vocabularys.array[j].array); + } // for + + free((void *) destination.array[i].vocabularys.array); + } // for + + free((void *) source.array); + free((void *) destination.array); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_append_all.h b/level_0/f_iki/tests/unit/c/test-iki-ekis_append_all.h new file mode 100644 index 0000000..4c75778 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_append_all.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki_ekis_append_all_h +#define _TEST__F_iki_ekis_append_all_h + +/** + * Test that the function returns F_data_not when asked to copy an empty structure. + * + * @see f_iki_ekis_append_all() + */ +extern void test__f_iki_ekis_append_all__returns_data_not(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_iki_ekis_append_all() + */ +extern void test__f_iki_ekis_append_all__parameter_checking(void **state); + +/** + * Test that the function works. + * + * @see f_iki_ekis_append_all() + */ +extern void test__f_iki_ekis_append_all__works(void **state); + +#endif // _TEST__F_iki_ekis_append_all_h diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_delete_callback.c b/level_0/f_iki/tests/unit/c/test-iki-ekis_delete_callback.c new file mode 100644 index 0000000..c509dab --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_delete_callback.c @@ -0,0 +1,141 @@ +#include "test-iki.h" +#include "test-iki-ekis_delete_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekis_delete_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_range_t base = macro_f_range_t_initialize_1(1, 0); + f_range_t base_array[] = { base }; + f_ranges_t bases = { .array = base_array, .used = 0, .size = 1 }; + + f_ranges_t content = bases; + f_number_unsigned_t delimit_array[] = { 0 }; + f_number_unsigneds_t delimits = { .array = delimit_array, .used = 0, .size = 1 }; + f_ranges_t variable = bases; + f_ranges_t vocabulary_array[] = { bases }; + f_rangess_t vocabularys = { .array = vocabulary_array, .used = 0, .size = 1 }; + + f_iki_eki_t data = { .content = content, .delimits = delimits, .variable = variable, .vocabularys = vocabularys }; + f_iki_eki_t data_array[] = { data }; + + { + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_delete_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + data_array[0].content = content; + data_array[0].delimits = delimits; + data_array[0].variable = variable; + data_array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_delete_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + data_array[0].content = content; + data_array[0].delimits = delimits; + data_array[0].variable = variable; + data_array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_delete_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + data_array[0].content = content; + data_array[0].delimits = delimits; + data_array[0].variable = variable; + data_array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_arrays_resize, true); + will_return(__wrap_f_memory_arrays_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_delete_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_iki_ekis_delete_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_iki_ekis_t datas = f_iki_ekis_t_initialize; + + { + f_status_t status = f_memory_array_resize(1, sizeof(f_iki_eki_t), (void **) &datas.array, &datas.used, &datas.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datas.array[0].content.array, &datas.array[0].content.used, &datas.array[0].content.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_number_unsigned_t), (void **) &datas.array[0].delimits.array, &datas.array[0].delimits.used, &datas.array[0].delimits.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datas.array[0].variable.array, &datas.array[0].variable.used, &datas.array[0].variable.size); + assert_int_equal(status, F_okay); + + status = f_memory_arrays_resize(1, sizeof(f_ranges_t), (void **) &datas.array[0].vocabularys.array, &datas.array[0].vocabularys.used, &datas.array[0].vocabularys.size, &f_rangess_delete_callback); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datas.array[0].vocabularys.array[0].array, &datas.array[0].vocabularys.array[0].used, &datas.array[0].vocabularys.array[0].size); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_iki_ekis_delete_callback(0, length, (void *) datas.array); + + assert_int_equal(status, F_okay); + assert_int_equal(datas.array[0].content.size, 0); + assert_int_equal(datas.array[0].delimits.size, 0); + assert_int_equal(datas.array[0].variable.size, 0); + assert_int_equal(datas.array[0].vocabularys.size, 0); + } + + free((void *) datas.array); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_delete_callback.h b/level_0/f_iki/tests/unit/c/test-iki-ekis_delete_callback.h new file mode 100644 index 0000000..9ad9a5f --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_delete_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki__ekis_delete_callback +#define _TEST__F_iki__ekis_delete_callback + +/** + * Test that the function fails. + * + * @see f_iki_ekis_delete_callback() + */ +extern void test__f_iki_ekis_delete_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_iki_ekis_delete_callback() + */ +extern void test__f_iki_ekis_delete_callback__works(void **state); + +#endif // _TEST__F_iki__ekis_delete_callback diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_destroy_callback.c b/level_0/f_iki/tests/unit/c/test-iki-ekis_destroy_callback.c new file mode 100644 index 0000000..28a2b8a --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_destroy_callback.c @@ -0,0 +1,141 @@ +#include "test-iki.h" +#include "test-iki-ekis_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekis_destroy_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_range_t base = macro_f_range_t_initialize_1(1, 0); + f_range_t base_array[] = { base }; + f_ranges_t bases = { .array = base_array, .used = 0, .size = 1 }; + + f_ranges_t content = bases; + f_number_unsigned_t delimit_array[] = { 0 }; + f_number_unsigneds_t delimits = { .array = delimit_array, .used = 0, .size = 1 }; + f_ranges_t variable = bases; + f_ranges_t vocabulary_array[] = { bases }; + f_rangess_t vocabularys = { .array = vocabulary_array, .used = 0, .size = 1 }; + + f_iki_eki_t data = { .content = content, .delimits = delimits, .variable = variable, .vocabularys = vocabularys }; + f_iki_eki_t data_array[] = { data }; + + { + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_destroy_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + data_array[0].content = content; + data_array[0].delimits = delimits; + data_array[0].variable = variable; + data_array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_destroy_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + data_array[0].content = content; + data_array[0].delimits = delimits; + data_array[0].variable = variable; + data_array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_destroy_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + data_array[0].content = content; + data_array[0].delimits = delimits; + data_array[0].variable = variable; + data_array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_arrays_adjust, true); + will_return(__wrap_f_memory_arrays_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekis_destroy_callback(0, 1, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_iki_ekis_destroy_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_iki_ekis_t datas = f_iki_ekis_t_initialize; + + { + f_status_t status = f_memory_array_resize(1, sizeof(f_iki_eki_t), (void **) &datas.array, &datas.used, &datas.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datas.array[0].content.array, &datas.array[0].content.used, &datas.array[0].content.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_number_unsigned_t), (void **) &datas.array[0].delimits.array, &datas.array[0].delimits.used, &datas.array[0].delimits.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datas.array[0].variable.array, &datas.array[0].variable.used, &datas.array[0].variable.size); + assert_int_equal(status, F_okay); + + status = f_memory_arrays_resize(1, sizeof(f_ranges_t), (void **) &datas.array[0].vocabularys.array, &datas.array[0].vocabularys.used, &datas.array[0].vocabularys.size, &f_rangess_delete_callback); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datas.array[0].vocabularys.array[0].array, &datas.array[0].vocabularys.array[0].used, &datas.array[0].vocabularys.array[0].size); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_iki_ekis_destroy_callback(0, length, (void *) datas.array); + + assert_int_equal(status, F_okay); + assert_int_equal(datas.array[0].content.size, 0); + assert_int_equal(datas.array[0].delimits.size, 0); + assert_int_equal(datas.array[0].variable.size, 0); + assert_int_equal(datas.array[0].vocabularys.size, 0); + } + + free((void *) datas.array); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekis_destroy_callback.h b/level_0/f_iki/tests/unit/c/test-iki-ekis_destroy_callback.h new file mode 100644 index 0000000..7ac49d1 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekis_destroy_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki__ekis_destroy_callback +#define _TEST__F_iki__ekis_destroy_callback + +/** + * Test that the function fails. + * + * @see f_iki_ekis_destroy_callback() + */ +extern void test__f_iki_ekis_destroy_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_iki_ekis_destroy_callback() + */ +extern void test__f_iki_ekis_destroy_callback__works(void **state); + +#endif // _TEST__F_iki__ekis_destroy_callback diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_append.c b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append.c new file mode 100644 index 0000000..a275d13 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append.c @@ -0,0 +1,185 @@ +#include "test-iki.h" +#include "test-iki-ekiss_append.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekiss_append__works(void **state) { + + const int length = 5; + const int length_outer = 2; + f_iki_ekis_t source = f_iki_ekis_t_initialize; + f_iki_ekiss_t destination = f_iki_ekiss_t_initialize; + + { + f_status_t status = f_memory_array_resize(length_outer, sizeof(f_iki_eki_t), (void **) &source.array, &source.used, &source.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.size, length_outer); + + f_number_unsigned_t i = 1; + + for (f_number_unsigned_t j = 0; j < length_outer; ++j) { + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.array[j].content.array, &source.array[j].content.used, &source.array[j].content.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].content.size, length); + + status = f_memory_array_resize(length, sizeof(f_number_unsigned_t), (void **) &source.array[j].delimits.array, &source.array[j].delimits.used, &source.array[j].delimits.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].delimits.size, length); + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.array[j].variable.array, &source.array[j].variable.used, &source.array[j].variable.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].variable.size, length); + + status = f_memory_arrays_resize(length, sizeof(f_ranges_t), (void **) &source.array[j].vocabularys.array, &source.array[j].vocabularys.used, &source.array[j].vocabularys.size, &f_rangess_delete_callback); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].vocabularys.size, length); + + for (; source.array[j].content.used < length; ++i) { + + source.array[j].content.array[source.array[j].content.used].start = i - 1; + source.array[j].content.array[source.array[j].content.used++].stop = i; + } // for + + for (; source.array[j].delimits.used < length; ++i) { + + source.array[j].delimits.array[source.array[j].delimits.used++] = i; + } // for + + for (; source.array[j].variable.used < length; ++i) { + + source.array[j].variable.array[source.array[j].variable.used].start = i - 1; + source.array[j].variable.array[source.array[j].variable.used++].stop = i; + } // for + + for (; source.array[j].vocabularys.used < length; ++i) { + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &source.array[j].vocabularys.array[source.array[j].vocabularys.used].array, &source.array[j].vocabularys.array[source.array[j].vocabularys.used].used, &source.array[j].vocabularys.array[source.array[j].vocabularys.used].size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[j].vocabularys.array[source.array[j].vocabularys.used].size, 1); + + // The used property must be set to ensure append works for child elements to be appended. + source.array[j].vocabularys.array[source.array[j].vocabularys.used].used = 1; + source.array[j].vocabularys.array[source.array[j].vocabularys.used].array[0].start = i - 1; + source.array[j].vocabularys.array[source.array[j].vocabularys.used++].array[0].stop = i; + } // for + } // for + + source.used = length_outer; + } + + { + const f_status_t status = f_iki_ekiss_append(source, &destination); + + assert_int_equal(status, F_okay); + assert_int_equal(destination.used, 1); + assert_int_equal(destination.array[0].used, source.used); + + for (f_number_unsigned_t j = 0; j < destination.used; ++j) { + + assert_int_equal(destination.array[0].array[j].content.used, source.array[j].content.used); + assert_int_equal(destination.array[0].array[j].delimits.used, source.array[j].delimits.used); + assert_int_equal(destination.array[0].array[j].variable.used, source.array[j].variable.used); + assert_int_equal(destination.array[0].array[j].vocabularys.used, source.array[j].vocabularys.used); + + for (f_number_unsigned_t i = 0; i < length; ++i) { + + assert_int_equal(destination.array[0].array[j].content.array[i].start, source.array[j].content.array[i].start); + assert_int_equal(destination.array[0].array[j].content.array[i].stop, source.array[j].content.array[i].stop); + + assert_int_equal(destination.array[0].array[j].delimits.array[i], source.array[j].delimits.array[i]); + + assert_int_equal(destination.array[0].array[j].variable.array[i].start, source.array[j].variable.array[i].start); + assert_int_equal(destination.array[0].array[j].variable.array[i].stop, source.array[j].variable.array[i].stop); + + assert_int_equal(destination.array[0].array[j].vocabularys.array[i].used, 1); + + assert_int_equal(destination.array[0].array[j].vocabularys.array[i].array[0].start, source.array[j].vocabularys.array[i].array[0].start); + assert_int_equal(destination.array[0].array[j].vocabularys.array[i].array[0].stop, source.array[j].vocabularys.array[i].array[0].stop); + } // for + } // for + } + + for (f_number_unsigned_t i = 0; i < source.used; ++i) { + + free((void *) source.array[i].content.array); + free((void *) source.array[i].delimits.array); + free((void *) source.array[i].variable.array); + + for (f_number_unsigned_t j = 0; j < source.array[i].vocabularys.used; ++j) { + free((void *) source.array[i].vocabularys.array[j].array); + } // for + + free((void *) source.array[i].vocabularys.array); + } // for + + for (f_number_unsigned_t j = 0; j < destination.used; ++j) { + + for (f_number_unsigned_t i = 0; i < destination.array[j].used; ++i) { + + free((void *) destination.array[j].array[i].content.array); + free((void *) destination.array[j].array[i].delimits.array); + free((void *) destination.array[j].array[i].variable.array); + + for (f_number_unsigned_t k = 0; k < destination.array[j].array[i].vocabularys.used; ++k) { + free((void *) destination.array[j].array[i].vocabularys.array[k].array); + } // for + + free((void *) destination.array[j].array[i].vocabularys.array); + } // for + + free((void *) destination.array[j].array); + } // for + + free((void *) source.array); + free((void *) destination.array); +} + +void test__f_iki_ekiss_append__returns_data_not(void **state) { + + const int length = 5; + f_iki_ekis_t source = f_iki_ekiss_t_initialize; + f_iki_ekiss_t destination = f_iki_ekiss_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_iki_eki_t), (void **) &source.array, &source.used, &source.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.used, 0); + assert_int_equal(source.size, length); + } + + { + const f_status_t status = f_iki_ekiss_append(source, &destination); + + assert_int_equal(status, F_data_not); + assert_int_equal(destination.used, 0); + assert_int_equal(destination.size, 0); + assert_null(destination.array); + } + + free((void *) source.array); +} + +void test__f_iki_ekiss_append__parameter_checking(void **state) { + + f_iki_ekis_t data = f_iki_ekis_t_initialize; + + { + const f_status_t status = f_iki_ekiss_append(data, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_append.h b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append.h new file mode 100644 index 0000000..20716de --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki_ekiss_append_h +#define _TEST__F_iki_ekiss_append_h + +/** + * Test that the function works. + * + * @see f_iki_ekiss_append() + */ +extern void test__f_iki_ekiss_append__works(void **state); + +/** + * Test that the function returns F_data_not when asked to copy an empty structure. + * + * @see f_iki_ekiss_append() + */ +extern void test__f_iki_ekiss_append__returns_data_not(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_iki_ekiss_append() + */ +extern void test__f_iki_ekiss_append__parameter_checking(void **state); + +#endif // _TEST__F_iki_ekiss_append_h diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_append_all.c b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append_all.c new file mode 100644 index 0000000..1cc8c8f --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append_all.c @@ -0,0 +1,201 @@ +#include "test-iki.h" +#include "test-iki-ekiss_append_all.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekiss_append_all__returns_data_not(void **state) { + + const int length = 5; + f_iki_ekiss_t source = f_iki_ekiss_t_initialize; + f_iki_ekiss_t destination = f_iki_ekiss_t_initialize; + + { + const f_status_t status = f_memory_arrays_resize(length, sizeof(f_iki_eki_t), (void **) &source.array, &source.used, &source.size, &f_iki_ekis_delete_callback); + + assert_int_equal(status, F_okay); + assert_int_equal(source.used, 0); + assert_int_equal(source.size, length); + } + + { + const f_status_t status = f_iki_ekiss_append_all(source, &destination); + + assert_int_equal(status, F_data_not); + assert_int_equal(destination.used, 0); + assert_int_equal(destination.size, 0); + assert_null(destination.array); + } + + free((void *) source.array); +} + +void test__f_iki_ekiss_append_all__parameter_checking(void **state) { + + const f_iki_ekiss_t data = f_iki_ekiss_t_initialize; + + { + const f_status_t status = f_iki_ekiss_append_all(data, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_iki_ekiss_append_all__works(void **state) { + + const int length = 5; + const int length_inner = 2; + const int length_outer = 2; + f_iki_ekiss_t source = f_iki_ekiss_t_initialize; + f_iki_ekiss_t destination = f_iki_ekiss_t_initialize; + + { + f_status_t status = f_memory_arrays_resize(length_outer, sizeof(f_iki_eki_t), (void **) &source.array, &source.used, &source.size, &f_iki_ekis_delete_callback); + + assert_int_equal(status, F_okay); + assert_int_equal(source.size, length_outer); + + f_number_unsigned_t i = 1; + f_number_unsigned_t j = 0; + + for (; source.used < length_outer; ++source.used) { + + status = f_memory_array_resize(length_inner, sizeof(f_iki_eki_t), (void **) &source.array[source.used].array, &source.array[source.used].used, &source.array[source.used].size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[source.used].size, length_inner); + + for (j = 0; j < length_inner; ++j) { + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.array[source.used].array[j].content.array, &source.array[source.used].array[j].content.used, &source.array[source.used].array[j].content.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[source.used].array[j].content.size, length); + + status = f_memory_array_resize(length, sizeof(f_number_unsigned_t), (void **) &source.array[source.used].array[j].delimits.array, &source.array[source.used].array[j].delimits.used, &source.array[source.used].array[j].delimits.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[source.used].array[j].delimits.size, length); + + status = f_memory_array_resize(length, sizeof(f_range_t), (void **) &source.array[source.used].array[j].variable.array, &source.array[source.used].array[j].variable.used, &source.array[source.used].array[j].variable.size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[source.used].array[j].variable.size, length); + + status = f_memory_arrays_resize(length, sizeof(f_ranges_t), (void **) &source.array[source.used].array[j].vocabularys.array, &source.array[source.used].array[j].vocabularys.used, &source.array[source.used].array[j].vocabularys.size, &f_rangess_delete_callback); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[source.used].array[j].vocabularys.size, length); + + for (; source.array[source.used].array[j].content.used < length; ++i) { + + source.array[source.used].array[j].content.array[source.array[source.used].array[j].content.used].start = i - 1; + source.array[source.used].array[j].content.array[source.array[source.used].array[j].content.used++].stop = i; + } // for + + for (; source.array[source.used].array[j].delimits.used < length; ++i) { + source.array[source.used].array[j].delimits.array[source.array[source.used].array[j].delimits.used++] = i; + } // for + + for (; source.array[source.used].array[j].variable.used < length; ++i) { + + source.array[source.used].array[j].variable.array[source.array[source.used].array[j].variable.used].start = i - 1; + source.array[source.used].array[j].variable.array[source.array[source.used].array[j].variable.used++].stop = i; + } // for + + for (; source.array[source.used].array[j].vocabularys.used < length; ++i) { + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used].array, &source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used].used, &source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used].size); + + assert_int_equal(status, F_okay); + assert_int_equal(source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used].size, 1); + + // The used property must be set to ensure append works for child elements to be appended. + source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used].used = 1; + source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used].array[0].start = i - 1; + source.array[source.used].array[j].vocabularys.array[source.array[source.used].array[j].vocabularys.used++].array[0].stop = i; + } // for + } // for + + source.array[source.used].used = length_inner; + } // for + } + + { + const f_status_t status = f_iki_ekiss_append_all(source, &destination); + + assert_int_equal(status, F_okay); + assert_int_equal(destination.used, source.used); + + for (f_number_unsigned_t k = 0; k < length_outer; ++k) { + + for (f_number_unsigned_t j = 0; j < length_inner; ++j) { + + assert_int_equal(destination.array[k].array[j].content.used, source.array[k].array[j].content.used); + assert_int_equal(destination.array[k].array[j].delimits.used, source.array[k].array[j].delimits.used); + assert_int_equal(destination.array[k].array[j].variable.used, source.array[k].array[j].variable.used); + assert_int_equal(destination.array[k].array[j].vocabularys.used, source.array[k].array[j].vocabularys.used); + + for (f_number_unsigned_t i = 0; i < length; ++i) { + + assert_int_equal(destination.array[k].array[j].content.array[i].start, source.array[k].array[j].content.array[i].start); + assert_int_equal(destination.array[k].array[j].content.array[i].stop, source.array[k].array[j].content.array[i].stop); + + assert_int_equal(destination.array[k].array[j].delimits.array[i], source.array[k].array[j].delimits.array[i]); + + assert_int_equal(destination.array[k].array[j].variable.array[i].start, source.array[k].array[j].variable.array[i].start); + assert_int_equal(destination.array[k].array[j].variable.array[i].stop, source.array[k].array[j].variable.array[i].stop); + + assert_int_equal(destination.array[k].array[j].vocabularys.array[i].used, 1); + + assert_int_equal(destination.array[k].array[j].vocabularys.array[i].array[0].start, source.array[k].array[j].vocabularys.array[i].array[0].start); + assert_int_equal(destination.array[k].array[j].vocabularys.array[i].array[0].stop, source.array[k].array[j].vocabularys.array[i].array[0].stop); + } // for + } // for + } // for + } + + for (f_number_unsigned_t j = 0; j < source.used; ++j) { + + for (f_number_unsigned_t i = 0; i < source.array[j].used; ++i) { + + free((void *) source.array[j].array[i].content.array); + free((void *) source.array[j].array[i].delimits.array); + free((void *) source.array[j].array[i].variable.array); + + for (f_number_unsigned_t k = 0; k < source.array[j].array[i].vocabularys.used; ++k) { + free((void *) source.array[j].array[i].vocabularys.array[k].array); + } // for + + free((void *) source.array[j].array[i].vocabularys.array); + } // for + + free((void *) source.array[j].array); + } // for + + for (f_number_unsigned_t j = 0; j < destination.used; ++j) { + + for (f_number_unsigned_t i = 0; i < destination.array[j].used; ++i) { + + free((void *) destination.array[j].array[i].content.array); + free((void *) destination.array[j].array[i].delimits.array); + free((void *) destination.array[j].array[i].variable.array); + + for (f_number_unsigned_t k = 0; k < destination.array[j].array[i].vocabularys.used; ++k) { + free((void *) destination.array[j].array[i].vocabularys.array[k].array); + } // for + + free((void *) destination.array[j].array[i].vocabularys.array); + } // for + + free((void *) destination.array[j].array); + } // for + + free((void *) source.array); + free((void *) destination.array); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_append_all.h b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append_all.h new file mode 100644 index 0000000..c3a16d3 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_append_all.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki_ekiss_append_all_h +#define _TEST__F_iki_ekiss_append_all_h + +/** + * Test that the function returns F_data_not when asked to copy an empty structure. + * + * @see f_iki_ekiss_append_all() + */ +extern void test__f_iki_ekiss_append_all__returns_data_not(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_iki_ekiss_append_all() + */ +extern void test__f_iki_ekiss_append_all__parameter_checking(void **state); + +/** + * Test that the function works. + * + * @see f_iki_ekiss_append_all() + */ +extern void test__f_iki_ekiss_append_all__works(void **state); + +#endif // _TEST__F_iki_ekiss_append_all_h diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_delete_callback.c b/level_0/f_iki/tests/unit/c/test-iki-ekiss_delete_callback.c new file mode 100644 index 0000000..c305149 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_delete_callback.c @@ -0,0 +1,173 @@ +#include "test-iki.h" +#include "test-iki-ekiss_delete_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekiss_delete_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_range_t base = macro_f_range_t_initialize_1(1, 0); + f_range_t base_array[] = { base }; + f_ranges_t bases = { .array = base_array, .used = 0, .size = 1 }; + + f_ranges_t content = bases; + f_number_unsigned_t delimit_array[] = { 0 }; + f_number_unsigneds_t delimits = { .array = delimit_array, .used = 0, .size = 1 }; + f_ranges_t variable = bases; + f_ranges_t vocabulary_array[] = { bases }; + f_rangess_t vocabularys = { .array = vocabulary_array, .used = 0, .size = 1 }; + + f_iki_eki_t data = { .content = content, .delimits = delimits, .variable = variable, .vocabularys = vocabularys }; + f_iki_eki_t data_array[] = { data }; + f_iki_ekis_t datas = { .array = data_array, .used = 1, .size = 1 }; + f_iki_ekis_t datas_array[] = { datas }; + + { + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_arrays_resize, true); + will_return(__wrap_f_memory_arrays_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, false); + will_return(__wrap_f_memory_array_resize, F_okay); + + will_return(__wrap_f_memory_arrays_resize, false); + will_return(__wrap_f_memory_arrays_resize, F_okay); + + will_return(__wrap_f_memory_array_resize, true); + will_return(__wrap_f_memory_array_resize, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_iki_ekiss_delete_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_iki_ekiss_t datass = f_iki_ekiss_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_iki_ekis_t), (void **) &datass.array, &datass.used, &datass.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_iki_eki_t), (void **) &datass.array[0].array, &datass.array[0].used, &datass.array[0].size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datass.array[0].array[0].content.array, &datass.array[0].array[0].content.used, &datass.array[0].array[0].content.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_number_unsigned_t), (void **) &datass.array[0].array[0].delimits.array, &datass.array[0].array[0].delimits.used, &datass.array[0].array[0].delimits.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datass.array[0].array[0].variable.array, &datass.array[0].array[0].variable.used, &datass.array[0].array[0].variable.size); + assert_int_equal(status, F_okay); + + status = f_memory_arrays_resize(1, sizeof(f_ranges_t), (void **) &datass.array[0].array[0].vocabularys.array, &datass.array[0].array[0].vocabularys.used, &datass.array[0].array[0].vocabularys.size, &f_rangess_delete_callback); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datass.array[0].array[0].vocabularys.array[0].array, &datass.array[0].array[0].vocabularys.array[0].used, &datass.array[0].array[0].vocabularys.array[0].size); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_iki_ekiss_delete_callback(0, length, (void *) datass.array); + + assert_int_equal(status, F_okay); + assert_int_equal(datass.array[0].size, 0); + } + + free((void *) datass.array); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_delete_callback.h b/level_0/f_iki/tests/unit/c/test-iki-ekiss_delete_callback.h new file mode 100644 index 0000000..cc51088 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_delete_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki__ekiss_delete_callback +#define _TEST__F_iki__ekiss_delete_callback + +/** + * Test that the function fails. + * + * @see f_iki_ekiss_delete_callback() + */ +extern void test__f_iki_ekiss_delete_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_iki_ekiss_delete_callback() + */ +extern void test__f_iki_ekiss_delete_callback__works(void **state); + +#endif // _TEST__F_iki__ekiss_delete_callback diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_destroy_callback.c b/level_0/f_iki/tests/unit/c/test-iki-ekiss_destroy_callback.c new file mode 100644 index 0000000..9ae2110 --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_destroy_callback.c @@ -0,0 +1,173 @@ +#include "test-iki.h" +#include "test-iki-ekiss_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_iki_ekiss_destroy_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_range_t base = macro_f_range_t_initialize_1(1, 0); + f_range_t base_array[] = { base }; + f_ranges_t bases = { .array = base_array, .used = 0, .size = 1 }; + + f_ranges_t content = bases; + f_number_unsigned_t delimit_array[] = { 0 }; + f_number_unsigneds_t delimits = { .array = delimit_array, .used = 0, .size = 1 }; + f_ranges_t variable = bases; + f_ranges_t vocabulary_array[] = { bases }; + f_rangess_t vocabularys = { .array = vocabulary_array, .used = 0, .size = 1 }; + + f_iki_eki_t data = { .content = content, .delimits = delimits, .variable = variable, .vocabularys = vocabularys }; + f_iki_eki_t data_array[] = { data }; + f_iki_ekis_t datas = { .array = data_array, .used = 1, .size = 1 }; + f_iki_ekis_t datas_array[] = { datas }; + + { + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_arrays_adjust, true); + will_return(__wrap_f_memory_arrays_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + datas_array[0].size = 1; + datas_array[0].array[0].content = content; + datas_array[0].array[0].delimits = delimits; + datas_array[0].array[0].variable = variable; + datas_array[0].array[0].vocabularys = vocabularys; + + { + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, false); + will_return(__wrap_f_memory_array_adjust, F_okay); + + will_return(__wrap_f_memory_arrays_adjust, false); + will_return(__wrap_f_memory_arrays_adjust, F_okay); + + will_return(__wrap_f_memory_array_adjust, true); + will_return(__wrap_f_memory_array_adjust, F_status_set_error(F_failure)); + + const f_status_t status = f_iki_ekiss_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_iki_ekiss_destroy_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_iki_ekiss_t datass = f_iki_ekiss_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_iki_ekis_t), (void **) &datass.array, &datass.used, &datass.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_iki_eki_t), (void **) &datass.array[0].array, &datass.array[0].used, &datass.array[0].size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datass.array[0].array[0].content.array, &datass.array[0].array[0].content.used, &datass.array[0].array[0].content.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_number_unsigned_t), (void **) &datass.array[0].array[0].delimits.array, &datass.array[0].array[0].delimits.used, &datass.array[0].array[0].delimits.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datass.array[0].array[0].variable.array, &datass.array[0].array[0].variable.used, &datass.array[0].array[0].variable.size); + assert_int_equal(status, F_okay); + + status = f_memory_arrays_resize(1, sizeof(f_ranges_t), (void **) &datass.array[0].array[0].vocabularys.array, &datass.array[0].array[0].vocabularys.used, &datass.array[0].array[0].vocabularys.size, &f_rangess_delete_callback); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_range_t), (void **) &datass.array[0].array[0].vocabularys.array[0].array, &datass.array[0].array[0].vocabularys.array[0].used, &datass.array[0].array[0].vocabularys.array[0].size); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_iki_ekiss_destroy_callback(0, length, (void *) datass.array); + + assert_int_equal(status, F_okay); + assert_int_equal(datass.array[0].size, 0); + } + + free((void *) datass.array); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_iki/tests/unit/c/test-iki-ekiss_destroy_callback.h b/level_0/f_iki/tests/unit/c/test-iki-ekiss_destroy_callback.h new file mode 100644 index 0000000..4d1d3df --- /dev/null +++ b/level_0/f_iki/tests/unit/c/test-iki-ekiss_destroy_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the array types in the type project. + */ +#ifndef _TEST__F_iki__ekiss_destroy_callback +#define _TEST__F_iki__ekiss_destroy_callback + +/** + * Test that the function fails. + * + * @see f_iki_ekiss_destroy_callback() + */ +extern void test__f_iki_ekiss_destroy_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_iki_ekiss_destroy_callback() + */ +extern void test__f_iki_ekiss_destroy_callback__works(void **state); + +#endif // _TEST__F_iki__ekiss_destroy_callback diff --git a/level_0/f_iki/tests/unit/c/test-iki-read.c b/level_0/f_iki/tests/unit/c/test-iki-read.c index 393d497..3d288f5 100644 --- a/level_0/f_iki/tests/unit/c/test-iki-read.c +++ b/level_0/f_iki/tests/unit/c/test-iki-read.c @@ -89,6 +89,8 @@ void test__f_iki_read__works(void **state) { f_string_static_t empty = macro_f_string_static_t_initialize_1(f_string_empty_s.string, f_string_empty_s.size, f_string_empty_s.used); f_string_static_t ascii_a = macro_f_string_static_t_initialize_1(f_string_ascii_a_s.string, f_string_ascii_a_s.size, f_string_ascii_a_s.used); + #define _inline_macro_total_rows 34 + f_string_static_t buffers[] = { empty, ascii_a, @@ -114,6 +116,16 @@ void test__f_iki_read__works(void **state) { macro_f_string_static_t_initialize_1("url:\"https://localhost/fake-0.7.0.tar.gz?query=xx¶meter=yyy%20\" end.", 0, 72), macro_f_string_static_t_initialize_1("url:`https://localhost/fake-0.7.0.tar.gz?query=xx¶meter=yyy%20` end.", 0, 72), macro_f_string_static_t_initialize_1("iki:'\"`' iki:'`\"'", 0, 17), + macro_f_string_static_t_initialize_1("[iki]:\"one\"", 0, 11), + macro_f_string_static_t_initialize_1("[iki]\\:\"none\"", 0, 13), + macro_f_string_static_t_initialize_1("[eki:iki]:\"one\"", 0, 15), + macro_f_string_static_t_initialize_1("[[iki]]:\"none\"", 0, 14), + macro_f_string_static_t_initialize_1("[[iki]]:`none`", 0, 14), + macro_f_string_static_t_initialize_1("[iki]:`one`", 0, 11), + macro_f_string_static_t_initialize_1("[iki]\\:'not'", 0, 12), + macro_f_string_static_t_initialize_1("iki\\:'not'", 0, 10), + macro_f_string_static_t_initialize_1("an:iki\\:'not'", 0, 13), + macro_f_string_static_t_initialize_1("an:iki:'is!'", 0, 12), }; const f_number_unsigned_t matches[] = { @@ -141,6 +153,16 @@ void test__f_iki_read__works(void **state) { 1, 1, 2, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, }; const f_status_t statuss[] = { @@ -168,9 +190,19 @@ void test__f_iki_read__works(void **state) { F_okay, F_okay, F_okay, + F_okay_stop, + F_data_not_stop, + F_data_not_stop, + F_data_not_stop, + F_data_not_stop, + F_okay_stop, + F_data_not_stop, + F_data_not_stop, + F_data_not_stop, + F_okay_stop, }; - const f_range_t variables[][24] = { + const f_range_t variables[][_inline_macro_total_rows] = { { f_range_t_initialize, f_range_t_initialize }, { f_range_t_initialize, f_range_t_initialize }, { macro_f_range_t_initialize_1(0, 8), f_range_t_initialize }, @@ -195,9 +227,19 @@ void test__f_iki_read__works(void **state) { { macro_f_range_t_initialize_1(0, 66), f_range_t_initialize }, { macro_f_range_t_initialize_1(0, 66), f_range_t_initialize }, { macro_f_range_t_initialize_1(0, 7), macro_f_range_t_initialize_1(9, 16) }, + { macro_f_range_t_initialize_1(0, 10), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(0, 10), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(3, 11), f_range_t_initialize }, }; - const f_range_t vocabularys[][24] = { + const f_range_t vocabularys[][_inline_macro_total_rows] = { { f_range_t_initialize, f_range_t_initialize }, { f_range_t_initialize, f_range_t_initialize }, { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, @@ -222,9 +264,19 @@ void test__f_iki_read__works(void **state) { { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, { macro_f_range_t_initialize_1(0, 2), f_range_t_initialize }, { macro_f_range_t_initialize_1(0, 2), macro_f_range_t_initialize_1(9, 11) }, + { macro_f_range_t_initialize_1(1, 3), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(1, 3), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(3, 5), f_range_t_initialize }, }; - const f_range_t contents[][24] = { + const f_range_t contents[][_inline_macro_total_rows] = { { f_range_t_initialize, f_range_t_initialize }, { f_range_t_initialize, f_range_t_initialize }, { macro_f_range_t_initialize_1(5, 7), f_range_t_initialize }, @@ -249,9 +301,19 @@ void test__f_iki_read__works(void **state) { { macro_f_range_t_initialize_1(5, 65), f_range_t_initialize }, { macro_f_range_t_initialize_1(5, 65), f_range_t_initialize }, { macro_f_range_t_initialize_1(5, 6), macro_f_range_t_initialize_1(14, 15) }, + { macro_f_range_t_initialize_1(7, 9), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(7, 9), f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { f_range_t_initialize, f_range_t_initialize }, + { macro_f_range_t_initialize_1(8, 10), f_range_t_initialize }, }; - for (uint8_t i = 0; i < 24; ++i) { + for (uint8_t i = 0; i < _inline_macro_total_rows; ++i) { f_range_t range = macro_f_range_t_initialize_2(buffers[i].used); f_iki_data_t iki = f_iki_data_t_initialize; @@ -297,6 +359,8 @@ void test__f_iki_read__works(void **state) { iki.content.used = 0; iki.delimits.used = 0; } // for + + #undef _inline_macro_total_rows } #ifdef __cplusplus diff --git a/level_0/f_iki/tests/unit/c/test-iki.c b/level_0/f_iki/tests/unit/c/test-iki.c index f032372..fefd70e 100644 --- a/level_0/f_iki/tests/unit/c/test-iki.c +++ b/level_0/f_iki/tests/unit/c/test-iki.c @@ -48,6 +48,30 @@ int main(void) { cmocka_unit_test(test__f_iki_datass_append_all__works), cmocka_unit_test(test__f_iki_datass_append_all__returns_data_not), + cmocka_unit_test(test__f_iki_eki_read__returns_data_not), + cmocka_unit_test(test__f_iki_eki_read__returns_data_not_eos), + cmocka_unit_test(test__f_iki_eki_read__returns_data_not_stop), + cmocka_unit_test(test__f_iki_eki_read__works), + + cmocka_unit_test(test__f_iki_ekis_delete_callback__fails), + cmocka_unit_test(test__f_iki_ekis_destroy_callback__fails), + cmocka_unit_test(test__f_iki_ekiss_destroy_callback__fails), + cmocka_unit_test(test__f_iki_ekiss_delete_callback__fails), + + cmocka_unit_test(test__f_iki_ekis_delete_callback__works), + cmocka_unit_test(test__f_iki_ekis_destroy_callback__works), + cmocka_unit_test(test__f_iki_ekiss_delete_callback__works), + cmocka_unit_test(test__f_iki_ekiss_destroy_callback__works), + + cmocka_unit_test(test__f_iki_ekis_append__works), + cmocka_unit_test(test__f_iki_ekis_append_all__works), + cmocka_unit_test(test__f_iki_ekis_append_all__returns_data_not), + + cmocka_unit_test(test__f_iki_ekiss_append__works), + cmocka_unit_test(test__f_iki_ekiss_append__returns_data_not), + cmocka_unit_test(test__f_iki_ekiss_append_all__works), + cmocka_unit_test(test__f_iki_ekiss_append_all__returns_data_not), + cmocka_unit_test(test__f_iki_object_is__returns_data_not), cmocka_unit_test(test__f_iki_object_is__returns_false), cmocka_unit_test(test__f_iki_object_is__returns_true), @@ -78,6 +102,19 @@ int main(void) { cmocka_unit_test(test__f_iki_datass_append__parameter_checking), cmocka_unit_test(test__f_iki_datass_append_all__parameter_checking), + // f_iki_ekis_destroy_callback() doesn't use parameter checking. + // f_iki_ekis_delete_callback() doesn't use parameter checking. + // f_iki_ekiss_destroy_callback() doesn't use parameter checking. + // f_iki_ekiss_delete_callback() doesn't use parameter checking. + + cmocka_unit_test(test__f_iki_eki_read__parameter_checking), + + cmocka_unit_test(test__f_iki_ekis_append__parameter_checking), + cmocka_unit_test(test__f_iki_ekis_append_all__parameter_checking), + + cmocka_unit_test(test__f_iki_ekiss_append__parameter_checking), + cmocka_unit_test(test__f_iki_ekiss_append_all__parameter_checking), + // f_iki_object_is() doesn't use parameter checking. // f_iki_object_partial_is() doesn't use parameter checking. diff --git a/level_0/f_iki/tests/unit/c/test-iki.h b/level_0/f_iki/tests/unit/c/test-iki.h index 24c1e1b..d60a527 100644 --- a/level_0/f_iki/tests/unit/c/test-iki.h +++ b/level_0/f_iki/tests/unit/c/test-iki.h @@ -36,6 +36,15 @@ #include "test-iki-datass_append_all.h" #include "test-iki-datass_delete_callback.h" #include "test-iki-datass_destroy_callback.h" +#include "test-iki-eki_read.h" +#include "test-iki-ekis_append.h" +#include "test-iki-ekis_append_all.h" +#include "test-iki-ekis_delete_callback.h" +#include "test-iki-ekis_destroy_callback.h" +#include "test-iki-ekiss_append.h" +#include "test-iki-ekiss_append_all.h" +#include "test-iki-ekiss_delete_callback.h" +#include "test-iki-ekiss_destroy_callback.h" #include "test-iki-object_is.h" #include "test-iki-object_partial_is.h" #include "test-iki-read.h"