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.
# 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:
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
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
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
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
${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}/ &&
//
// 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
//
// 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
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
//
// 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
//
// 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
--- /dev/null
+#include "abstruse.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+// FLL-0 includes.
+#include <fll/level_0/type.h>
+#include <fll/level_0/status.h>
+#include <fll/level_0/memory.h>
+#include <fll/level_0/type_array.h>
+#include <fll/level_0/string.h>
+
+// FLL-0 type includes.
+#include <fll/level_0/abstruse/enum.h>
+#include <fll/level_0/abstruse/type.h>
+#include <fll/level_0/abstruse/abstruse.h>
+#include <fll/level_0/abstruse/map.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _F_abstruse_h
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+/**
+ * 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
--- /dev/null
+# fss-0000
+
--- /dev/null
+# fss-0000
+
+f_type
+f_status
+f_memory
+f_string
--- /dev/null
+# fss-0001
+
+cmocka 1.*
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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'
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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 <semaphore.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-0 includes.
+#include <fll/level_0/abstruse.h>
+
+#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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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 <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-0 includes.
+#include <fll/level_0/abstruse.h>
+
+// 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