From: Kevin Day Date: Wed, 4 Oct 2023 02:00:19 +0000 (-0500) Subject: Feature: Add f_abstruse project. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=5308fa7db61a978e52fc848155fecfc467ed4651;p=fll Feature: Add f_abstruse project. This is the initial design and may be subject to significant change as I begin to use it more. The idea here is to provide a type that can act as a catch all for any sort of header of any specific type. I use standard types and provide void pointer types for everything else. I have some concerns about supporting void pointer types due to the special case of how to handle this allocation actions. I have decided to withhold the "append" and similar standard functions for now until I get a better grasp on how this should be used. A union is used to use the same memory space at the cost of the largest size. A dynamic string is likely the most common case. The resize and similar functions provide warnings that the caller needs to be careful about allocation and de-allocation. This poses extra security concerns for when callers of these functions do not properly or safely handle the data. I intend to use this in the FSS Simple Packet processing code, such as writing (building) the Simple Packet string. --- diff --git a/build/disable/about.txt b/build/disable/about.txt index da3828d..47ebd9b 100644 --- a/build/disable/about.txt +++ b/build/disable/about.txt @@ -33,11 +33,11 @@ Consider the following example using the fake dependencies for the stand alone b # echo $(cat level_3/fake/data/build/dependencies) Which prints: - # fss-0000 f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_parse f_path f_pipe f_print f_rip f_signal f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fll_error fll_execute fll_file fll_fss fll_print fll_program + # fss-0000 f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_parse f_path f_pipe f_print f_rip f_signal f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fll_error fll_execute fll_file fll_fss fll_print fll_program From this list, build the level_0: -# for i in f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_parse f_path f_pipe f_print f_rip f_signal f_thread f_time ; do if [[ -f build/disable/level_0/$i.h ]] ; then echo >> build/stand_alone/fake.config.h && cat build/disable/level_0/$i.h >> build/stand_alone/fake.config.h ; fi ; done +# for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_parse f_path f_pipe f_print f_rip f_signal f_thread f_time ; do if [[ -f build/disable/level_0/$i.h ]] ; then echo >> build/stand_alone/fake.config.h && cat build/disable/level_0/$i.h >> build/stand_alone/fake.config.h ; fi ; done From the list, build the level_1: diff --git a/build/level_0/settings b/build/level_0/settings index 6208ea8..745f3c5 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -33,6 +33,7 @@ build_language c build_libraries -lc -lcap +build_sources_library abstruse.c abstruse/abstruse.c abstruse/map.c abstruse/private-abstruse.c build_sources_library account.c private-account.c account/accounts.c build_sources_library capability.c build_sources_library color.c private-color.c color/common.c @@ -83,6 +84,7 @@ build_sources_library utf/private-dynamics.c utf/private-maps.c utf/private-map_ build_sources_library-thread thread.c thread/attribute.c thread/barrier.c thread/barrier_attribute.c thread/condition.c thread/condition_attribute.c thread/id.c thread/key.c thread/lock.c thread/lock_attribute.c thread/mutex.c thread/mutex_attribute.c thread/once.c thread/semaphore.c thread/set.c thread/spin.c +build_sources_headers abstruse.h abstruse/abstruse.h abstruse/enum.h abstruse/map.h abstruse/type.h build_sources_headers account.h account/accounts.h account/common.h build_sources_headers capability.h capability/common.h build_sources_headers color.h color/common.h diff --git a/build/monolithic/settings b/build/monolithic/settings index 7eaf6ba..bd861a1 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -33,6 +33,7 @@ build_language c build_libraries -lc -lcap +build_sources_library level_0/abstruse.c level_0/abstruse/abstruse.c level_0/abstruse/map.c level_0/abstruse/private-abstruse.c build_sources_library level_0/account.c level_0/private-account.c level_0/account/accounts.c build_sources_library level_0/capability.c build_sources_library level_0/color.c level_0/private-color.c level_0/color/common.c @@ -104,6 +105,7 @@ build_sources_library level_2/program.c level_2/program/common.c level_2/program build_sources_library-thread level_0/thread.c level_0/thread/attribute.c level_0/thread/barrier.c level_0/thread/barrier_attribute.c level_0/thread/condition.c level_0/thread/condition_attribute.c level_0/thread/id.c level_0/thread/key.c level_0/thread/lock.c level_0/thread/lock_attribute.c level_0/thread/mutex.c level_0/thread/mutex_attribute.c level_0/thread/once.c level_0/thread/semaphore.c level_0/thread/set.c level_0/thread/spin.c +build_sources_headers level_0/abstruse.h level_0/abstruse/abstruse.h level_0/abstruse/enum.h level_0/abstruse/map.h level_0/abstruse/type.h build_sources_headers level_0/account.h level_0/account/accounts.h level_0/account/common.h build_sources_headers level_0/capability.h level_0/capability/common.h build_sources_headers level_0/color.h level_0/color/common.h diff --git a/build/scripts/bootstrap-example.sh b/build/scripts/bootstrap-example.sh index d2b36e0..07e1a57 100644 --- a/build/scripts/bootstrap-example.sh +++ b/build/scripts/bootstrap-example.sh @@ -130,7 +130,7 @@ if [[ ${1} == "individual" ]] ; then ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -i if [[ ${?} -eq 0 ]] ; then - for i in f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_status_string f_serialize f_signal f_socket f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do + for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_status_string f_serialize f_signal f_socket f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do echo && echo "Processing ${i}." && cd package/individual/${i}-${version}/ && diff --git a/build/stand_alone/byte_dump.config.h b/build/stand_alone/byte_dump.config.h index 5c97d92..979334d 100644 --- a/build/stand_alone/byte_dump.config.h +++ b/build/stand_alone/byte_dump.config.h @@ -8,7 +8,7 @@ // // Example: // echo > /tmp/all.txt -// for i in f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done +// for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done // for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done // for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done // sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt diff --git a/build/stand_alone/fake.config.h b/build/stand_alone/fake.config.h index fe96292..848e7c2 100644 --- a/build/stand_alone/fake.config.h +++ b/build/stand_alone/fake.config.h @@ -8,7 +8,7 @@ // // Example: // echo > /tmp/all.txt -// for i in f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done +// for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done // for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done // for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done // sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt diff --git a/build/stand_alone/fake.settings b/build/stand_alone/fake.settings index 09a0f9e..40876f0 100644 --- a/build/stand_alone/fake.settings +++ b/build/stand_alone/fake.settings @@ -31,6 +31,7 @@ build_language c build_libraries -lc -lcap +build_sources_program fll/level_0/abstruse.c fll/level_0/abstruse/abstruse.c fll/level_0/abstruse/map.c fll/level_0/abstruse/private-abstruse.c build_sources_program fll/level_0/account.c fll/level_0/private-account.c fll/level_0/account/accounts.c build_sources_program fll/level_0/capability.c build_sources_program fll/level_0/color.c fll/level_0/private-color.c fll/level_0/color/common.c diff --git a/build/stand_alone/firewall.config.h b/build/stand_alone/firewall.config.h index 5c97d92..979334d 100644 --- a/build/stand_alone/firewall.config.h +++ b/build/stand_alone/firewall.config.h @@ -8,7 +8,7 @@ // // Example: // echo > /tmp/all.txt -// for i in f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done +// for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done // for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done // for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done // sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt diff --git a/build/stand_alone/utf8.config.h b/build/stand_alone/utf8.config.h index 5c97d92..979334d 100644 --- a/build/stand_alone/utf8.config.h +++ b/build/stand_alone/utf8.config.h @@ -8,7 +8,7 @@ // // Example: // echo > /tmp/all.txt -// for i in f_type f_status f_memory f_type_array f_string f_utf f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done +// for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_rip f_signal f_socket f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done // for i in fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done // for i in fll_error fll_execute fll_file fll_fss fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done // sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt diff --git a/level_0/f_abstruse/c/abstruse.c b/level_0/f_abstruse/c/abstruse.c new file mode 100644 index 0000000..6277590 --- /dev/null +++ b/level_0/f_abstruse/c/abstruse.c @@ -0,0 +1,9 @@ +#include "abstruse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/c/abstruse.h b/level_0/f_abstruse/c/abstruse.h new file mode 100644 index 0000000..b7b274f --- /dev/null +++ b/level_0/f_abstruse/c/abstruse.h @@ -0,0 +1,50 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides abstruse type definitions. + * + * An abstruse type is intended to act as a variable that can be passed and then later cast to the appropriate type. + * This produces behavior similar to an object-oriented design in a non-object-oriented language like C. + * + * This is not intended to handle all possible types but instead handle a set of common and core FLL types. + */ +#ifndef _F_abstruse_h +#define _F_abstruse_h + +// Include pre-requirements. +#ifndef _GNU_SOURCE + #define _GNU_SOURCE +#endif // _GNU_SOURCE + +// Libc includes. +#include +#include +#include +#include + +// FLL-0 includes. +#include +#include +#include +#include +#include + +// FLL-0 type includes. +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_abstruse_h diff --git a/level_0/f_abstruse/c/abstruse/abstruse.c b/level_0/f_abstruse/c/abstruse/abstruse.c new file mode 100644 index 0000000..0587655 --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/abstruse.c @@ -0,0 +1,102 @@ +#include "../abstruse.h" +#include "private-abstruse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_abstruses_delete_callback_ + f_status_t f_abstruses_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruse_t * const array = (f_abstruse_t *) void_array; + f_status_t status = F_okay; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + status = private_f_abstruses_delete_switch(&array[i]); + if (F_status_is_error(status)) return status; + } // for + } + + return F_okay; + } +#endif // _di_f_abstruses_delete_callback_ + +#ifndef _di_f_abstruses_destroy_callback_ + f_status_t f_abstruses_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruse_t * const array = (f_abstruse_t *) void_array; + f_status_t status = F_okay; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + status = private_f_abstruses_destroy_switch(&array[i]); + if (F_status_is_error(status)) return status; + } // for + } + + return F_okay; + } +#endif // _di_f_abstruses_destroy_callback_ + +#ifndef _di_f_abstrusess_delete_callback_ + f_status_t f_abstrusess_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruses_t * const array = (f_abstruses_t *) void_array; + f_status_t status = F_okay; + f_number_unsigned_t i = start; + f_number_unsigned_t j = 0; + + for (; i < stop; ++i) { + + if (array[i].size) { + for (j = 0; j < array[i].size; ++j) { + + status = private_f_abstruses_delete_switch(&array[i].array[j]); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_array_resize(0, sizeof(f_abstruse_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_abstrusess_delete_callback_ + +#ifndef _di_f_abstrusess_destroy_callback_ + f_status_t f_abstrusess_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruses_t * const array = (f_abstruses_t *) void_array; + f_status_t status = F_okay; + f_number_unsigned_t i = start; + f_number_unsigned_t j = 0; + + for (; i < stop; ++i) { + + if (array[i].size) { + for (j = 0; j < array[i].size; ++j) { + + status = private_f_abstruses_destroy_switch(&array[i].array[j]); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_array_adjust(0, sizeof(f_abstruse_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_abstrusess_destroy_callback_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/c/abstruse/abstruse.h b/level_0/f_abstruse/c/abstruse/abstruse.h new file mode 100644 index 0000000..4dcfd78 --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/abstruse.h @@ -0,0 +1,309 @@ +/** + * FLL - Level 0 + * + * Project: Abstuse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Defines abstruse data. + * + * This is auto-included by abstruse.h and should not need to be explicitly included. + */ +#ifndef _F_type_abstruse_abstruse_h +#define _F_type_abstruse_abstruse_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An abstruse a structure that represents different possible types. + * + * The type variable is used to designate the type within the f_abstruse_type_t union in use. + * + * De-allocation must be performed when swapping between types when the old type contains dynamically allocated data. + * + * It may be a good idea to use statically allocated data or dynamically allocated data managed elsewhere with this to avoid potential design complications with de-allocation. + * + * properties: + * - type: The type in which the "is" property is, represented by f_abstruse_type_e. + * - is: The value, where "is" is chosen as a variable name so that when type is f_abstruse_type_unsigned_e, then accessing this would be done via "is.a_unsigned". + */ +#ifndef _di_f_abstruse_t_ + typedef struct { + uint8_t type; + + f_abstruse_type_t is; + } f_abstruse_t; + + #define f_abstruse_t_initialize { 0, f_abstruse_type_t_initialize } + + #define macro_f_abstruse_t_initialize_1(type, is) { type, is } + #define macro_f_abstruse_t_initialize_2(type) { type, f_abstruse_type_t_initialize } + + #define macro_f_abstruse_t_clear(abstruse) \ + abstruse.type = 0; \ + macro_f_abstruse_type_t_clear(abstruse.is); +#endif // _di_f_abstruse_t_ + +/** + * An array of f_abstruse_t. + * + * Properties: + * - array: The array of f_abstruse_t. + * - size: Total amount of allocated space. + * - used: Total number of allocated spaces used. + */ +#ifndef _di_f_abstruses_t_ + typedef struct { + f_abstruse_t *array; + + f_number_unsigned_t size; + f_number_unsigned_t used; + } f_abstruses_t; + + #define f_abstruses_t_initialize { 0, 0, 0 } + + #define macro_f_abstruses_t_initialize_1(array, size, used) { array, size, used } + #define macro_f_abstruses_t_initialize_2(array, length) { array, length, length } +#endif // _di_f_abstruses_t_ + +/** + * This holds an array of f_abstruses_t. + * + * Properties: + * - array: The array of f_abstruse_t arrays. + * - size: Total amount of allocated space. + * - used: Total number of allocated spaces used. + */ +#ifndef _di_f_abstrusess_t_ + typedef struct { + f_abstruses_t *array; + + f_number_unsigned_t size; + f_number_unsigned_t used; + } f_abstrusess_t; + + #define f_abstrusess_t_initialize { 0, 0, 0 } + + #define macro_f_abstrusess_t_initialize_1(array, size, used) { array, size, used } + #define macro_f_abstrusess_t_initialize_2(array, length) { array, length, length } +#endif // _di_f_abstrusess_t_ + +/** + * A callback intended to be passed to f_memory_arrays_resize() for an f_abstruses_t structure. + * + * This callback only de-allocates the following: + * - a_u8s + * - a_u16s + * - a_u32s + * - a_u64s + * - a_i8s + * - a_i16s + * - a_i32s + * - a_i64s + * - a_signeds + * - a_unsigneds + * - a_static (as an f_string_dynamic_t, if size > 0). + * - a_statics (as an f_string_dynamics_t, if size > 0). + * - a_map + * - a_maps + * - a_map_multi + * - a_map_multis + * - a_quantitys + * - a_ranges + * - a_triple + * - a_triples + * + * For all other types, the caller must handle de-allocation to avoid memory leaks. + * Provide and use a custom callback if special handling of deallocation is needed. + * + * 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, including when nothing done due to no match against the type. + * + * 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_abstruses_delete_callback_ + extern f_status_t f_abstruses_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstruses_delete_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_adjust() for an f_abstruses_t structure. + * + * This callback only de-allocates the following: + * - a_u8s + * - a_u16s + * - a_u32s + * - a_u64s + * - a_i8s + * - a_i16s + * - a_i32s + * - a_i64s + * - a_signeds + * - a_unsigneds + * - a_static (as an f_string_dynamic_t, if size > 0). + * - a_statics (as an f_string_dynamics_t, if size > 0). + * - a_map + * - a_maps + * - a_map_multi + * - a_map_multis + * - a_quantitys + * - a_ranges + * - a_triple + * - a_triples + * + * For all other types, the caller must handle de-allocation to avoid memory leaks. + * Provide and use a custom callback if special handling of deallocation is needed. + * + * 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, including when nothing done due to no match against the type. + * + * 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_abstruses_destroy_callback_ + extern f_status_t f_abstruses_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstruses_destroy_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_resize() for an f_abstrusess_t structure. + * + * This callback only de-allocates the following: + * - a_u8s + * - a_u16s + * - a_u32s + * - a_u64s + * - a_i8s + * - a_i16s + * - a_i32s + * - a_i64s + * - a_signeds + * - a_unsigneds + * - a_static (as an f_string_dynamic_t, if size > 0). + * - a_statics (as an f_string_dynamics_t, if size > 0). + * - a_map + * - a_maps + * - a_map_multi + * - a_map_multis + * - a_quantitys + * - a_ranges + * - a_triple + * - a_triples + * + * For all other types, the caller must handle de-allocation to avoid memory leaks. + * Provide and use a custom callback if special handling of deallocation is needed. + * + * 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. + * + * 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_abstrusess_delete_callback_ + extern f_status_t f_abstrusess_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstrusess_delete_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_adjust() for an f_abstrusess_t structure. + * + * This callback only de-allocates the following: + * - a_u8s + * - a_u16s + * - a_u32s + * - a_u64s + * - a_i8s + * - a_i16s + * - a_i32s + * - a_i64s + * - a_signeds + * - a_unsigneds + * - a_static (as an f_string_dynamic_t, if size > 0). + * - a_statics (as an f_string_dynamics_t, if size > 0). + * - a_map + * - a_maps + * - a_map_multi + * - a_map_multis + * - a_quantitys + * - a_ranges + * - a_triple + * - a_triples + * + * For all other types, the caller must handle de-allocation to avoid memory leaks. + * Provide and use a custom callback if special handling of deallocation is needed. + * + * 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. + * + * 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_abstrusess_destroy_callback_ + extern f_status_t f_abstrusess_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstrusess_destroy_callback_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_type_abstruse_abstruse_h diff --git a/level_0/f_abstruse/c/abstruse/enum.h b/level_0/f_abstruse/c/abstruse/enum.h new file mode 100644 index 0000000..696d417 --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/enum.h @@ -0,0 +1,117 @@ +/** + * FLL - Level 0 + * + * Project: Type + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Defines abstruse type data. + * + * This is auto-included by abstruse.h and should not need to be explicitly included. + */ +#ifndef _F_type_abstruse_enum_h +#define _F_type_abstruse_enum_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An enumeration representing all standard abstruse union types. + * + * Generally, the types ending in "s" represent an array. + * + * f_abstruse_uint8: Maps to uint8_t. + * f_abstruse_uint8s: Maps to f_uint8s_t. + * f_abstruse_uint16: Maps to uint16_t. + * f_abstruse_uint16s: Maps to f_uint16s_t. + * f_abstruse_uint32: Maps to uint32_t. + * f_abstruse_uint32s: Maps to f_uint32s_t. + * f_abstruse_uint64: Maps to uint64_t. + * f_abstruse_uint64s: Maps to f_uint64s_t. + * f_abstruse_int8: Maps to int8_t. + * f_abstruse_int8s: Maps to f_int8_t. + * f_abstruse_int16: Maps to int16_t. + * f_abstruse_int16s: Maps to f_int16_t. + * f_abstruse_int32: Maps to int32_t. + * f_abstruse_int32s: Maps to f_int32s_t. + * f_abstruse_int64: Maps to int64_t. + * f_abstruse_int64s: Maps to f_int64_t. + * f_abstruse_signed: Maps to f_number_singed_t. + * f_abstruse_signeds: Maps to f_number_singeds_t. + * f_abstruse_unsigned: Maps to f_number_unsinged_t. + * f_abstruse_unsigneds: Maps to f_number_unsingeds_t. + * f_abstruse_char: Maps to f_char_t. + * f_abstruse_string: Maps to f_string_t (also: (f_char_t *)). + * f_abstruse_strings: Maps to (f_string_t *). + * f_abstruse_dynamic: Maps to f_string_dynamic_t (or f_string_static_t). + * f_abstruse_dynamics: Maps to f_string_dynamics_t (or f_string_statics_t). + * f_abstruse_map: Maps to f_string_map_t. + * f_abstruse_maps: Maps to f_string_maps_t. + * f_abstruse_map_multi: Maps to f_string_map_multi_t. + * f_abstruse_map_multis: Maps to f_string_map_multis_t. + * f_abstruse_quantity: Maps to f_string_quantity_t. + * f_abstruse_quantitys: Maps to f_string_quantitys_t. + * f_abstruse_range: Maps to f_string_range_t. + * f_abstruse_ranges: Maps to f_string_ranges_t. + * f_abstruse_triple: Maps to f_string_triple_t. + * f_abstruse_triples: Maps to f_string_triples_t. + * f_abstruse_void: Maps to (void *). + * f_abstruse_voids: Maps to (void **). + * f_abstruse_size: Maps to size_t. + * f_abstruse_sizes: Maps to (size_t *). + * f_abstruse_ssize: Maps to ssize_t. + * f_abstruse_ssizes: Maps to (ssize_t *). + */ +#ifndef _di_f_abstruse_e_ + enum { + f_abstruse_none_e = 0, + f_abstruse_uint8_e, + f_abstruse_uint8s_e, + f_abstruse_uint16_e, + f_abstruse_uint16s_e, + f_abstruse_uint32_e, + f_abstruse_uint32s_e, + f_abstruse_uint64_e, + f_abstruse_uint64s_e, + f_abstruse_int8_e, + f_abstruse_int8s_e, + f_abstruse_int16_e, + f_abstruse_int16s_e, + f_abstruse_int32_e, + f_abstruse_int32s_e, + f_abstruse_int64_e, + f_abstruse_int64s_e, + f_abstruse_signed_e, + f_abstruse_signeds_e, + f_abstruse_unsigned_e, + f_abstruse_unsigneds_e, + f_abstruse_char_e, + f_abstruse_string_e, + f_abstruse_strings_e, + f_abstruse_dynamic_e, + f_abstruse_dynamics_e, + f_abstruse_map_e, + f_abstruse_maps_e, + f_abstruse_map_multi_e, + f_abstruse_map_multis_e, + f_abstruse_quantity_e, + f_abstruse_quantitys_e, + f_abstruse_range_e, + f_abstruse_ranges_e, + f_abstruse_triple_e, + f_abstruse_triples_e, + f_abstruse_void_e, + f_abstruse_voids_e, + f_abstruse_size_e, + f_abstruse_sizes_e, + f_abstruse_ssize_e, + f_abstruse_ssizes_e, + }; +#endif // _di_f_abstruse_e_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_type_abstruse_enum_h diff --git a/level_0/f_abstruse/c/abstruse/map.c b/level_0/f_abstruse/c/abstruse/map.c new file mode 100644 index 0000000..4b5e1a3 --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/map.c @@ -0,0 +1,114 @@ +#include "../abstruse.h" +#include "private-abstruse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_abstruse_maps_delete_callback_ + f_status_t f_abstruse_maps_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruse_map_t * const array = (f_abstruse_map_t *) void_array; + f_status_t status = F_okay; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + status = f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].key.string, &array[i].key.used, &array[i].key.size); + if (F_status_is_error(status)) return status; + + status = private_f_abstruses_delete_switch(&array[i].value); + if (F_status_is_error(status)) return status; + } // for + } + + return F_okay; + } +#endif // _di_f_abstruse_maps_delete_callback_ + +#ifndef _di_f_abstruse_maps_destroy_callback_ + f_status_t f_abstruse_maps_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruse_map_t * const array = (f_abstruse_map_t *) void_array; + f_status_t status = F_okay; + + for (f_number_unsigned_t i = start; i < stop; ++i) { + + status = f_memory_array_adjust(0, sizeof(f_char_t), (void **) &array[i].key.string, &array[i].key.used, &array[i].key.size); + if (F_status_is_error(status)) return status; + + status = private_f_abstruses_destroy_switch(&array[i].value); + if (F_status_is_error(status)) return status; + } // for + } + + return F_okay; + } +#endif // _di_f_abstruse_maps_destroy_callback_ + +#ifndef _di_f_abstruse_mapss_delete_callback_ + f_status_t f_abstruse_mapss_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruse_maps_t * const array = (f_abstruse_maps_t *) void_array; + f_status_t status = F_okay; + f_number_unsigned_t i = start; + f_number_unsigned_t j = 0; + + for (; i < stop; ++i) { + + if (array[i].size) { + for (j = 0; j < array[i].size; ++j) { + + status = f_memory_array_resize(0, sizeof(f_char_t), (void **) &array[i].array[j].key.string, &array[i].array[j].key.used, &array[i].array[j].key.size); + if (F_status_is_error(status)) return status; + + status = private_f_abstruses_delete_switch(&array[i].array[j].value); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_array_resize(0, sizeof(f_abstruse_map_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_abstruse_mapss_delete_callback_ + +#ifndef _di_f_abstruse_mapss_destroy_callback_ + f_status_t f_abstruse_mapss_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const void_array) { + + { + f_abstruse_maps_t * const array = (f_abstruse_maps_t *) void_array; + f_status_t status = F_okay; + f_number_unsigned_t i = start; + f_number_unsigned_t j = 0; + + for (; i < stop; ++i) { + + if (array[i].size) { + for (j = 0; j < array[i].size; ++j) { + + status = f_memory_array_adjust(0, sizeof(f_char_t), (void **) &array[i].array[j].key.string, &array[i].array[j].key.used, &array[i].array[j].key.size); + if (F_status_is_error(status)) return status; + + status = private_f_abstruses_destroy_switch(&array[i].array[j].value); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_array_adjust(0, sizeof(f_abstruse_map_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_abstruse_mapss_destroy_callback_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/c/abstruse/map.h b/level_0/f_abstruse/c/abstruse/map.h new file mode 100644 index 0000000..dce5e8d --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/map.h @@ -0,0 +1,201 @@ +/** + * FLL - Level 0 + * + * Project: Abstuse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Defines abstruse map data. + * + * This is auto-included by abstruse.h and should not need to be explicitly included. + */ +#ifndef _F_type_abstruse_map_h +#define _F_type_abstruse_map_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A map of an abstruse as the value and a string as the key. + * + * properties: + * - key: The string mapping the abstruse. + * - value: The abstruse being mapped by the key. + */ +#ifndef _di_f_abstruse_map_t_ + typedef struct { + f_string_dynamic_t key; + f_abstruse_t value; + } f_abstruse_map_t; + + #define f_abstruse_map_t_initialize { f_string_dynamic_t_initialize, f_abstruse_t_initialize } + + #define macro_f_abstruse_map_t_initialize_1(key, value) { key, value } + + #define macro_f_abstruse_map_t_clear(map) \ + macro_f_string_dynamic_t_clear(map.key); \ + macro_f_abstruse_t_clear(map.value); +#endif // _di_f_abstruse_map_t_ + +/** + * An array of f_abstruse_map_t. + * + * Properties: + * - array: The array of f_abstruse_map_t. + * - size: Total amount of allocated space. + * - used: Total number of allocated spaces used. + */ +#ifndef _di_f_abstruse_maps_t_ + typedef struct { + f_abstruse_map_t *array; + + f_number_unsigned_t size; + f_number_unsigned_t used; + } f_abstruse_maps_t; + + #define f_abstruses_t_initialize { 0, 0, 0 } + + #define macro_f_abstruse_maps_t_initialize_1(array, size, used) { array, size, used } + #define macro_f_abstruse_maps_t_initialize_2(array, length) { array, length, length } +#endif // _di_f_abstruse_maps_t_ + +/** + * This holds an array of f_abstruse_map_maps_t. + * + * Properties: + * - array: The array of f_abstruse_map_t arrays. + * - size: Total amount of allocated space. + * - used: Total number of allocated spaces used. + */ +#ifndef _di_f_abstruse_mapss_t_ + typedef struct { + f_abstruse_maps_t *array; + + f_number_unsigned_t size; + f_number_unsigned_t used; + } f_abstruse_mapss_t; + + #define f_abstruse_mapss_t_initialize { 0, 0, 0 } + + #define macro_f_abstruse_mapss_t_initialize_1(array, size, used) { array, size, used } + #define macro_f_abstruse_mapss_t_initialize_2(array, length) { array, length, length } +#endif // _di_f_abstruse_mapss_t_ + +/** + * A callback intended to be passed to f_memory_arrays_resize() for an f_abstruse_maps_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, including when nothing done due to no match against the type. + * + * 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_abstruse_maps_delete_callback_ + extern f_status_t f_abstruse_maps_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstruse_maps_delete_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_adjust() for an f_abstruse_maps_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, including when nothing done due to no match against the type. + * + * 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_abstruse_maps_destroy_callback_ + extern f_status_t f_abstruse_maps_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstruse_maps_destroy_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_resize() for an f_abstruse_mapss_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. + * + * 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_abstruse_mapss_delete_callback_ + extern f_status_t f_abstruse_mapss_delete_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstruse_mapss_delete_callback_ + +/** + * A callback intended to be passed to f_memory_arrays_adjust() for an f_abstruse_mapss_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. + * + * 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_abstruse_mapss_destroy_callback_ + extern f_status_t f_abstruse_mapss_destroy_callback(const f_number_unsigned_t start, const f_number_unsigned_t stop, void * const array); +#endif // _di_f_abstruse_mapss_destroy_callback_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_type_abstruse_map_h diff --git a/level_0/f_abstruse/c/abstruse/private-abstruse.c b/level_0/f_abstruse/c/abstruse/private-abstruse.c new file mode 100644 index 0000000..7753f1b --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/private-abstruse.c @@ -0,0 +1,346 @@ +#include "../abstruse.h" +#include "private-abstruse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_abstruses_delete_callback_) || !defined(_di_f_abstrusess_delete_callback_) || !defined(_di_f_abstruse_maps_delete_callback_) || !defined(_di_f_abstruse_mapss_delete_callback_) + f_status_t private_f_abstruses_delete_switch(f_abstruse_t * const abstruse) { + + switch (abstruse->type) { + case f_abstruse_uint8_e: + if (abstruse->is.a_u8s.size) { + return f_memory_array_resize(0, sizeof(uint8_t), (void **) &abstruse->is.a_u8s.array, &abstruse->is.a_u8s.used, &abstruse->is.a_u8s.size); + } + + break; + + case f_abstruse_uint16s_e: + if (abstruse->is.a_u16s.size) { + return f_memory_array_resize(0, sizeof(uint16_t), (void **) &abstruse->is.a_u16s.array, &abstruse->is.a_u16s.used, &abstruse->is.a_u16s.size); + } + + break; + + case f_abstruse_uint32s_e: + if (abstruse->is.a_u32s.size) { + return f_memory_array_resize(0, sizeof(uint32_t), (void **) &abstruse->is.a_u32s.array, &abstruse->is.a_u32s.used, &abstruse->is.a_u32s.size); + } + + break; + + case f_abstruse_uint64s_e: + if (abstruse->is.a_u64s.size) { + return f_memory_array_resize(0, sizeof(uint64_t), (void **) &abstruse->is.a_u64s.array, &abstruse->is.a_u64s.used, &abstruse->is.a_u64s.size); + } + + break; + + case f_abstruse_int8s_e: + if (abstruse->is.a_i8s.size) { + return f_memory_array_resize(0, sizeof(int8_t), (void **) &abstruse->is.a_i8s.array, &abstruse->is.a_i8s.used, &abstruse->is.a_i8s.size); + } + + break; + + case f_abstruse_int16s_e: + if (abstruse->is.a_i16s.size) { + return f_memory_array_resize(0, sizeof(int16_t), (void **) &abstruse->is.a_i16s.array, &abstruse->is.a_i16s.used, &abstruse->is.a_i16s.size); + } + + break; + + case f_abstruse_int32s_e: + if (abstruse->is.a_i32s.size) { + return f_memory_array_resize(0, sizeof(int32_t), (void **) &abstruse->is.a_i32s.array, &abstruse->is.a_i32s.used, &abstruse->is.a_i32s.size); + } + + break; + + case f_abstruse_int64s_e: + if (abstruse->is.a_i64s.size) { + return f_memory_array_resize(0, sizeof(int64_t), (void **) &abstruse->is.a_i64s.array, &abstruse->is.a_i64s.used, &abstruse->is.a_i64s.size); + } + + break; + + case f_abstruse_signeds_e: + if (abstruse->is.a_signeds.size) { + return f_memory_array_resize(0, sizeof(f_number_signed_t), (void **) &abstruse->is.a_signeds.array, &abstruse->is.a_signeds.used, &abstruse->is.a_signeds.size); + } + + break; + + case f_abstruse_unsigneds_e: + if (abstruse->is.a_unsigneds.size) { + return f_memory_array_resize(0, sizeof(f_number_unsigned_t), (void **) &abstruse->is.a_unsigneds.array, &abstruse->is.a_unsigneds.used, &abstruse->is.a_unsigneds.size); + } + + break; + + case f_abstruse_dynamic_e: + if (abstruse->is.a_dynamic.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_dynamic.string, &abstruse->is.a_dynamic.used, &abstruse->is.a_dynamic.size); + } + + break; + + case f_abstruse_dynamics_e: + if (abstruse->is.a_dynamics.size) { + return f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &abstruse->is.a_dynamics.array, &abstruse->is.a_dynamics.used, &abstruse->is.a_dynamics.size, &f_string_dynamics_delete_callback); + } + + break; + + case f_abstruse_map_e: + if (abstruse->is.a_map.name.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_map.name.string, &abstruse->is.a_map.name.used, &abstruse->is.a_map.name.size); + } + + if (abstruse->is.a_map.value.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_map.value.string, &abstruse->is.a_map.value.used, &abstruse->is.a_map.value.size); + } + + break; + + case f_abstruse_maps_e: + if (abstruse->is.a_maps.size) { + return f_memory_arrays_resize(0, sizeof(f_string_map_t), (void **) &abstruse->is.a_maps.array, &abstruse->is.a_maps.used, &abstruse->is.a_maps.size, &f_string_maps_delete_callback); + } + + break; + + case f_abstruse_map_multi_e: + if (abstruse->is.a_map_multi.name.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_map_multi.name.string, &abstruse->is.a_map_multi.name.used, &abstruse->is.a_map_multi.name.size); + } + + if (abstruse->is.a_map_multi.value.size) { + return f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &abstruse->is.a_map_multi.value.array, &abstruse->is.a_map_multi.value.used, &abstruse->is.a_map_multi.value.size, &f_string_dynamics_delete_callback); + } + + break; + + case f_abstruse_map_multis_e: + if (abstruse->is.a_map_multis.size) { + return f_memory_arrays_resize(0, sizeof(f_string_map_multi_t), (void **) &abstruse->is.a_map_multis.array, &abstruse->is.a_map_multis.used, &abstruse->is.a_map_multis.size, &f_string_map_multis_delete_callback); + } + + break; + + case f_abstruse_quantitys_e: + if (abstruse->is.a_quantitys.size) { + return f_memory_array_resize(0, sizeof(f_string_quantity_t), (void **) &abstruse->is.a_quantitys.array, &abstruse->is.a_quantitys.used, &abstruse->is.a_quantitys.size); + } + + break; + + case f_abstruse_ranges_e: + if (abstruse->is.a_quantitys.size) { + return f_memory_array_resize(0, sizeof(f_string_range_t), (void **) &abstruse->is.a_ranges.array, &abstruse->is.a_ranges.used, &abstruse->is.a_ranges.size); + } + + break; + + case f_abstruse_triple_e: + if (abstruse->is.a_triple.a.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_triple.a.string, &abstruse->is.a_triple.a.used, &abstruse->is.a_triple.a.size); + } + + if (abstruse->is.a_triple.b.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_triple.b.string, &abstruse->is.a_triple.b.used, &abstruse->is.a_triple.b.size); + } + + if (abstruse->is.a_triple.c.size) { + return f_memory_array_resize(0, sizeof(f_char_t), (void **) &abstruse->is.a_triple.c.string, &abstruse->is.a_triple.c.used, &abstruse->is.a_triple.c.size); + } + + break; + + case f_abstruse_triples_e: + if (abstruse->is.a_triples.size) { + return f_memory_arrays_resize(0, sizeof(f_string_triple_t), (void **) &abstruse->is.a_triples.array, &abstruse->is.a_triples.used, &abstruse->is.a_triples.size, &f_string_triples_delete_callback); + } + + break; + + default: + break; + }; + + return F_okay; + } +#endif // !defined(_di_f_abstruses_delete_callback_) || !defined(_di_f_abstrusess_delete_callback_) || !defined(_di_f_abstruse_maps_delete_callback_) || !defined(_di_f_abstruse_mapss_delete_callback_) + +#if !defined(_di_f_abstruses_destroy_callback_) || !defined(_di_f_abstrusess_destroy_callback_) || !defined(_di_f_abstruse_maps_destroy_callback_) || !defined(_di_f_abstruse_mapss_destroy_callback_) + f_status_t private_f_abstruses_destroy_switch(f_abstruse_t * const abstruse) { + + switch (abstruse->type) { + case f_abstruse_uint8_e: + if (abstruse->is.a_u8s.size) { + return f_memory_array_adjust(0, sizeof(uint8_t), (void **) &abstruse->is.a_u8s.array, &abstruse->is.a_u8s.used, &abstruse->is.a_u8s.size); + } + + break; + + case f_abstruse_uint16s_e: + if (abstruse->is.a_u16s.size) { + return f_memory_array_adjust(0, sizeof(uint16_t), (void **) &abstruse->is.a_u16s.array, &abstruse->is.a_u16s.used, &abstruse->is.a_u16s.size); + } + + break; + + case f_abstruse_uint32s_e: + if (abstruse->is.a_u32s.size) { + return f_memory_array_adjust(0, sizeof(uint32_t), (void **) &abstruse->is.a_u32s.array, &abstruse->is.a_u32s.used, &abstruse->is.a_u32s.size); + } + + break; + + case f_abstruse_uint64s_e: + if (abstruse->is.a_u64s.size) { + return f_memory_array_adjust(0, sizeof(uint64_t), (void **) &abstruse->is.a_u64s.array, &abstruse->is.a_u64s.used, &abstruse->is.a_u64s.size); + } + + break; + + case f_abstruse_int8s_e: + if (abstruse->is.a_i8s.size) { + return f_memory_array_adjust(0, sizeof(int8_t), (void **) &abstruse->is.a_i8s.array, &abstruse->is.a_i8s.used, &abstruse->is.a_i8s.size); + } + + break; + + case f_abstruse_int16s_e: + if (abstruse->is.a_i16s.size) { + return f_memory_array_adjust(0, sizeof(int16_t), (void **) &abstruse->is.a_i16s.array, &abstruse->is.a_i16s.used, &abstruse->is.a_i16s.size); + } + + break; + + case f_abstruse_int32s_e: + if (abstruse->is.a_i32s.size) { + return f_memory_array_adjust(0, sizeof(int32_t), (void **) &abstruse->is.a_i32s.array, &abstruse->is.a_i32s.used, &abstruse->is.a_i32s.size); + } + + break; + + case f_abstruse_int64s_e: + if (abstruse->is.a_i64s.size) { + return f_memory_array_adjust(0, sizeof(int64_t), (void **) &abstruse->is.a_i64s.array, &abstruse->is.a_i64s.used, &abstruse->is.a_i64s.size); + } + + break; + + case f_abstruse_signeds_e: + if (abstruse->is.a_signeds.size) { + return f_memory_array_adjust(0, sizeof(f_number_signed_t), (void **) &abstruse->is.a_signeds.array, &abstruse->is.a_signeds.used, &abstruse->is.a_signeds.size); + } + + break; + + case f_abstruse_unsigneds_e: + if (abstruse->is.a_unsigneds.size) { + return f_memory_array_adjust(0, sizeof(f_number_unsigned_t), (void **) &abstruse->is.a_unsigneds.array, &abstruse->is.a_unsigneds.used, &abstruse->is.a_unsigneds.size); + } + + break; + + case f_abstruse_dynamic_e: + if (abstruse->is.a_dynamic.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_dynamic.string, &abstruse->is.a_dynamic.used, &abstruse->is.a_dynamic.size); + } + + break; + + case f_abstruse_dynamics_e: + if (abstruse->is.a_dynamics.size) { + return f_memory_arrays_adjust(0, sizeof(f_string_dynamic_t), (void **) &abstruse->is.a_dynamics.array, &abstruse->is.a_dynamics.used, &abstruse->is.a_dynamics.size, &f_string_dynamics_destroy_callback); + } + + break; + + case f_abstruse_map_e: + if (abstruse->is.a_map.name.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_map.name.string, &abstruse->is.a_map.name.used, &abstruse->is.a_map.name.size); + } + + if (abstruse->is.a_map.value.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_map.value.string, &abstruse->is.a_map.value.used, &abstruse->is.a_map.value.size); + } + + break; + + case f_abstruse_maps_e: + if (abstruse->is.a_maps.size) { + return f_memory_arrays_adjust(0, sizeof(f_string_map_t), (void **) &abstruse->is.a_maps.array, &abstruse->is.a_maps.used, &abstruse->is.a_maps.size, &f_string_maps_destroy_callback); + } + + break; + + case f_abstruse_map_multi_e: + if (abstruse->is.a_map_multi.name.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_map_multi.name.string, &abstruse->is.a_map_multi.name.used, &abstruse->is.a_map_multi.name.size); + } + + if (abstruse->is.a_map_multi.value.size) { + return f_memory_arrays_adjust(0, sizeof(f_string_dynamic_t), (void **) &abstruse->is.a_map_multi.value.array, &abstruse->is.a_map_multi.value.used, &abstruse->is.a_map_multi.value.size, &f_string_dynamics_destroy_callback); + } + + break; + + case f_abstruse_map_multis_e: + if (abstruse->is.a_map_multis.size) { + return f_memory_arrays_adjust(0, sizeof(f_string_map_multi_t), (void **) &abstruse->is.a_map_multis.array, &abstruse->is.a_map_multis.used, &abstruse->is.a_map_multis.size, &f_string_map_multis_destroy_callback); + } + + break; + + case f_abstruse_quantitys_e: + if (abstruse->is.a_quantitys.size) { + return f_memory_array_adjust(0, sizeof(f_string_quantity_t), (void **) &abstruse->is.a_quantitys.array, &abstruse->is.a_quantitys.used, &abstruse->is.a_quantitys.size); + } + + break; + + case f_abstruse_ranges_e: + if (abstruse->is.a_quantitys.size) { + return f_memory_array_adjust(0, sizeof(f_string_range_t), (void **) &abstruse->is.a_ranges.array, &abstruse->is.a_ranges.used, &abstruse->is.a_ranges.size); + } + + break; + + case f_abstruse_triple_e: + if (abstruse->is.a_triple.a.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_triple.a.string, &abstruse->is.a_triple.a.used, &abstruse->is.a_triple.a.size); + } + + if (abstruse->is.a_triple.b.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_triple.b.string, &abstruse->is.a_triple.b.used, &abstruse->is.a_triple.b.size); + } + + if (abstruse->is.a_triple.c.size) { + return f_memory_array_adjust(0, sizeof(f_char_t), (void **) &abstruse->is.a_triple.c.string, &abstruse->is.a_triple.c.used, &abstruse->is.a_triple.c.size); + } + + break; + + case f_abstruse_triples_e: + if (abstruse->is.a_triples.size) { + return f_memory_arrays_adjust(0, sizeof(f_string_triple_t), (void **) &abstruse->is.a_triples.array, &abstruse->is.a_triples.used, &abstruse->is.a_triples.size, &f_string_triples_destroy_callback); + } + + break; + + default: + break; + }; + + return F_okay; + } +#endif // !defined(_di_f_abstruses_destroy_callback_) || !defined(_di_f_abstrusess_destroy_callback_) || !defined(_di_f_abstruse_maps_destroy_callback_) || !defined(_di_f_abstruse_mapss_destroy_callback_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/c/abstruse/private-abstruse.h b/level_0/f_abstruse/c/abstruse/private-abstruse.h new file mode 100644 index 0000000..7d3d98f --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/private-abstruse.h @@ -0,0 +1,64 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * 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_abstruse_h +#define _PRIVATE_F_abstruse_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Helper function for abstruse delete callbacks, performing the switch logic against the abstruse type. + * + * Intended to be shared to each of the different implementation variations. + * + * @param abstruse + * The abstruse to perform the switch-based delete operation on. + * + * @return + * F_okay on success, including when nothing done due to no match against the type. + * + * 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() + */ +#if !defined(_di_f_abstruses_delete_callback_) || !defined(_di_f_abstrusess_delete_callback_) || !defined(_di_f_abstruse_maps_delete_callback_) || !defined(_di_f_abstruse_mapss_delete_callback_) + extern f_status_t private_f_abstruses_delete_switch(f_abstruse_t * const abstruse) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_abstruses_delete_callback_) || !defined(_di_f_abstrusess_delete_callback_) || !defined(_di_f_abstruse_maps_delete_callback_) || !defined(_di_f_abstruse_mapss_delete_callback_) + +/** + * Helper function for abstruse destroy callbacks, performing the switch logic against the abstruse type. + * + * Intended to be shared to each of the different implementation variations. + * + * @param abstruse + * The abstruse to perform the switch-based destroy operation on. + * + * @return + * F_okay on success, including when nothing done due to no match against the type. + * + * 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() + */ +#if !defined(_di_f_abstruses_destroy_callback_) || !defined(_di_f_abstrusess_destroy_callback_) || !defined(_di_f_abstruse_maps_destroy_callback_) || !defined(_di_f_abstruse_mapss_destroy_callback_) + extern f_status_t private_f_abstruses_destroy_switch(f_abstruse_t * const abstruse) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_abstruses_destroy_callback_) || !defined(_di_f_abstrusess_destroy_callback_) || !defined(_di_f_abstruse_maps_destroy_callback_) || !defined(_di_f_abstruse_mapss_destroy_callback_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_abstruse_h diff --git a/level_0/f_abstruse/c/abstruse/type.h b/level_0/f_abstruse/c/abstruse/type.h new file mode 100644 index 0000000..be26152 --- /dev/null +++ b/level_0/f_abstruse/c/abstruse/type.h @@ -0,0 +1,84 @@ +/** + * FLL - Level 0 + * + * Project: Abstuse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Defines abstruse type data. + * + * This is auto-included by abstruse.h and should not need to be explicitly included. + */ +#ifndef _F_type_abstruse_type_h +#define _F_type_abstruse_type_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An abstruse type is a union representing any particular set of common types. + * + * The common type property names are prefixed with "a_" followed by the type name without the suffix "_t". + * + * This must be specially handled when swapping between types that contain allocated data. + * Be sure to de-allocate all memory before swapping to a differrent type. + */ +#ifndef _di_f_abstruse_type_t_ + typedef union { + uint8_t a_u8; + f_uint8s_t a_u8s; + uint16_t a_u16; + f_uint16s_t a_u16s; + uint32_t a_u32; + f_uint32s_t a_u32s; + uint64_t a_u64; + f_uint64s_t a_u64s; + int8_t a_i8; + f_int8s_t a_i8s; + int16_t a_i16; + f_int16s_t a_i16s; + int32_t a_i32; + f_int32s_t a_i32s; + int64_t a_i64; + f_int64s_t a_i64s; + f_number_signed_t a_signed; + f_number_signeds_t a_signeds; + f_number_unsigned_t a_unsigned; + f_number_unsigneds_t a_unsigneds; + f_char_t a_char; + f_string_t a_string; + f_string_t * a_strings; + f_string_dynamic_t a_dynamic; + f_string_dynamics_t a_dynamics; + f_string_map_t a_map; + f_string_maps_t a_maps; + f_string_map_multi_t a_map_multi; + f_string_map_multis_t a_map_multis; + f_string_quantity_t a_quantity; + f_string_quantitys_t a_quantitys; + f_string_range_t a_range; + f_string_ranges_t a_ranges; + f_string_triple_t a_triple; + f_string_triples_t a_triples; + void * a_void; + void ** a_voids; + size_t a_size; + size_t * a_sizes; + ssize_t a_ssize; + ssize_t * a_ssizes; + } f_abstruse_type_t; + + #define f_abstruse_type_t_initialize { 0 } + + #define macro_f_abstruse_type_t_initialize_1(value) { value } + + #define macro_f_abstruse_type_t_clear(abstruse_type) \ + abstruse_type = 0; +#endif // _di_f_abstruse_type_t_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_type_abstruse_type_h diff --git a/level_0/f_abstruse/data/build/defines b/level_0/f_abstruse/data/build/defines new file mode 100644 index 0000000..c665317 --- /dev/null +++ b/level_0/f_abstruse/data/build/defines @@ -0,0 +1,2 @@ +# fss-0000 + diff --git a/level_0/f_abstruse/data/build/dependencies b/level_0/f_abstruse/data/build/dependencies new file mode 100644 index 0000000..d798245 --- /dev/null +++ b/level_0/f_abstruse/data/build/dependencies @@ -0,0 +1,6 @@ +# fss-0000 + +f_type +f_status +f_memory +f_string diff --git a/level_0/f_abstruse/data/build/dependencies-tests b/level_0/f_abstruse/data/build/dependencies-tests new file mode 100644 index 0000000..dea3179 --- /dev/null +++ b/level_0/f_abstruse/data/build/dependencies-tests @@ -0,0 +1,3 @@ +# fss-0001 + +cmocka 1.* diff --git a/level_0/f_abstruse/data/build/fakefile b/level_0/f_abstruse/data/build/fakefile new file mode 100644 index 0000000..90a7134 --- /dev/null +++ b/level_0/f_abstruse/data/build/fakefile @@ -0,0 +1,12 @@ +# fss-0005 iki-0002 + +settings: + fail exit + modes individual individual_thread level monolithic clang test fanalyzer thread threadless + + environment PATH LD_LIBRARY_PATH + environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +main: + + build diff --git a/level_0/f_abstruse/data/build/settings b/level_0/f_abstruse/data/build/settings new file mode 100644 index 0000000..cc8c83a --- /dev/null +++ b/level_0/f_abstruse/data/build/settings @@ -0,0 +1,70 @@ +# fss-0001 +# +# Modes: +# - individual: Compile using per project (individual) libraries, does not handle thread or threadless cases. +# - individual_thread: This is required when compiling in individual mode with "thread" mode. +# - level: Compile using per level libraries. +# - monolithic: Compile using per monolithic libraries. +# - clang: Use clang rather than the default, which is generally gcc. +# - test: Compile for a test, such as unit testing. +# - fanalyzer: Compile using GCC's -fanalyzer compile time option. +# - thread: Compile with thread support. +# - threadless: Compile without thread support. +# + +build_name f_abstruse + +version_major 0 +version_minor 7 +version_micro 0 +version_file micro +version_target minor + +modes individual individual_thread level monolithic clang test fanalyzer thread threadless +modes_default individual individual_thread thread + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c + +build_libraries -lc +build_libraries-individual -lf_memory -lf_string + +build_sources_library abstruse.c abstruse/abstruse.c abstruse/map.c abstruse/private-abstruse.c +build_sources_headers abstruse.h abstruse/abstruse.h abstruse/enum.h abstruse/map.h abstruse/type.h + +build_script yes +build_shared yes +build_static no + +path_headers fll/level_0 +path_library_script script +path_library_shared shared +path_library_static static +path_object_script script +path_object_shared shared +path_object_static static +path_program_script script +path_program_shared shared +path_program_static static + +has_path_standard yes +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +environment PATH LD_LIBRARY_PATH +environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses +flags-clang -Wno-logical-op-parentheses +flags-test -O0 -fstack-protector -Wall +flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/ + +flags_library -fPIC +flags_object -fPIC +flags_program -fPIE diff --git a/level_0/f_abstruse/data/build/settings-mocks b/level_0/f_abstruse/data/build/settings-mocks new file mode 100644 index 0000000..bdf28dc --- /dev/null +++ b/level_0/f_abstruse/data/build/settings-mocks @@ -0,0 +1,69 @@ +# fss-0001 +# +# Build the project with appropriate mocks linked in via the dynamic linker's "--wrap" functionality. +# +# The -Wl,--wrap does not work across shared files. +# Therefore, this file is a work-around to inject the mocks into the library for testing purposes. +# This should exactly match the "settings" file, except for the additional "-Wl,--wrap" parts and the additional mock source file. +# +# The flags -o0 must be passed to prevent the compiler from optimizing away any functions being mocked (which results in the mock not happening and a real function being called). +# Alternatively, figure out which optimization that is disabled by -o0 and have that specific optimization disabled. +# + +build_name f_abstruse + +version_major 0 +version_minor 7 +version_micro 0 +version_file micro +version_target minor + +modes individual clang test coverage +modes_default individual test + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c + +build_libraries -lc +build_libraries-individual -lf_memory -lf_string + +build_sources_library abstruse.c abstruse/abstruse.c abstruse/map.c abstruse/private-abstruse.c +build_sources_library ../../tests/unit/c/mock-abstruse.c + +build_sources_headers abstruse.h abstruse/abstruse.h abstruse/enum.h abstruse/map.h abstruse/type.h + +build_script yes +build_shared yes +build_static no + +path_headers fll/level_0 +path_library_script script +path_library_shared shared +path_library_static static + +has_path_standard yes +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +environment PATH LD_LIBRARY_PATH +environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +#defines -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_ +defines -D_pthread_sigqueue_unsupported_ + +flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses +flags-clang -Wno-logical-op-parentheses +flags-test -fstack-protector -Wall +flags-coverage --coverage -fprofile-abs-path -fprofile-dir=build/coverage/ + +flags_library -fPIC + +# Inject mocks. +flags -Wl,--wrap=f_memory_array_adjust +flags -Wl,--wrap=f_memory_array_resize diff --git a/level_0/f_abstruse/data/build/settings-tests b/level_0/f_abstruse/data/build/settings-tests new file mode 100644 index 0000000..5bc01ca --- /dev/null +++ b/level_0/f_abstruse/data/build/settings-tests @@ -0,0 +1,58 @@ +# fss-0001 +# +# Builds a program that is links to the generated library and is executed to perform tests. +# +# Memory leaks in the test program can be checked for by running valgrind with this executable. +# + +build_name test-f_abstruse + +version_major 0 +version_minor 7 +version_micro 0 +version_file major +version_target major + +modes individual clang test coverage +modes_default individual test + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c + +build_libraries -lc -lcmocka +build_libraries-individual -lf_memory -lf_string -lf_abstruse + +build_sources_program test-abstruse-s_delete_callback.c test-abstruse-s_destroy_callback.c test-abstruse-ss_delete_callback.c test-abstruse-ss_destroy_callback.c +build_sources_program test-abstruse-maps_delete_callback.c test-abstruse-maps_destroy_callback.c test-abstruse-mapss_delete_callback.c test-abstruse-mapss_destroy_callback.c +build_sources_program test-abstruse.c + +build_script no +build_shared yes +build_static no + +path_headers tests/unit/c +path_sources tests/unit/c + +has_path_standard no +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +environment PATH LD_LIBRARY_PATH +environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + +defines -Ibuild/includes +defines_static -Lbuild/libraries/static +defines_shared -Lbuild/libraries/shared + +flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses +flags-clang -Wno-logical-op-parentheses +flags-test -fstack-protector -Wall +flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/ + +flags_program -fPIE diff --git a/level_0/f_abstruse/data/build/testfile b/level_0/f_abstruse/data/build/testfile new file mode 100644 index 0000000..dbeaf4f --- /dev/null +++ b/level_0/f_abstruse/data/build/testfile @@ -0,0 +1,63 @@ +# fss-0005 abstruse-0002 + +settings: + load_build yes + fail exit + + environment PATH LD_LIBRARY_PATH + environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH + environment CMOCKA_XML_FILE CMOCKA_MESSAGE_OUTPUT CMOCKA_TEST_ABORT + + # Cmocka is not fully thread-safe, set this to "1" to have cmocka call abort() on a test failure. + #CMOCKA_TEST_ABORT 1 + + # One of: STDOUT, SUBUNIT, TAP, or XML. + #define CMOCKA_MESSAGE_OUTPUT STDOUT + + # When in "XML" output mode, output to this file rather than stdout. + #define CMOCKA_XML_FILE ./out.xml + +main: + build settings-mocks individual test + build settings-tests individual test + + operate build_path + operate ld_library_path + + if exist parameter:"build_path"programs/shared/test-f_abstruse + shell parameter:"build_path"programs/shared/test-f_abstruse + + if exist parameter:"build_path"programs/static/test-f_abstruse + shell parameter:"build_path"programs/static/test-f_abstruse + + if not exist parameter:"build_path"programs/shared/test-f_abstruse + and not exist parameter:"build_path"programs/static/test-f_abstruse + operate not_created + +not_created: + print + print 'context:"error"Failed to test due to being unable to find either a shared or static test binary to perform tests. context:"reset"' + + exit failure + +build_path: + parameter build_path build/ + + if parameter build:value + parameter build_path parameter:"build:value" + +ld_library_path: + if define LD_LIBRARY_PATH + and parameter work:value + define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"' + + else + if define LD_LIBRARY_PATH + define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:define:"LD_LIBRARY_PATH"' + + else + if parameter work:value + define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:parameter:"work:value"libraries/shared' + + else + define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared' diff --git a/level_0/f_abstruse/tests/unit/c/mock-abstruse.c b/level_0/f_abstruse/tests/unit/c/mock-abstruse.c new file mode 100644 index 0000000..a1455b4 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/mock-abstruse.c @@ -0,0 +1,46 @@ +#include "mock-abstruse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int mock_unwrap = 0; +int mock_unwrap_f_memory = 1; + +f_status_t __wrap_f_memory_array_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_array_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) { + return __real_f_memory_array_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_abstruse/tests/unit/c/mock-abstruse.h b/level_0/f_abstruse/tests/unit/c/mock-abstruse.h new file mode 100644 index 0000000..4dcb9f0 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/mock-abstruse.h @@ -0,0 +1,45 @@ +/** + * FLL - Level 0 + * + * Project: IKI + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstruse project. + */ +#ifndef _MOCK__abstruse_h +#define _MOCK__abstruse_h + +// Libc includes. +#include +#include +#include +#include +#include + +// cmocka includes. +#include + +// FLL-0 includes. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const static int mock_errno_generic = 32767; + +extern int mock_unwrap; +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 __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); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _MOCK__abstruse_h diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_delete_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_delete_callback.c new file mode 100644 index 0000000..3014452 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_delete_callback.c @@ -0,0 +1,119 @@ +#include "test-abstruse.h" +#include "test-abstruse-maps_delete_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_maps_delete_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t value_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t value_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t value_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t value_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + + f_string_static_t key_0 = macro_f_string_static_t_initialize_2("key_0", 5); + f_string_static_t key_1 = macro_f_string_static_t_initialize_2("key_1", 5); + f_string_static_t key_2 = macro_f_string_static_t_initialize_2("key_2", 5); + f_string_static_t key_3 = macro_f_string_static_t_initialize_2("key_3", 5); + + f_abstruse_map_t data_0 = macro_f_abstruse_map_t_initialize_1(key_0, value_0); + f_abstruse_map_t data_1 = macro_f_abstruse_map_t_initialize_1(key_1, value_1); + f_abstruse_map_t data_2 = macro_f_abstruse_map_t_initialize_1(key_2, value_2); + f_abstruse_map_t data_3 = macro_f_abstruse_map_t_initialize_1(key_3, value_3); + + f_abstruse_map_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + { + 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_abstruse_maps_delete_callback(0, length, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + free((void *) a_dynamic.string); +} + +void test__f_abstruse_maps_delete_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t value_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t value_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t value_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t value_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + + f_string_dynamic_t key_0 = f_string_static_t_initialize; + f_string_dynamic_t key_1 = f_string_static_t_initialize; + f_string_dynamic_t key_2 = f_string_static_t_initialize; + f_string_dynamic_t key_3 = f_string_static_t_initialize; + + f_abstruse_map_t data_0 = macro_f_abstruse_map_t_initialize_1(key_0, value_0); + f_abstruse_map_t data_1 = macro_f_abstruse_map_t_initialize_1(key_1, value_1); + f_abstruse_map_t data_2 = macro_f_abstruse_map_t_initialize_1(key_2, value_2); + f_abstruse_map_t data_3 = macro_f_abstruse_map_t_initialize_1(key_3, value_3); + + f_abstruse_map_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + f_abstruse_maps_t datas = macro_f_abstruse_maps_t_initialize_2(data_array, length); + + { + f_status_t status = f_string_append("key_0", 5, &datas.array[0].key); + assert_int_equal(status, F_okay); + + status = f_string_append("key_1", 5, &datas.array[1].key); + assert_int_equal(status, F_okay); + + status = f_string_append("key_2", 5, &datas.array[2].key); + assert_int_equal(status, F_okay); + + status = f_string_append("key_3", 5, &datas.array[3].key); + assert_int_equal(status, F_okay); + + status = f_string_append("a", 1, &datas.array[3].value.is.a_dynamic); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_abstruse_maps_delete_callback(0, length, (void *) datas.array); + + assert_int_equal(status, F_okay); + + assert_int_equal(datas.array[0].key.size, 0); + assert_int_equal(datas.array[1].key.size, 0); + assert_int_equal(datas.array[2].key.size, 0); + + assert_int_equal(datas.array[3].key.size, 0); + assert_int_equal(datas.array[3].value.is.a_dynamic.size, 0); + } + + free((void *) key_0.string); + free((void *) key_1.string); + free((void *) key_2.string); + free((void *) key_3.string); + free((void *) a_dynamic.string); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_delete_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_delete_callback.h new file mode 100644 index 0000000..9158496 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_delete_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__maps_delete_callback +#define _TEST__F_abstruse__maps_delete_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_maps_delete_callback() + */ +extern void test__f_abstruse_maps_delete_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_maps_delete_callback() + */ +extern void test__f_abstruse_maps_delete_callback__works(void **state); + +#endif // _TEST__F_abstruse__maps_delete_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_destroy_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_destroy_callback.c new file mode 100644 index 0000000..c8ae558 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_destroy_callback.c @@ -0,0 +1,119 @@ +#include "test-abstruse.h" +#include "test-abstruse-maps_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_maps_destroy_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t value_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t value_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t value_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t value_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + + f_string_static_t key_0 = macro_f_string_static_t_initialize_2("key_0", 5); + f_string_static_t key_1 = macro_f_string_static_t_initialize_2("key_1", 5); + f_string_static_t key_2 = macro_f_string_static_t_initialize_2("key_2", 5); + f_string_static_t key_3 = macro_f_string_static_t_initialize_2("key_3", 5); + + f_abstruse_map_t data_0 = macro_f_abstruse_map_t_initialize_1(key_0, value_0); + f_abstruse_map_t data_1 = macro_f_abstruse_map_t_initialize_1(key_1, value_1); + f_abstruse_map_t data_2 = macro_f_abstruse_map_t_initialize_1(key_2, value_2); + f_abstruse_map_t data_3 = macro_f_abstruse_map_t_initialize_1(key_3, value_3); + + f_abstruse_map_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + { + 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_abstruse_maps_destroy_callback(0, length, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + free((void *) a_dynamic.string); +} + +void test__f_abstruse_maps_destroy_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t value_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t value_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t value_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t value_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + + f_string_dynamic_t key_0 = f_string_static_t_initialize; + f_string_dynamic_t key_1 = f_string_static_t_initialize; + f_string_dynamic_t key_2 = f_string_static_t_initialize; + f_string_dynamic_t key_3 = f_string_static_t_initialize; + + f_abstruse_map_t data_0 = macro_f_abstruse_map_t_initialize_1(key_0, value_0); + f_abstruse_map_t data_1 = macro_f_abstruse_map_t_initialize_1(key_1, value_1); + f_abstruse_map_t data_2 = macro_f_abstruse_map_t_initialize_1(key_2, value_2); + f_abstruse_map_t data_3 = macro_f_abstruse_map_t_initialize_1(key_3, value_3); + + f_abstruse_map_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + f_abstruse_maps_t datas = macro_f_abstruse_maps_t_initialize_2(data_array, length); + + { + f_status_t status = f_string_append("key_0", 5, &datas.array[0].key); + assert_int_equal(status, F_okay); + + status = f_string_append("key_1", 5, &datas.array[1].key); + assert_int_equal(status, F_okay); + + status = f_string_append("key_2", 5, &datas.array[2].key); + assert_int_equal(status, F_okay); + + status = f_string_append("key_3", 5, &datas.array[3].key); + assert_int_equal(status, F_okay); + + status = f_string_append("a", 1, &datas.array[3].value.is.a_dynamic); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_abstruse_maps_destroy_callback(0, length, (void *) datas.array); + + assert_int_equal(status, F_okay); + + assert_int_equal(datas.array[0].key.size, 0); + assert_int_equal(datas.array[1].key.size, 0); + assert_int_equal(datas.array[2].key.size, 0); + + assert_int_equal(datas.array[3].key.size, 0); + assert_int_equal(datas.array[3].value.is.a_dynamic.size, 0); + } + + free((void *) key_0.string); + free((void *) key_1.string); + free((void *) key_2.string); + free((void *) key_3.string); + free((void *) a_dynamic.string); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_destroy_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_destroy_callback.h new file mode 100644 index 0000000..8005562 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-maps_destroy_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__maps_destroy_callback +#define _TEST__F_abstruse__maps_destroy_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_maps_destroy_callback() + */ +extern void test__f_abstruse_maps_destroy_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_maps_destroy_callback() + */ +extern void test__f_abstruse_maps_destroy_callback__works(void **state); + +#endif // _TEST__F_abstruse__maps_destroy_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_delete_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_delete_callback.c new file mode 100644 index 0000000..bd4b58d --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_delete_callback.c @@ -0,0 +1,85 @@ +#include "test-abstruse.h" +#include "test-abstruse-mapss_delete_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_mapss_delete_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t value_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t value_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t value_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t value_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + + f_string_static_t key_0 = macro_f_string_static_t_initialize_2("key_0", 5); + f_string_static_t key_1 = macro_f_string_static_t_initialize_2("key_1", 5); + f_string_static_t key_2 = macro_f_string_static_t_initialize_2("key_2", 5); + f_string_static_t key_3 = macro_f_string_static_t_initialize_2("key_3", 5); + + f_abstruse_map_t data_0 = macro_f_abstruse_map_t_initialize_1(key_0, value_0); + f_abstruse_map_t data_1 = macro_f_abstruse_map_t_initialize_1(key_1, value_1); + f_abstruse_map_t data_2 = macro_f_abstruse_map_t_initialize_1(key_2, value_2); + f_abstruse_map_t data_3 = macro_f_abstruse_map_t_initialize_1(key_3, value_3); + + f_abstruse_map_t data_array[] = { data_0, data_1, data_2, data_3 }; + + f_abstruse_maps_t datas = { .array = data_array, .used = 1, .size = 1 }; + f_abstruse_maps_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_abstruse_mapss_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_abstruse_mapss_delete_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_abstruse_mapss_t datass = f_abstruse_mapss_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_abstruse_maps_t), (void **) &datass.array, &datass.used, &datass.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_abstruse_map_t), (void **) &datass.array[0].array, &datass.array[0].used, &datass.array[0].size); + assert_int_equal(status, F_okay); + + status = f_string_append("key_0", 5, &datass.array[0].array[0].key); + assert_int_equal(status, F_okay); + + status = f_string_append("a", 1, &datass.array[0].array[0].value.is.a_dynamic); + assert_int_equal(status, F_okay); + + datass.array[0].array[0].value.type = f_abstruse_dynamic_e; + } + + { + const f_status_t status = f_abstruse_mapss_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_abstruse/tests/unit/c/test-abstruse-mapss_delete_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_delete_callback.h new file mode 100644 index 0000000..0712dff --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_delete_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__mapss_delete_callback +#define _TEST__F_abstruse__mapss_delete_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_mapss_delete_callback() + */ +extern void test__f_abstruse_mapss_delete_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_mapss_delete_callback() + */ +extern void test__f_abstruse_mapss_delete_callback__works(void **state); + +#endif // _TEST__F_abstruse__mapss_delete_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_destroy_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_destroy_callback.c new file mode 100644 index 0000000..9104f24 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_destroy_callback.c @@ -0,0 +1,85 @@ +#include "test-abstruse.h" +#include "test-abstruse-mapss_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_mapss_destroy_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t value_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t value_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t value_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t value_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + + f_string_static_t key_0 = macro_f_string_static_t_initialize_2("key_0", 5); + f_string_static_t key_1 = macro_f_string_static_t_initialize_2("key_1", 5); + f_string_static_t key_2 = macro_f_string_static_t_initialize_2("key_2", 5); + f_string_static_t key_3 = macro_f_string_static_t_initialize_2("key_3", 5); + + f_abstruse_map_t data_0 = macro_f_abstruse_map_t_initialize_1(key_0, value_0); + f_abstruse_map_t data_1 = macro_f_abstruse_map_t_initialize_1(key_1, value_1); + f_abstruse_map_t data_2 = macro_f_abstruse_map_t_initialize_1(key_2, value_2); + f_abstruse_map_t data_3 = macro_f_abstruse_map_t_initialize_1(key_3, value_3); + + f_abstruse_map_t data_array[] = { data_0, data_1, data_2, data_3 }; + + f_abstruse_maps_t datas = { .array = data_array, .used = 1, .size = 1 }; + f_abstruse_maps_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_abstruse_mapss_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_abstruse_mapss_destroy_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_abstruse_mapss_t datass = f_abstruse_mapss_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_abstruse_maps_t), (void **) &datass.array, &datass.used, &datass.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_abstruse_map_t), (void **) &datass.array[0].array, &datass.array[0].used, &datass.array[0].size); + assert_int_equal(status, F_okay); + + status = f_string_append("key_0", 5, &datass.array[0].array[0].key); + assert_int_equal(status, F_okay); + + status = f_string_append("a", 1, &datass.array[0].array[0].value.is.a_dynamic); + assert_int_equal(status, F_okay); + + datass.array[0].array[0].value.type = f_abstruse_dynamic_e; + } + + { + const f_status_t status = f_abstruse_mapss_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_abstruse/tests/unit/c/test-abstruse-mapss_destroy_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_destroy_callback.h new file mode 100644 index 0000000..6b9de5b --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-mapss_destroy_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__mapss_destroy_callback +#define _TEST__F_abstruse__mapss_destroy_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_mapss_destroy_callback() + */ +extern void test__f_abstruse_mapss_destroy_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_mapss_destroy_callback() + */ +extern void test__f_abstruse_mapss_destroy_callback__works(void **state); + +#endif // _TEST__F_abstruse__mapss_destroy_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-s_delete_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_delete_callback.c new file mode 100644 index 0000000..4153479 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_delete_callback.c @@ -0,0 +1,80 @@ +#include "test-abstruse.h" +#include "test-abstruse-s_delete_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_s_delete_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t data_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t data_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t data_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t data_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + f_abstruse_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + { + const f_status_t status = f_string_append("a", 1, &data_array[3].is.a_dynamic); + assert_int_equal(status, 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_abstruses_delete_callback(0, length, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + free((void *) data_array[3].is.a_dynamic.string); +} + +void test__f_abstruse_s_delete_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t data_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t data_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t data_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t data_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + f_abstruse_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + f_abstruses_t datas = macro_f_abstruses_t_initialize_2(data_array, length); + + { + const f_status_t status = f_string_append("a", 1, &datas.array[3].is.a_dynamic); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_abstruses_delete_callback(0, length, (void *) datas.array); + + assert_int_equal(status, F_okay); + assert_int_equal(datas.array[3].is.a_dynamic.size, 0); + } + + free((void *) datas.array[3].is.a_dynamic.string); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-s_delete_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_delete_callback.h new file mode 100644 index 0000000..0ff9040 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_delete_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__s_delete_callback +#define _TEST__F_abstruse__s_delete_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_s_delete_callback() + */ +extern void test__f_abstruse_s_delete_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_s_delete_callback() + */ +extern void test__f_abstruse_s_delete_callback__works(void **state); + +#endif // _TEST__F_abstruse__s_delete_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-s_destroy_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_destroy_callback.c new file mode 100644 index 0000000..4481c89 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_destroy_callback.c @@ -0,0 +1,80 @@ +#include "test-abstruse.h" +#include "test-abstruse-s_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_s_destroy_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t data_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t data_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t data_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t data_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + f_abstruse_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + { + const f_status_t status = f_string_append("a", 1, &data_array[3].is.a_dynamic); + assert_int_equal(status, 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_abstruses_destroy_callback(0, length, (void *) data_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } + + free((void *) data_array[3].is.a_dynamic.string); +} + +void test__f_abstruse_s_destroy_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t data_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t data_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t data_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t data_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + f_abstruse_t data_array[] = { data_0, data_1, data_2, data_3 }; + + const f_number_unsigned_t length = 4; + + f_abstruses_t datas = macro_f_abstruses_t_initialize_2(data_array, length); + + { + const f_status_t status = f_string_append("a", 1, &datas.array[3].is.a_dynamic); + assert_int_equal(status, F_okay); + } + + { + const f_status_t status = f_abstruses_destroy_callback(0, length, (void *) datas.array); + + assert_int_equal(status, F_okay); + assert_int_equal(datas.array[3].is.a_dynamic.size, 0); + } + + free((void *) datas.array[3].is.a_dynamic.string); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-s_destroy_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_destroy_callback.h new file mode 100644 index 0000000..25f7123 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-s_destroy_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__s_destroy_callback +#define _TEST__F_abstruse__s_destroy_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_s_destroy_callback() + */ +extern void test__f_abstruse_s_destroy_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_s_destroy_callback() + */ +extern void test__f_abstruse_s_destroy_callback__works(void **state); + +#endif // _TEST__F_abstruse__s_destroy_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_delete_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_delete_callback.c new file mode 100644 index 0000000..4e112da --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_delete_callback.c @@ -0,0 +1,71 @@ +#include "test-abstruse.h" +#include "test-abstruse-ss_delete_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_ss_delete_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t data_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t data_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t data_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t data_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + f_abstruse_t data_array[] = { data_0, data_1, data_2, data_3 }; + + f_abstruses_t datas = { .array = data_array, .used = 1, .size = 1 }; + f_abstruses_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_abstrusess_delete_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_abstruse_ss_delete_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_abstrusess_t datass = f_abstrusess_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_abstruse_t), (void **) &datass.array, &datass.used, &datass.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_abstruse_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_string_t), (void **) &datass.array[0].array[0].is.a_dynamic, &datass.array[0].array[0].is.a_dynamic.used, &datass.array[0].array[0].is.a_dynamic.size); + assert_int_equal(status, F_okay); + + datass.array[0].array[0].type = f_abstruse_dynamic_e; + } + + { + const f_status_t status = f_abstrusess_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_abstruse/tests/unit/c/test-abstruse-ss_delete_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_delete_callback.h new file mode 100644 index 0000000..8058151 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_delete_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__ss_delete_callback +#define _TEST__F_abstruse__ss_delete_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_ss_delete_callback() + */ +extern void test__f_abstruse_ss_delete_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_ss_delete_callback() + */ +extern void test__f_abstruse_ss_delete_callback__works(void **state); + +#endif // _TEST__F_abstruse__ss_delete_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_destroy_callback.c b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_destroy_callback.c new file mode 100644 index 0000000..5b5e47d --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_destroy_callback.c @@ -0,0 +1,71 @@ +#include "test-abstruse.h" +#include "test-abstruse-ss_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_abstruse_ss_destroy_callback__fails(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 0; + + f_string_t a_string = "example"; + f_string_range_t a_range = macro_f_string_range_t_initialize_1(1, 2); + f_string_static_t a_static = macro_f_string_static_t_initialize_1(a_string, 0, 7); + f_string_dynamic_t a_dynamic = f_string_dynamic_t_initialize; + + f_abstruse_t data_0 = { .type = f_abstruse_range_e, .is.a_range = a_range }; + f_abstruse_t data_1 = { .type = f_abstruse_string_e, .is.a_string = a_string }; + f_abstruse_t data_2 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_static }; + f_abstruse_t data_3 = { .type = f_abstruse_dynamic_e, .is.a_dynamic = a_dynamic }; + f_abstruse_t data_array[] = { data_0, data_1, data_2, data_3 }; + + f_abstruses_t datas = { .array = data_array, .used = 1, .size = 1 }; + f_abstruses_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_abstrusess_destroy_callback(0, 1, (void *) datas_array); + + assert_int_equal(status, F_status_set_error(F_failure)); + } +} + +void test__f_abstruse_ss_destroy_callback__works(void **state) { + + mock_unwrap = 0; + mock_unwrap_f_memory = 1; + + const f_number_unsigned_t length = 1; + + f_abstrusess_t datass = f_abstrusess_t_initialize; + + { + f_status_t status = f_memory_array_resize(length, sizeof(f_abstruses_t), (void **) &datass.array, &datass.used, &datass.size); + assert_int_equal(status, F_okay); + + status = f_memory_array_resize(1, sizeof(f_abstruse_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_string_t), (void **) &datass.array[0].array[0].is.a_dynamic, &datass.array[0].array[0].is.a_dynamic.used, &datass.array[0].array[0].is.a_dynamic.size); + assert_int_equal(status, F_okay); + + datass.array[0].array[0].type = f_abstruse_dynamic_e; + } + + { + const f_status_t status = f_abstrusess_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_abstruse/tests/unit/c/test-abstruse-ss_destroy_callback.h b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_destroy_callback.h new file mode 100644 index 0000000..75ca862 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse-ss_destroy_callback.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstract project. + */ +#ifndef _TEST__F_abstruse__ss_destroy_callback +#define _TEST__F_abstruse__ss_destroy_callback + +/** + * Test that the function fails. + * + * @see f_abstruse_ss_destroy_callback() + */ +extern void test__f_abstruse_ss_destroy_callback__fails(void **state); + +/** + * Test that the function works. + * + * @see f_abstruse_ss_destroy_callback() + */ +extern void test__f_abstruse_ss_destroy_callback__works(void **state); + +#endif // _TEST__F_abstruse__ss_destroy_callback diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse.c b/level_0/f_abstruse/tests/unit/c/test-abstruse.c new file mode 100644 index 0000000..2dbde80 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse.c @@ -0,0 +1,60 @@ +#include "test-abstruse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int setup(void **state) { + + return 0; +} + +int setdown(void **state) { + + errno = 0; + + return 0; +} + +int main(void) { + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test__f_abstruse_s_delete_callback__fails), + cmocka_unit_test(test__f_abstruse_s_destroy_callback__fails), + cmocka_unit_test(test__f_abstruse_ss_destroy_callback__fails), + cmocka_unit_test(test__f_abstruse_ss_delete_callback__fails), + + cmocka_unit_test(test__f_abstruse_s_delete_callback__works), + cmocka_unit_test(test__f_abstruse_s_destroy_callback__works), + cmocka_unit_test(test__f_abstruse_ss_delete_callback__works), + cmocka_unit_test(test__f_abstruse_ss_destroy_callback__works), + + cmocka_unit_test(test__f_abstruse_maps_delete_callback__fails), + cmocka_unit_test(test__f_abstruse_maps_destroy_callback__fails), + cmocka_unit_test(test__f_abstruse_mapss_destroy_callback__fails), + cmocka_unit_test(test__f_abstruse_mapss_delete_callback__fails), + + cmocka_unit_test(test__f_abstruse_maps_delete_callback__works), + cmocka_unit_test(test__f_abstruse_maps_destroy_callback__works), + cmocka_unit_test(test__f_abstruse_mapss_delete_callback__works), + cmocka_unit_test(test__f_abstruse_mapss_destroy_callback__works), + + #ifndef _di_level_0_parameter_checking_ + // f_abstruse_maps_destroy_callback() doesn't use parameter checking. + // f_abstruse_maps_delete_callback() doesn't use parameter checking. + // f_abstruse_mapss_destroy_callback() doesn't use parameter checking. + // f_abstruse_mapss_delete_callback() doesn't use parameter checking. + + // f_abstruse_s_destroy_callback() doesn't use parameter checking. + // f_abstruse_s_delete_callback() doesn't use parameter checking. + // f_abstruse_ss_destroy_callback() doesn't use parameter checking. + // f_abstruse_ss_delete_callback() doesn't use parameter checking. + #endif // _di_level_0_parameter_checking_ + }; + + return cmocka_run_group_tests(tests, setup, setdown); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_abstruse/tests/unit/c/test-abstruse.h b/level_0/f_abstruse/tests/unit/c/test-abstruse.h new file mode 100644 index 0000000..d0e7e61 --- /dev/null +++ b/level_0/f_abstruse/tests/unit/c/test-abstruse.h @@ -0,0 +1,79 @@ +/** + * FLL - Level 0 + * + * Project: Abstruse + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the abstruse project. + */ +#ifndef _TEST__F_abstruse_h +#define _TEST__F_abstruse_h + +// Libc includes. +#include +#include +#include +#include + +// cmocka includes. +#include + +// FLL-0 includes. +#include + +// Mock includes. +#include "mock-abstruse.h" + +// Test includes. +#include "test-abstruse-maps_delete_callback.h" +#include "test-abstruse-maps_destroy_callback.h" +#include "test-abstruse-mapss_delete_callback.h" +#include "test-abstruse-mapss_destroy_callback.h" +#include "test-abstruse-s_delete_callback.h" +#include "test-abstruse-s_destroy_callback.h" +#include "test-abstruse-ss_delete_callback.h" +#include "test-abstruse-ss_destroy_callback.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform any setup operations. + * + * @param state + * The test state. + * + * @return + * The status of this function, where 0 means success. + */ +extern int setup(void **state); + +/** + * Peform any setdown operations. + * + * @param state + * The test state. + * + * @return + * The status of this function, where 0 means success. + */ +extern int setdown(void **state); + +/** + * Run all tests. + * + * @return + * The final result of the tests. + * + * @see cmocka_run_group_tests() + * @see cmocka_unit_test() + */ +extern int main(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _TEST__F_abstruse_h