From 9f6b588e3071ce1164c2e67047794ac6a69d9ee0 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 14 May 2022 19:57:19 -0500 Subject: [PATCH] Update: The f_limit project is out of date. Writing unit tests revealed that the f_limit project does not operate like the latest code. Restructure and rewrite f_limit to be consistent with the latest practices and designs in the rest of the project. Other projects utilizing this are also updated. --- build/level_0/settings | 6 +- build/monolithic/settings | 6 +- level_0/f_limit/c/limit.c | 50 --- level_0/f_limit/c/limit.h | 45 +-- level_0/f_limit/c/limit/common.h | 130 ------- level_0/f_limit/c/limit/private-set.c | 127 +++++++ level_0/f_limit/c/limit/private-set.h | 175 ++++++++++ level_0/f_limit/c/limit/private-value.c | 127 +++++++ level_0/f_limit/c/limit/private-value.h | 175 ++++++++++ level_0/f_limit/c/limit/set.c | 290 ++++++++++++++++ level_0/f_limit/c/limit/set.h | 466 ++++++++++++++++++++++++++ level_0/f_limit/c/limit/value.c | 290 ++++++++++++++++ level_0/f_limit/c/limit/value.h | 463 +++++++++++++++++++++++++ level_0/f_limit/data/build/dependencies-tests | 3 + level_0/f_limit/data/build/settings | 4 +- level_0/f_limit/data/build/settings-mocks | 50 +++ level_0/f_limit/data/build/settings-tests | 57 ++++ level_0/f_limit/data/build/testfile | 45 +++ level_3/controller/c/rule/private-rule.c | 3 +- 19 files changed, 2280 insertions(+), 232 deletions(-) delete mode 100644 level_0/f_limit/c/limit/common.h create mode 100644 level_0/f_limit/c/limit/private-set.c create mode 100644 level_0/f_limit/c/limit/private-set.h create mode 100644 level_0/f_limit/c/limit/private-value.c create mode 100644 level_0/f_limit/c/limit/private-value.h create mode 100644 level_0/f_limit/c/limit/set.c create mode 100644 level_0/f_limit/c/limit/set.h create mode 100644 level_0/f_limit/c/limit/value.c create mode 100644 level_0/f_limit/c/limit/value.h create mode 100644 level_0/f_limit/data/build/dependencies-tests create mode 100644 level_0/f_limit/data/build/settings-mocks create mode 100644 level_0/f_limit/data/build/settings-tests create mode 100644 level_0/f_limit/data/build/testfile diff --git a/build/level_0/settings b/build/level_0/settings index f8fbdde..1b77f31 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -28,10 +28,10 @@ build_sources_library conversion.c private-conversion.c conversion/common.c build_sources_library directory.c directory/common.c private-directory.c build_sources_library environment.c build_sources_library execute.c -build_sources_library file.c file/common.c private-file.c +build_sources_library file.c private-file.c file/common.c build_sources_library fss.c private-fss.c fss/common.c fss/named.c fss/nest.c fss/set.c build_sources_library iki.c iki/common.c iki/data.c private-iki.c iki/private-data.c -build_sources_library limit.c +build_sources_library limit.c limit/set.c limit/value.c limit/private-set.c limit/private-value.c build_sources_library memory.c private-memory.c memory/structure.c build_sources_library path.c private-path.c path/common.c build_sources_library pipe.c @@ -60,7 +60,7 @@ build_sources_headers execute.h execute/common.h build_sources_headers file.h file/common.h build_sources_headers fss.h fss/comment.h fss/common.h fss/delimit.h fss/named.h fss/nest.h fss/quote.h fss/set.h build_sources_headers iki.h iki/common.h iki/data.h -build_sources_headers limit.h limit/common.h +build_sources_headers limit.h limit/set.h limit/value.h build_sources_headers memory.h memory/structure.h memory/common.h build_sources_headers path.h path/common.h build_sources_headers pipe.h diff --git a/build/monolithic/settings b/build/monolithic/settings index b06e664..0d6ee6a 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -28,10 +28,10 @@ build_sources_library level_0/conversion.c level_0/private-conversion.c level_0/ build_sources_library level_0/directory.c level_0/directory/common.c level_0/private-directory.c build_sources_library level_0/environment.c build_sources_library level_0/execute.c -build_sources_library level_0/file.c level_0/file/common.c level_0/private-file.c +build_sources_library level_0/file.c level_0/private-file.c level_0/file/common.c build_sources_library level_0/fss.c level_0/private-fss.c level_0/fss/common.c level_0/fss/named.c level_0/fss/nest.c level_0/fss/set.c build_sources_library level_0/iki.c level_0/iki/common.c level_0/iki/data.c level_0/private-iki.c level_0/iki/private-data.c -build_sources_library level_0/limit.c +build_sources_library level_0/limit.c level_0/limit/set.c level_0/limit/value.c level_0/limit/private-set.c level_0/limit/private-value.c build_sources_library level_0/memory.c level_0/private-memory.c level_0/memory/structure.c build_sources_library level_0/path.c level_0/private-path.c level_0/path/common.c build_sources_library level_0/pipe.c @@ -83,7 +83,7 @@ build_sources_headers level_0/execute.h level_0/execute/common.h build_sources_headers level_0/file.h level_0/file/common.h build_sources_headers level_0/fss.h level_0/fss/comment.h level_0/fss/common.h level_0/fss/delimit.h level_0/fss/named.h level_0/fss/nest.h level_0/fss/quote.h level_0/fss/set.h build_sources_headers level_0/iki.h level_0/iki/common.h level_0/iki/data.h -build_sources_headers level_0/limit.h level_0/limit/common.h +build_sources_headers level_0/limit.h level_0/limit/set.h level_0/limit/value.h build_sources_headers level_0/memory.h level_0/memory/structure.h level_0/memory/common.h build_sources_headers level_0/path.h level_0/path/common.h build_sources_headers level_0/pipe.h diff --git a/level_0/f_limit/c/limit.c b/level_0/f_limit/c/limit.c index 96cd5af..474332f 100644 --- a/level_0/f_limit/c/limit.c +++ b/level_0/f_limit/c/limit.c @@ -23,56 +23,6 @@ extern "C" { } #endif // _di_f_limit_process_ -#ifndef _di_f_limit_sets_copy_ - f_status_t f_limit_sets_copy(const f_limit_sets_t source, f_limit_sets_t * const destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - destination->used = 0; - - if (source.used > destination->size) { - f_status_t status = F_none; - - macro_f_memory_structure_resize(status, (*destination), f_limit_set_t, source.used) - if (F_status_is_error(status)) return status; - } - - for (f_array_length_t i = 0; i < source.used; ++i) { - - destination->array[i].type = source.array[i].type; - destination->array[i].value = source.array[i].value; - } // for - - return F_none; - } -#endif // _di_f_limit_sets_copy_ - -#ifndef _di_f_limit_values_copy_ - f_status_t f_limit_values_copy(const f_limit_values_t source, f_limit_values_t * const destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - destination->used = 0; - - if (source.used > destination->size) { - f_status_t status = F_none; - - macro_f_memory_structure_resize(status, (*destination), f_limit_value_t, source.used) - if (F_status_is_error(status)) return status; - } - - for (f_array_length_t i = 0; i < source.used; ++i) { - - destination->array[i].rlim_cur = source.array[i].rlim_cur; - destination->array[i].rlim_max = source.array[i].rlim_max; - } // for - - return F_none; - } -#endif // _di_f_limit_values_copy_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_limit/c/limit.h b/level_0/f_limit/c/limit.h index 682dad1..287fb9a 100644 --- a/level_0/f_limit/c/limit.h +++ b/level_0/f_limit/c/limit.h @@ -23,7 +23,8 @@ #include // FLL-0 control includes. -#include +#include +#include #ifdef __cplusplus extern "C" { @@ -59,48 +60,6 @@ extern "C" { extern f_status_t f_limit_process(const pid_t id, const int type, const f_limit_value_t * const value_next, f_limit_value_t * const value_current); #endif // _di_f_limit_process_ -/** - * Copy the source limit sets onto the destination limit sets. - * - * @param source - * The source to append. - * @param destination - * The destination the source is appended onto. - * - * @return - * F_none on success. - * - * F_parameter (with error bit) if a parameter is invalid. - * - * Errors (with error bit) from: f_memory_structure_increase_by(). - * - * @see f_memory_structure_increase_by() - */ -#ifndef _di_f_limit_sets_copy_ - extern f_status_t f_limit_sets_copy(const f_limit_sets_t source, f_limit_sets_t * const destination); -#endif // _di_f_limit_sets_copy_ - -/** - * Copy the source limit values onto the destination limit values. - * - * @param source - * The source to append. - * @param destination - * The destination the source is appended onto. - * - * @return - * F_none on success. - * - * F_parameter (with error bit) if a parameter is invalid. - * - * Errors (with error bit) from: f_memory_structure_increase_by(). - * - * @see f_memory_structure_increase_by() - */ -#ifndef _di_f_limit_values_copy_ - extern f_status_t f_limit_values_copy(const f_limit_values_t source, f_limit_values_t * const destination); -#endif // _di_f_limit_values_copy_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_limit/c/limit/common.h b/level_0/f_limit/c/limit/common.h deleted file mode 100644 index 4d7e1ee..0000000 --- a/level_0/f_limit/c/limit/common.h +++ /dev/null @@ -1,130 +0,0 @@ -/** - * FLL - Level 0 - * - * Project: Limit - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - * - * Defines common data to be used for/by limit related functionality. - * - * This is auto-included by limit.h and should not need to be explicitly included. - */ -#ifndef _F_limit_common_h -#define _F_limit_common_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * A limit value structure. - * - * rlim_cur: The soft limit. - * rlim_max: The hard limit. - */ -#ifndef _di_f_limit_value_t_ - typedef struct rlimit f_limit_value_t; - - #define f_limit_value_t_initialize { 0, 0 } - - #define macro_f_limit_value_t_initialize(value) { value } - - #define macro_f_limit_value_t_clear(value) \ - value.rlim_cur = 0; \ - value.rlim_max = 0; -#endif // _di_f_limit_value_t_ - -/** - * An array of limit values. - * - * array: An array of limit values. - * size: Total amount of allocated space. - * used: Total number of allocated spaces used. - */ -#ifndef _di_f_limit_values_t_ - typedef struct { - f_limit_value_t *array; - - f_array_length_t size; - f_array_length_t used; - } f_limit_values_t; - - #define f_limit_values_t_initialize { 0, 0, 0 } - - #define macro_f_limit_values_t_initialize(content, size, used) { array, size, used } - #define macro_f_limit_values_t_initialize2(array, length) { array, length, length } - - #define macro_f_limit_values_t_clear(values) macro_f_memory_structure_clear(values) - - #define macro_f_limit_values_t_resize(status, values, length) macro_f_memory_structure_resize(status, values, f_limit_value_t, length) - #define macro_f_limit_values_t_adjust(status, values, length) macro_f_memory_structure_adjust(status, values, f_limit_value_t, length) - - #define macro_f_limit_values_t_delete_simple(values) macro_f_memory_structure_delete_simple(values, f_limit_value_t) - #define macro_f_limit_values_t_destroy_simple(values) macro_f_memory_structure_destroy_simple(values, f_limit_value_t) - - #define macro_f_limit_values_t_increase(status, step, values) macro_f_memory_structure_increase(status, step, values, f_limit_value_t) - #define macro_f_limit_values_t_increase_by(status, values, amount) macro_f_memory_structure_increase_by(status, values, f_limit_value_t, amount) - #define macro_f_limit_values_t_decrease_by(status, values, amount) macro_f_memory_structure_decrease_by(status, values, f_limit_value_t, amount) - #define macro_f_limit_values_t_decimate_by(status, values, amount) macro_f_memory_structure_decimate_by(status, values, f_limit_value_t, amount) -#endif // _di_f_limit_values_t_ - -/** - * A limit value structure. - * - * type: The limit resource type code. - * value: The limit value containing the soft and hard limit. - */ -#ifndef _di_f_limit_set_t_ - typedef struct { - int type; - f_limit_value_t value; - } f_limit_set_t; - - #define f_limit_set_t_initialize { 0, 0 } - - #define macro_f_limit_set_t_initialize(type, value) { type, value } - - #define macro_f_limit_set_t_clear(set) \ - set.type = 0; \ - set.value = 0; -#endif // _di_f_limit_set_t_ - -/** - * An array of limit sets. - * - * array: An array of limit sets. - * size: Total amount of allocated space. - * used: Total number of allocated spaces used. - */ -#ifndef _di_f_limit_sets_t_ - typedef struct { - f_limit_set_t *array; - - f_array_length_t size; - f_array_length_t used; - } f_limit_sets_t; - - #define f_limit_sets_t_initialize { 0, 0, 0 } - - #define macro_f_limit_sets_t_initialize(content, size, used) { array, size, used } - #define macro_f_limit_sets_t_initialize2(array, length) { array, length, length } - - #define macro_f_limit_sets_t_clear(sets) macro_f_memory_structure_clear(sets) - - #define macro_f_limit_sets_t_resize(status, sets, length) macro_f_memory_structure_resize(status, sets, f_limit_set_t, length) - #define macro_f_limit_sets_t_adjust(status, sets, length) macro_f_memory_structure_adjust(status, sets, f_limit_set_t, length) - - #define macro_f_limit_sets_t_delete_simple(sets) macro_f_memory_structure_delete_simple(sets, f_limit_set_t) - #define macro_f_limit_sets_t_destroy_simple(sets) macro_f_memory_structure_destroy_simple(sets, f_limit_set_t) - - #define macro_f_limit_sets_t_increase(status, step, sets) macro_f_memory_structure_increase(status, step, sets, f_limit_set_t) - #define macro_f_limit_sets_t_increase_by(status, sets, amount) macro_f_memory_structure_increase_by(status, sets, f_limit_set_t, amount) - #define macro_f_limit_sets_t_decrease_by(status, sets, amount) macro_f_memory_structure_decrease_by(status, sets, f_limit_set_t, amount) - #define macro_f_limit_sets_t_decimate_by(status, sets, amount) macro_f_memory_structure_decimate_by(status, sets, f_limit_set_t, amount) -#endif // _di_f_limit_sets_t_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _F_limit_common_h diff --git a/level_0/f_limit/c/limit/private-set.c b/level_0/f_limit/c/limit/private-set.c new file mode 100644 index 0000000..ab8640e --- /dev/null +++ b/level_0/f_limit/c/limit/private-set.c @@ -0,0 +1,127 @@ +#include "../limit.h" +#include "set.h" +#include "private-set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_limit_sets_adjust_) || !defined(_di_f_limit_sets_decimate_by_) + f_status_t private_f_limit_sets_adjust(const f_array_length_t length, f_limit_sets_t *sets) { + + const f_status_t status = f_memory_adjust(sets->size, length, sizeof(f_limit_set_t), (void **) & sets->array); + if (F_status_is_error(status)) return status; + + sets->size = length; + + if (sets->used > sets->size) { + sets->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_sets_adjust_) || !defined(_di_f_limit_sets_decimate_by_) + +#if !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_setss_append_) + extern f_status_t private_f_limit_sets_append(const f_limit_set_t source, f_limit_sets_t *destination) { + + if (destination->used + 1 > destination->size) { + const f_status_t status = private_f_limit_sets_adjust(destination->used + F_memory_default_allocation_small_d, destination); + if (F_status_is_error(status)) return status; + } + + destination->array[destination->used++] = source; + + return F_none; + } +#endif // !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_setss_append_) + +#if !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_append_all_) || !defined(_di_f_limit_setss_append_all_) + extern f_status_t private_f_limit_sets_append_all(const f_limit_sets_t source, f_limit_sets_t *destination) { + + if (destination->used + source.used > destination->size) { + const f_status_t status = private_f_limit_sets_adjust(destination->used + source.used, destination); + if (F_status_is_error(status)) return status; + } + + for (f_array_length_t i = 0; i < source.used; ++i) { + destination->array[destination->used++] = source.array[i]; + } // for + + return F_none; + } +#endif // !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_append_all_) || !defined(_di_f_limit_setss_append_all_) + +#if !defined(_di_f_limit_sets_resize_) || !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_decimate_by_) || !defined(_di_f_limit_setss_append_) + f_status_t private_f_limit_sets_resize(const f_array_length_t length, f_limit_sets_t *sets) { + + const f_status_t status = f_memory_resize(sets->size, length, sizeof(f_limit_set_t), (void **) & sets->array); + if (F_status_is_error(status)) return status; + + sets->size = length; + + if (sets->used > sets->size) { + sets->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_sets_resize_) || !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_decimate_by_) || !defined(_di_f_limit_setss_append_) + +#if !defined(_di_f_limit_setss_adjust_) || !defined(_di_f_limit_setss_decimate_by_) + f_status_t private_f_limit_setss_adjust(const f_array_length_t length, f_limit_setss_t *setss) { + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < setss->size; ++i) { + + status = f_memory_destroy(setss->array[i].size, sizeof(f_limit_sets_t), (void **) & setss->array[i].array); + if (F_status_is_error(status)) return status; + + setss->array[i].size = 0; + setss->array[i].used = 0; + } // for + + status = f_memory_adjust(setss->size, length, sizeof(f_limit_sets_t), (void **) & setss->array); + if (F_status_is_error(status)) return status; + + setss->size = length; + + if (setss->used > setss->size) { + setss->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_setss_adjust_) || !defined(_di_f_limit_setss_decimate_by_) + +#if !defined(_di_f_limit_setss_decrease_by_) || !defined(_di_f_limit_setss_increase_) || !defined(_di_f_limit_setss_increase_by_) || !defined(_di_f_limit_setss_resize_) + f_status_t private_f_limit_setss_resize(const f_array_length_t length, f_limit_setss_t *setss) { + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < setss->size; ++i) { + + status = f_memory_delete(setss->array[i].size, sizeof(f_limit_sets_t), (void **) & setss->array[i].array); + if (F_status_is_error(status)) return status; + + setss->array[i].size = 0; + setss->array[i].used = 0; + } // for + + status = f_memory_resize(setss->size, length, sizeof(f_limit_sets_t), (void **) & setss->array); + if (F_status_is_error(status)) return status; + + setss->size = length; + + if (setss->used > setss->size) { + setss->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_setss_decrease_by_) || !defined(_di_f_limit_setss_increase_) || !defined(_di_f_limit_setss_increase_by_) || !defined(_di_f_limit_setss_resize_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_limit/c/limit/private-set.h b/level_0/f_limit/c/limit/private-set.h new file mode 100644 index 0000000..2bc1210 --- /dev/null +++ b/level_0/f_limit/c/limit/private-set.h @@ -0,0 +1,175 @@ +/** + * FLL - Level 0 + * + * Project: Limit + * API Version: 0.5 + * 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_limit_set_h +#define _PRIVATE_F_limit_set_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation for resizing the sets array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to adjust to. + * @param sets + * The sets array to adjust. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_limit_sets_adjust() + * @see f_limit_sets_decimate_by() + */ +#if !defined(_di_f_limit_sets_adjust_) || !defined(_di_f_limit_sets_decimate_by_) + extern f_status_t private_f_limit_sets_adjust(const f_array_length_t length, f_limit_sets_t *sets) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_sets_adjust_) || !defined(_di_f_limit_sets_decimate_by_) + +/** + * Private implementation for appending the set array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source set to append. + * @param destination + * The destination lengths the source is appended onto. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_limit_sets_append() + * @see f_limit_setss_append() + */ +#if !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_setss_append_) + extern f_status_t private_f_limit_sets_append(const f_limit_set_t source, f_limit_sets_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_setss_append_) + +/** + * Private implementation for appending the set array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source sets to append. + * @param destination + * The destination lengths the source is appended onto. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_limit_sets_append_all() + * @see f_limit_setss_append() + * @see f_limit_setss_append_all() + */ +#if !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_append_all_) || !defined(_di_f_limit_setss_append_all_) + extern f_status_t private_f_limit_sets_append_all(const f_limit_sets_t source, f_limit_sets_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_append_all_) || !defined(_di_f_limit_setss_append_all_) + +/** + * Private implementation for resizing the sets array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to adjust to. + * @param sets + * The sets array to adjust. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_limit_sets_resize() + * @see f_limit_sets_append() + * @see f_limit_sets_decimate_by() + * @see f_limit_setss_append() + */ +#if !defined(_di_f_limit_sets_resize_) || !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_decimate_by_) || !defined(_di_f_limit_setss_append_) + extern f_status_t private_f_limit_sets_resize(const f_array_length_t length, f_limit_sets_t *sets) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_sets_resize_) || !defined(_di_f_limit_sets_append_) || !defined(_di_f_limit_sets_decimate_by_) || !defined(_di_f_limit_setss_append_) + +/** + * Private implementation for resizing the setss array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to adjust to. + * @param setss + * The setss array to adjust. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if new length is larger than max array length. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + * Errors (with error bit) from: f_memory_destroy(). + * + * @see f_limit_setss_adjust() + * @see f_limit_setss_decimate_by() + */ +#if !defined(_di_f_limit_setss_adjust_) || !defined(_di_f_limit_setss_decimate_by_) + extern f_status_t private_f_limit_setss_adjust(const f_array_length_t length, f_limit_setss_t *setss) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_setss_adjust_) || !defined(_di_f_limit_setss_decimate_by_) + +/** + * Private implementation for resizing the setss array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to resize to. + * @param setss + * The setss array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if new length is larger than max array length. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_delete(). + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_limit_setss_decrease_by() + * @see f_limit_setss_increase() + * @see f_limit_setss_increase_by() + * @see f_limit_setss_resize() + */ +#if !defined(_di_f_limit_setss_decrease_by_) || !defined(_di_f_limit_setss_increase_) || !defined(_di_f_limit_setss_increase_by_) || !defined(_di_f_limit_setss_resize_) + extern f_status_t private_f_limit_setss_resize(const f_array_length_t length, f_limit_setss_t *setss) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_setss_decrease_by_) || !defined(_di_f_limit_setss_increase_) || !defined(_di_f_limit_setss_increase_by_) || !defined(_di_f_limit_setss_resize_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_limit_set_h diff --git a/level_0/f_limit/c/limit/private-value.c b/level_0/f_limit/c/limit/private-value.c new file mode 100644 index 0000000..1cdb62d --- /dev/null +++ b/level_0/f_limit/c/limit/private-value.c @@ -0,0 +1,127 @@ +#include "../limit.h" +#include "value.h" +#include "private-value.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_limit_values_adjust_) || !defined(_di_f_limit_values_decimate_by_) + f_status_t private_f_limit_values_adjust(const f_array_length_t length, f_limit_values_t *values) { + + const f_status_t status = f_memory_adjust(values->size, length, sizeof(f_limit_value_t), (void **) & values->array); + if (F_status_is_error(status)) return status; + + values->size = length; + + if (values->used > values->size) { + values->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_values_adjust_) || !defined(_di_f_limit_values_decimate_by_) + +#if !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_valuess_append_) + extern f_status_t private_f_limit_values_append(const f_limit_value_t source, f_limit_values_t *destination) { + + if (destination->used + 1 > destination->size) { + const f_status_t status = private_f_limit_values_adjust(destination->used + F_memory_default_allocation_small_d, destination); + if (F_status_is_error(status)) return status; + } + + destination->array[destination->used++] = source; + + return F_none; + } +#endif // !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_valuess_append_) + +#if !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_append_all_) || !defined(_di_f_limit_valuess_append_all_) + extern f_status_t private_f_limit_values_append_all(const f_limit_values_t source, f_limit_values_t *destination) { + + if (destination->used + source.used > destination->size) { + const f_status_t status = private_f_limit_values_adjust(destination->used + source.used, destination); + if (F_status_is_error(status)) return status; + } + + for (f_array_length_t i = 0; i < source.used; ++i) { + destination->array[destination->used++] = source.array[i]; + } // for + + return F_none; + } +#endif // !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_append_all_) || !defined(_di_f_limit_valuess_append_all_) + +#if !defined(_di_f_limit_values_resize_) || !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_decimate_by_) || !defined(_di_f_limit_valuess_append_) + f_status_t private_f_limit_values_resize(const f_array_length_t length, f_limit_values_t *values) { + + const f_status_t status = f_memory_resize(values->size, length, sizeof(f_limit_value_t), (void **) & values->array); + if (F_status_is_error(status)) return status; + + values->size = length; + + if (values->used > values->size) { + values->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_values_resize_) || !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_decimate_by_) || !defined(_di_f_limit_valuess_append_) + +#if !defined(_di_f_limit_valuess_adjust_) || !defined(_di_f_limit_valuess_decimate_by_) + f_status_t private_f_limit_valuess_adjust(const f_array_length_t length, f_limit_valuess_t *valuess) { + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < valuess->size; ++i) { + + status = f_memory_destroy(valuess->array[i].size, sizeof(f_limit_values_t), (void **) & valuess->array[i].array); + if (F_status_is_error(status)) return status; + + valuess->array[i].size = 0; + valuess->array[i].used = 0; + } // for + + status = f_memory_adjust(valuess->size, length, sizeof(f_limit_values_t), (void **) & valuess->array); + if (F_status_is_error(status)) return status; + + valuess->size = length; + + if (valuess->used > valuess->size) { + valuess->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_valuess_adjust_) || !defined(_di_f_limit_valuess_decimate_by_) + +#if !defined(_di_f_limit_valuess_decrease_by_) || !defined(_di_f_limit_valuess_increase_) || !defined(_di_f_limit_valuess_increase_by_) || !defined(_di_f_limit_valuess_resize_) + f_status_t private_f_limit_valuess_resize(const f_array_length_t length, f_limit_valuess_t *valuess) { + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < valuess->size; ++i) { + + status = f_memory_delete(valuess->array[i].size, sizeof(f_limit_values_t), (void **) & valuess->array[i].array); + if (F_status_is_error(status)) return status; + + valuess->array[i].size = 0; + valuess->array[i].used = 0; + } // for + + status = f_memory_resize(valuess->size, length, sizeof(f_limit_values_t), (void **) & valuess->array); + if (F_status_is_error(status)) return status; + + valuess->size = length; + + if (valuess->used > valuess->size) { + valuess->used = length; + } + + return F_none; + } +#endif // !defined(_di_f_limit_valuess_decrease_by_) || !defined(_di_f_limit_valuess_increase_) || !defined(_di_f_limit_valuess_increase_by_) || !defined(_di_f_limit_valuess_resize_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_limit/c/limit/private-value.h b/level_0/f_limit/c/limit/private-value.h new file mode 100644 index 0000000..e739b1c --- /dev/null +++ b/level_0/f_limit/c/limit/private-value.h @@ -0,0 +1,175 @@ +/** + * FLL - Level 0 + * + * Project: Limit + * API Version: 0.5 + * 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_limit_value_h +#define _PRIVATE_F_limit_value_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation for resizing the values array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to adjust to. + * @param values + * The values array to adjust. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_limit_values_adjust() + * @see f_limit_values_decimate_by() + */ +#if !defined(_di_f_limit_values_adjust_) || !defined(_di_f_limit_values_decimate_by_) + extern f_status_t private_f_limit_values_adjust(const f_array_length_t length, f_limit_values_t *values) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_values_adjust_) || !defined(_di_f_limit_values_decimate_by_) + +/** + * Private implementation for appending the value array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source value to append. + * @param destination + * The destination lengths the source is appended onto. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_limit_values_append() + * @see f_limit_valuess_append() + */ +#if !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_valuess_append_) + extern f_status_t private_f_limit_values_append(const f_limit_value_t source, f_limit_values_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_valuess_append_) + +/** + * Private implementation for appending the value array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source values to append. + * @param destination + * The destination lengths the source is appended onto. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_limit_values_append_all() + * @see f_limit_valuess_append() + * @see f_limit_valuess_append_all() + */ +#if !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_append_all_) || !defined(_di_f_limit_valuess_append_all_) + extern f_status_t private_f_limit_values_append_all(const f_limit_values_t source, f_limit_values_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_append_all_) || !defined(_di_f_limit_valuess_append_all_) + +/** + * Private implementation for resizing the values array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to adjust to. + * @param values + * The values array to adjust. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_limit_values_resize() + * @see f_limit_values_append() + * @see f_limit_values_decimate_by() + * @see f_limit_valuess_append() + */ +#if !defined(_di_f_limit_values_resize_) || !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_decimate_by_) || !defined(_di_f_limit_valuess_append_) + extern f_status_t private_f_limit_values_resize(const f_array_length_t length, f_limit_values_t *values) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_values_resize_) || !defined(_di_f_limit_values_append_) || !defined(_di_f_limit_values_decimate_by_) || !defined(_di_f_limit_valuess_append_) + +/** + * Private implementation for resizing the valuess array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to adjust to. + * @param valuess + * The valuess array to adjust. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if new length is larger than max array length. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + * Errors (with error bit) from: f_memory_destroy(). + * + * @see f_limit_valuess_adjust() + * @see f_limit_valuess_decimate_by() + */ +#if !defined(_di_f_limit_valuess_adjust_) || !defined(_di_f_limit_valuess_decimate_by_) + extern f_status_t private_f_limit_valuess_adjust(const f_array_length_t length, f_limit_valuess_t *valuess) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_valuess_adjust_) || !defined(_di_f_limit_valuess_decimate_by_) + +/** + * Private implementation for resizing the valuess array. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The length to resize to. + * @param valuess + * The valuess array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if new length is larger than max array length. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_delete(). + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_limit_valuess_decrease_by() + * @see f_limit_valuess_increase() + * @see f_limit_valuess_increase_by() + * @see f_limit_valuess_resize() + */ +#if !defined(_di_f_limit_valuess_decrease_by_) || !defined(_di_f_limit_valuess_increase_) || !defined(_di_f_limit_valuess_increase_by_) || !defined(_di_f_limit_valuess_resize_) + extern f_status_t private_f_limit_valuess_resize(const f_array_length_t length, f_limit_valuess_t *valuess) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_limit_valuess_decrease_by_) || !defined(_di_f_limit_valuess_increase_) || !defined(_di_f_limit_valuess_increase_by_) || !defined(_di_f_limit_valuess_resize_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_limit_value_h diff --git a/level_0/f_limit/c/limit/set.c b/level_0/f_limit/c/limit/set.c new file mode 100644 index 0000000..51e2583 --- /dev/null +++ b/level_0/f_limit/c/limit/set.c @@ -0,0 +1,290 @@ +#include "../limit.h" +#include "set.h" +#include "private-set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_limit_sets_adjust_ + f_status_t f_limit_sets_adjust(const f_array_length_t length, f_limit_sets_t *sets) { + #ifndef _di_level_0_parameter_checking_ + if (!sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_sets_adjust(length, sets); + } +#endif // _di_f_limit_sets_adjust_ + +#ifndef _di_f_limit_sets_append_ + f_status_t f_limit_sets_append(const f_limit_set_t source, f_limit_sets_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_sets_append(source, destination); + } +#endif // _di_f_limit_sets_append_ + +#ifndef _di_f_limit_sets_append_all_ + f_status_t f_limit_sets_append_all(const f_limit_sets_t source, f_limit_sets_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + return private_f_limit_sets_append_all(source, destination); + } +#endif // _di_f_limit_sets_append_all_ + +#ifndef _di_f_limit_sets_decimate_by_ + f_status_t f_limit_sets_decimate_by(const f_array_length_t amount, f_limit_sets_t *sets) { + #ifndef _di_level_0_parameter_checking_ + if (!sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (sets->size - amount > 0) { + return private_f_limit_sets_adjust(sets->size - amount, sets); + } + + return private_f_limit_sets_adjust(0, sets); + } +#endif // _di_f_limit_sets_decimate_by_ + +#ifndef _di_f_limit_sets_decrease_by_ + f_status_t f_limit_sets_decrease_by(const f_array_length_t amount, f_limit_sets_t *sets) { + #ifndef _di_level_0_parameter_checking_ + if (!sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (sets->size - amount > 0) { + return private_f_limit_sets_resize(sets->size - amount, sets); + } + + return private_f_limit_sets_resize(0, sets); + } +#endif // _di_f_limit_sets_decrease_by_ + +#ifndef _di_f_limit_sets_increase_ + f_status_t f_limit_sets_increase(const f_array_length_t step, f_limit_sets_t *sets) { + #ifndef _di_level_0_parameter_checking_ + if (!sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (step && sets->used + 1 > sets->size) { + f_array_length_t size = sets->used + step; + + if (size > F_array_length_t_size_d) { + if (sets->used + 1 > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + size = F_array_length_t_size_d; + } + + return private_f_limit_sets_resize(size, sets); + } + + return F_data_not; + } +#endif // _di_f_limit_sets_increase_ + +#ifndef _di_f_limit_sets_increase_by_ + f_status_t f_limit_sets_increase_by(const f_array_length_t amount, f_limit_sets_t *sets) { + #ifndef _di_level_0_parameter_checking_ + if (!sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (sets->used + amount > sets->size) { + if (sets->used + amount > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + return private_f_limit_sets_resize(sets->used + amount, sets); + } + + return F_data_not; + } +#endif // _di_f_limit_sets_increase_by_ + +#ifndef _di_f_limit_sets_resize_ + f_status_t f_limit_sets_resize(const f_array_length_t length, f_limit_sets_t *sets) { + #ifndef _di_level_0_parameter_checking_ + if (!sets) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_sets_resize(length, sets); + } +#endif // _di_f_limit_sets_resize_ + +#ifndef _di_f_limit_setss_adjust_ + f_status_t f_limit_setss_adjust(const f_array_length_t length, f_limit_setss_t *setss) { + #ifndef _di_level_0_parameter_checking_ + if (!setss) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_setss_adjust(length, setss); + } +#endif // _di_f_limit_setss_adjust_ + +#ifndef _di_f_limit_setss_append_ + f_status_t f_limit_setss_append(const f_limit_sets_t source, f_limit_setss_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + f_status_t status = F_none; + + if (destination->used + 1 > destination->size) { + status = private_f_limit_setss_resize(destination->used + F_memory_default_allocation_small_d, destination); + if (F_status_is_error(status)) return status; + } + + status = private_f_limit_sets_append_all(source, &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + + ++destination->used; + + return F_none; + } +#endif // _di_f_limit_setss_append_ + +#ifndef _di_f_limit_setss_append_all_ + f_status_t f_limit_setss_append_all(const f_limit_setss_t source, f_limit_setss_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + f_status_t status = F_none; + + if (destination->used + source.used > destination->size) { + status = private_f_limit_setss_resize(destination->used + source.used, destination); + if (F_status_is_error(status)) return status; + } + + for (f_array_length_t i = 0; i < source.used; ++i, ++destination->used) { + + destination->array[destination->used].used = 0; + + if (source.array[i].used) { + status = private_f_limit_sets_append_all(source.array[i], &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + } + } // for + + return F_none; + } +#endif // _di_f_limit_setss_append_all_ + +#ifndef _di_f_limit_setss_decimate_by_ + f_status_t f_limit_setss_decimate_by(const f_array_length_t amount, f_limit_setss_t *setss) { + #ifndef _di_level_0_parameter_checking_ + if (!setss) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (setss->size - amount > 0) { + return private_f_limit_setss_adjust(setss->size - amount, setss); + } + + return private_f_limit_setss_adjust(0, setss); + } +#endif // _di_f_limit_setss_decimate_by_ + +#ifndef _di_f_limit_setss_decrease_by_ + f_status_t f_limit_setss_decrease_by(const f_array_length_t amount, f_limit_setss_t *setss) { + #ifndef _di_level_0_parameter_checking_ + if (!setss) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (setss->size - amount > 0) { + return private_f_limit_setss_resize(setss->size - amount, setss); + } + + return private_f_limit_setss_resize(0, setss); + } +#endif // _di_f_limit_setss_decrease_by_ + +#ifndef _di_f_limit_setss_increase_ + f_status_t f_limit_setss_increase(const f_array_length_t step, f_limit_setss_t *setss) { + #ifndef _di_level_0_parameter_checking_ + if (!setss) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (step && setss->used + 1 > setss->size) { + f_array_length_t size = setss->used + step; + + if (size > F_array_length_t_size_d) { + if (setss->used + 1 > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + size = F_array_length_t_size_d; + } + + return private_f_limit_setss_resize(size, setss); + } + + return F_data_not; + } +#endif // _di_f_limit_setss_increase_ + +#ifndef _di_f_limit_setss_increase_by_ + f_status_t f_limit_setss_increase_by(const f_array_length_t amount, f_limit_setss_t *setss) { + #ifndef _di_level_0_parameter_checking_ + if (!setss) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (setss->used + amount > setss->size) { + if (setss->used + amount > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + return private_f_limit_setss_resize(setss->used + amount, setss); + } + + return F_data_not; + } +#endif // _di_f_limit_setss_increase_by_ + +#ifndef _di_f_limit_setss_resize_ + f_status_t f_limit_setss_resize(const f_array_length_t length, f_limit_setss_t *setss) { + #ifndef _di_level_0_parameter_checking_ + if (!setss) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_setss_resize(length, setss); + } +#endif // _di_f_limit_setss_resize_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_limit/c/limit/set.h b/level_0/f_limit/c/limit/set.h new file mode 100644 index 0000000..1eaf2d5 --- /dev/null +++ b/level_0/f_limit/c/limit/set.h @@ -0,0 +1,466 @@ +/** + * FLL - Level 0 + * + * Project: Limit + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Defines common data to be used for/by limit related functionality. + * + * This is auto-included by limit.h and should not need to be explicitly included. + */ +#ifndef _F_limit_set_h +#define _F_limit_set_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A limit value structure. + * + * type: The limit resource type code. + * value: The limit value containing the soft and hard limit. + */ +#ifndef _di_f_limit_set_t_ + typedef struct { + int type; + f_limit_value_t value; + } f_limit_set_t; + + #define f_limit_set_t_initialize { 0, f_limit_value_t_initialize } + + #define macro_f_limit_set_t_initialize(type, value) { type, value } + + #define macro_f_limit_set_t_clear(set) \ + set.type = 0; \ + macro_f_limit_value_t_clear(set.value); +#endif // _di_f_limit_set_t_ + +/** + * An array of limit sets. + * + * array: An array of limit sets. + * size: Total amount of allocated space. + * used: Total number of allocated spaces used. + */ +#ifndef _di_f_limit_sets_t_ + typedef struct { + f_limit_set_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_limit_sets_t; + + #define f_limit_sets_t_initialize { 0, 0, 0 } + + #define macro_f_limit_sets_t_initialize(array, size, used) { array, size, used } + #define macro_f_limit_sets_t_initialize2(array, length) { array, length, length } + + #define macro_f_limit_sets_t_clear(sets) macro_f_memory_structure_clear(sets) + + #define macro_f_limit_sets_t_resize(status, sets, length) status = f_limit_sets_resize(length, &sets); + #define macro_f_limit_sets_t_adjust(status, sets, length) status = f_limit_sets_adjust(length, &sets); + + #define macro_f_limit_sets_t_delete_simple(sets) f_limit_sets_resize(0, &sets); + #define macro_f_limit_sets_t_destroy_simple(sets) f_limit_sets_adjust(0, &sets); + + #define macro_f_limit_sets_t_increase(status, step, sets) status = f_limit_sets_increase(step, &sets); + #define macro_f_limit_sets_t_increase_by(status, sets, amount) status = f_limit_sets_increase_by(amount, &sets); + #define macro_f_limit_sets_t_decrease_by(status, sets, amount) status = f_limit_sets_decrease_by(amount, &sets); + #define macro_f_limit_sets_t_decimate_by(status, sets, amount) status = f_limit_sets_decimate_by(amount, &sets); +#endif // _di_f_limit_sets_t_ + +/** + * This holds an array of f_limit_sets_t. + * + * array: An array of f_limit_sets_t. + * size: Total amount of allocated space. + * used: Total number of allocated spaces used. + */ +#ifndef _di_f_limit_setss_t_ + typedef struct { + f_limit_sets_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_limit_setss_t; + + #define f_limit_setss_t_initialize { 0, 0, 0 } + + #define macro_f_limit_setss_t_initialize(array, size, used) { array, size, used } + #define macro_f_limit_setss_t_initialize2(array, length) { array, length, length } + + #define macro_f_limit_setss_t_clear(setss) macro_f_memory_structure_clear(setss); + + #define macro_f_limit_setss_t_resize(status, setss, length) status = f_limit_setss_resize(length, &setss); + #define macro_f_limit_setss_t_adjust(status, setss, length) status = f_limit_setss_adjust(length, &setss); + + #define macro_f_limit_setss_t_delete_simple(setss) f_limit_setss_resize(0, &setss); + #define macro_f_limit_setss_t_destroy_simple(setss) f_limit_setss_adjust(0, &setss); + + #define macro_f_limit_setss_t_increase(status, step, setss) status = f_limit_setss_increase(step, &setss); + #define macro_f_limit_setss_t_increase_by(status, setss, amount) status = f_limit_setss_increase_by(amount, &setss); + #define macro_f_limit_setss_t_decrease_by(status, setss, amount) status = f_limit_setss_decrease_by(amount, &setss); + #define macro_f_limit_setss_t_decimate_by(status, setss, amount) status = f_limit_setss_decimate_by(amount, &setss); +#endif // _di_f_limit_setss_t_ + +/** + * Resize the sets array. + * + * @param length + * The new size to use. + * @param sets + * The sets array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + */ +#ifndef _di_f_limit_sets_adjust_ + extern f_status_t f_limit_sets_adjust(const f_array_length_t length, f_limit_sets_t *sets); +#endif // _di_f_limit_sets_adjust_ + +/** + * Append the single source set onto the destination. + * + * @param source + * The source set to append. + * @param destination + * The destination sets the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_sets_append_ + extern f_status_t f_limit_sets_append(const f_limit_set_t source, f_limit_sets_t *destination); +#endif // _di_f_limit_sets_append_ + +/** + * Append the source sets onto the destination. + * + * @param source + * The source sets to append. + * @param destination + * The destination sets the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_sets_append_all_ + extern f_status_t f_limit_sets_append_all(const f_limit_sets_t source, f_limit_sets_t *destination); +#endif // _di_f_limit_sets_append_all_ + +/** + * Resize the sets array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to les than 0. + * + * @param amount + * A positive number representing how much to decimate the size by. + * @param sets + * The sets array to resize. + * + * @return + * F_none on success. + * F_data_not if amount is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + */ +#ifndef _di_f_limit_sets_decimate_by_ + extern f_status_t f_limit_sets_decimate_by(const f_array_length_t amount, f_limit_sets_t *sets); +#endif // _di_f_limit_sets_decimate_by_ + +/** + * Resize the sets array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to les than 0. + * + * @param amount + * A positive number representing how much to decrease the size by. + * @param sets + * The sets array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_sets_decrease_by_ + extern f_status_t f_limit_sets_decrease_by(const f_array_length_t amount, f_limit_sets_t *sets); +#endif // _di_f_limit_sets_decrease_by_ + +/** + * Increase the size of the sets array, but only if necesary. + * + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param step + * The allocation step to use. + * Must be greater than 0. + * @param sets + * The sets array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_sets_increase_ + extern f_status_t f_limit_sets_increase(const f_array_length_t step, f_limit_sets_t *sets); +#endif // _di_f_limit_sets_increase_ + +/** + * Resize the sets array to a larger size. + * + * This will resize making the string larger based on the given length. + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param amount + * A positive number representing how much to increase the size by. + * @param sets + * The sets array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + amount <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_sets_increase_by_ + extern f_status_t f_limit_sets_increase_by(const f_array_length_t amount, f_limit_sets_t *sets); +#endif // _di_f_limit_sets_increase_by_ + +/** + * Resize the sets array. + * + * @param length + * The new size to use. + * @param sets + * The sets array to adjust. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_sets_resize_ + extern f_status_t f_limit_sets_resize(const f_array_length_t length, f_limit_sets_t *sets); +#endif // _di_f_limit_sets_resize_ + +/** + * Resize the setss array. + * + * @param length + * The new size to use. + * @param setss + * The setss array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + * Errors (with error bit) from: f_memory_destroy(). + */ +#ifndef _di_f_limit_setss_adjust_ + extern f_status_t f_limit_setss_adjust(const f_array_length_t length, f_limit_setss_t *setss); +#endif // _di_f_limit_setss_adjust_ + +/** + * Append the single source sets onto the destination. + * + * @param source + * The source sets to append. + * @param destination + * The destination ranges the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_setss_append_ + extern f_status_t f_limit_setss_append(const f_limit_sets_t source, f_limit_setss_t *destination); +#endif // _di_f_limit_setss_append_ + +/** + * Append the source setss onto the destination. + * + * @param source + * The source setss to append. + * @param destination + * The destination ranges the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_setss_append_all_ + extern f_status_t f_limit_setss_append_all(const f_limit_setss_t source, f_limit_setss_t *destination); +#endif // _di_f_limit_setss_append_all_ + +/** + * Resize the setss array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to less than 0. + * + * @param amount + * A positive number representing how much to decimate the size by. + * @param setss + * The setss array to resize. + * + * @return + * F_none on success. + * F_data_not if amount is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + * Errors (with error bit) from: f_memory_destroy(). + */ +#ifndef _di_f_limit_setss_decimate_by_ + extern f_status_t f_limit_setss_decimate_by(const f_array_length_t amount, f_limit_setss_t *setss); +#endif // _di_f_limit_setss_decimate_by_ + +/** + * Resize the setss array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to less than 0. + * + * @param amount + * A positive number representing how much to decrease the size by. + * @param setss + * The setss array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_delete(). + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_setss_decrease_by_ + extern f_status_t f_limit_setss_decrease_by(const f_array_length_t amount, f_limit_setss_t *setss); +#endif // _di_f_limit_setss_decrease_by_ + +/** + * Increase the size of the setss array, but only if necessary. + * + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param step + * The allocation step to use. + * Must be greater than 0. + * @param setss + * The setss array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_setss_increase_ + extern f_status_t f_limit_setss_increase(const f_array_length_t step, f_limit_setss_t *setss); +#endif // _di_f_limit_setss_increase_ + +/** + * Resize the setss array to a larger size. + * + * This will resize making the string larger based on the given length. + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param amount + * A positive number representing how much to increase the size by. + * @param setss + * The setss array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + amount <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_setss_increase_by_ + extern f_status_t f_limit_setss_increase_by(const f_array_length_t amount, f_limit_setss_t *setss); +#endif // _di_f_limit_setss_increase_by_ + +/** + * Resize the setss array. + * + * @param length + * The new size to use. + * @param setss + * The setss array to adjust. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_delete(). + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_setss_resize_ + extern f_status_t f_limit_setss_resize(const f_array_length_t length, f_limit_setss_t *setss); +#endif // _di_f_limit_setss_resize_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_limit_set_h diff --git a/level_0/f_limit/c/limit/value.c b/level_0/f_limit/c/limit/value.c new file mode 100644 index 0000000..01aa6ec --- /dev/null +++ b/level_0/f_limit/c/limit/value.c @@ -0,0 +1,290 @@ +#include "../limit.h" +#include "value.h" +#include "private-value.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_limit_values_adjust_ + f_status_t f_limit_values_adjust(const f_array_length_t length, f_limit_values_t *values) { + #ifndef _di_level_0_parameter_checking_ + if (!values) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_values_adjust(length, values); + } +#endif // _di_f_limit_values_adjust_ + +#ifndef _di_f_limit_values_append_ + f_status_t f_limit_values_append(const f_limit_value_t source, f_limit_values_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_values_append(source, destination); + } +#endif // _di_f_limit_values_append_ + +#ifndef _di_f_limit_values_append_all_ + f_status_t f_limit_values_append_all(const f_limit_values_t source, f_limit_values_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + return private_f_limit_values_append_all(source, destination); + } +#endif // _di_f_limit_values_append_all_ + +#ifndef _di_f_limit_values_decimate_by_ + f_status_t f_limit_values_decimate_by(const f_array_length_t amount, f_limit_values_t *values) { + #ifndef _di_level_0_parameter_checking_ + if (!values) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (values->size - amount > 0) { + return private_f_limit_values_adjust(values->size - amount, values); + } + + return private_f_limit_values_adjust(0, values); + } +#endif // _di_f_limit_values_decimate_by_ + +#ifndef _di_f_limit_values_decrease_by_ + f_status_t f_limit_values_decrease_by(const f_array_length_t amount, f_limit_values_t *values) { + #ifndef _di_level_0_parameter_checking_ + if (!values) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (values->size - amount > 0) { + return private_f_limit_values_resize(values->size - amount, values); + } + + return private_f_limit_values_resize(0, values); + } +#endif // _di_f_limit_values_decrease_by_ + +#ifndef _di_f_limit_values_increase_ + f_status_t f_limit_values_increase(const f_array_length_t step, f_limit_values_t *values) { + #ifndef _di_level_0_parameter_checking_ + if (!values) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (step && values->used + 1 > values->size) { + f_array_length_t size = values->used + step; + + if (size > F_array_length_t_size_d) { + if (values->used + 1 > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + size = F_array_length_t_size_d; + } + + return private_f_limit_values_resize(size, values); + } + + return F_data_not; + } +#endif // _di_f_limit_values_increase_ + +#ifndef _di_f_limit_values_increase_by_ + f_status_t f_limit_values_increase_by(const f_array_length_t amount, f_limit_values_t *values) { + #ifndef _di_level_0_parameter_checking_ + if (!values) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (values->used + amount > values->size) { + if (values->used + amount > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + return private_f_limit_values_resize(values->used + amount, values); + } + + return F_data_not; + } +#endif // _di_f_limit_values_increase_by_ + +#ifndef _di_f_limit_values_resize_ + f_status_t f_limit_values_resize(const f_array_length_t length, f_limit_values_t *values) { + #ifndef _di_level_0_parameter_checking_ + if (!values) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_values_resize(length, values); + } +#endif // _di_f_limit_values_resize_ + +#ifndef _di_f_limit_valuess_adjust_ + f_status_t f_limit_valuess_adjust(const f_array_length_t length, f_limit_valuess_t *valuess) { + #ifndef _di_level_0_parameter_checking_ + if (!valuess) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_valuess_adjust(length, valuess); + } +#endif // _di_f_limit_valuess_adjust_ + +#ifndef _di_f_limit_valuess_append_ + f_status_t f_limit_valuess_append(const f_limit_values_t source, f_limit_valuess_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + f_status_t status = F_none; + + if (destination->used + 1 > destination->size) { + status = private_f_limit_valuess_resize(destination->used + F_memory_default_allocation_small_d, destination); + if (F_status_is_error(status)) return status; + } + + status = private_f_limit_values_append_all(source, &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + + ++destination->used; + + return F_none; + } +#endif // _di_f_limit_valuess_append_ + +#ifndef _di_f_limit_valuess_append_all_ + f_status_t f_limit_valuess_append_all(const f_limit_valuess_t source, f_limit_valuess_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!source.used) return F_data_not; + + f_status_t status = F_none; + + if (destination->used + source.used > destination->size) { + status = private_f_limit_valuess_resize(destination->used + source.used, destination); + if (F_status_is_error(status)) return status; + } + + for (f_array_length_t i = 0; i < source.used; ++i, ++destination->used) { + + destination->array[destination->used].used = 0; + + if (source.array[i].used) { + status = private_f_limit_values_append_all(source.array[i], &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + } + } // for + + return F_none; + } +#endif // _di_f_limit_valuess_append_all_ + +#ifndef _di_f_limit_valuess_decimate_by_ + f_status_t f_limit_valuess_decimate_by(const f_array_length_t amount, f_limit_valuess_t *valuess) { + #ifndef _di_level_0_parameter_checking_ + if (!valuess) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (valuess->size - amount > 0) { + return private_f_limit_valuess_adjust(valuess->size - amount, valuess); + } + + return private_f_limit_valuess_adjust(0, valuess); + } +#endif // _di_f_limit_valuess_decimate_by_ + +#ifndef _di_f_limit_valuess_decrease_by_ + f_status_t f_limit_valuess_decrease_by(const f_array_length_t amount, f_limit_valuess_t *valuess) { + #ifndef _di_level_0_parameter_checking_ + if (!valuess) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (valuess->size - amount > 0) { + return private_f_limit_valuess_resize(valuess->size - amount, valuess); + } + + return private_f_limit_valuess_resize(0, valuess); + } +#endif // _di_f_limit_valuess_decrease_by_ + +#ifndef _di_f_limit_valuess_increase_ + f_status_t f_limit_valuess_increase(const f_array_length_t step, f_limit_valuess_t *valuess) { + #ifndef _di_level_0_parameter_checking_ + if (!valuess) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (step && valuess->used + 1 > valuess->size) { + f_array_length_t size = valuess->used + step; + + if (size > F_array_length_t_size_d) { + if (valuess->used + 1 > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + size = F_array_length_t_size_d; + } + + return private_f_limit_valuess_resize(size, valuess); + } + + return F_data_not; + } +#endif // _di_f_limit_valuess_increase_ + +#ifndef _di_f_limit_valuess_increase_by_ + f_status_t f_limit_valuess_increase_by(const f_array_length_t amount, f_limit_valuess_t *valuess) { + #ifndef _di_level_0_parameter_checking_ + if (!valuess) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) { + return F_data_not; + } + + if (valuess->used + amount > valuess->size) { + if (valuess->used + amount > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + return private_f_limit_valuess_resize(valuess->used + amount, valuess); + } + + return F_data_not; + } +#endif // _di_f_limit_valuess_increase_by_ + +#ifndef _di_f_limit_valuess_resize_ + f_status_t f_limit_valuess_resize(const f_array_length_t length, f_limit_valuess_t *valuess) { + #ifndef _di_level_0_parameter_checking_ + if (!valuess) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_limit_valuess_resize(length, valuess); + } +#endif // _di_f_limit_valuess_resize_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_limit/c/limit/value.h b/level_0/f_limit/c/limit/value.h new file mode 100644 index 0000000..210fccb --- /dev/null +++ b/level_0/f_limit/c/limit/value.h @@ -0,0 +1,463 @@ +/** + * FLL - Level 0 + * + * Project: Limit + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Defines common data to be used for/by limit related functionality. + * + * This is auto-included by limit.h and should not need to be explicitly included. + */ +#ifndef _F_limit_value_h +#define _F_limit_value_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A limit value structure. + * + * rlim_cur: The soft limit. + * rlim_max: The hard limit. + */ +#ifndef _di_f_limit_value_t_ + typedef struct rlimit f_limit_value_t; + + #define f_limit_value_t_initialize { 0, 0 } + + #define macro_f_limit_value_t_initialize(current, max) { current, max } + + #define macro_f_limit_value_t_clear(value) \ + value.rlim_cur = 0; \ + value.rlim_max = 0; +#endif // _di_f_limit_value_t_ + +/** + * An array of limit values. + * + * array: An array of limit values. + * size: Total amount of allocated space. + * used: Total number of allocated spaces used. + */ +#ifndef _di_f_limit_values_t_ + typedef struct { + f_limit_value_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_limit_values_t; + + #define f_limit_values_t_initialize { 0, 0, 0 } + + #define macro_f_limit_values_t_initialize(content, size, used) { array, size, used } + #define macro_f_limit_values_t_initialize2(array, length) { array, length, length } + + #define macro_f_limit_values_t_clear(values) macro_f_memory_structure_clear(values) + + #define macro_f_limit_values_t_resize(status, values, length) status = f_limit_values_resize(length, &values); + #define macro_f_limit_values_t_adjust(status, values, length) status = f_limit_values_adjust(length, &values); + + #define macro_f_limit_values_t_delete_simple(values) f_limit_values_resize(0, &values); + #define macro_f_limit_values_t_destroy_simple(values) f_limit_values_adjust(0, &values); + + #define macro_f_limit_values_t_increase(status, step, values) status = f_limit_values_increase(step, &values); + #define macro_f_limit_values_t_increase_by(status, values, amount) status = f_limit_values_increase_by(amount, &values); + #define macro_f_limit_values_t_decrease_by(status, values, amount) status = f_limit_values_decrease_by(amount, &values); + #define macro_f_limit_values_t_decimate_by(status, values, amount) status = f_limit_values_decimate_by(amount, &values); +#endif // _di_f_limit_values_t_ + +/** + * This holds an array of f_limit_values_t. + * + * array: An array of f_limit_values_t. + * size: Total amount of allocated space. + * used: Total number of allocated spaces used. + */ +#ifndef _di_f_limit_valuess_t_ + typedef struct { + f_limit_values_t *array; + + f_array_length_t size; + f_array_length_t used; + } f_limit_valuess_t; + + #define f_limit_valuess_t_initialize { 0, 0, 0 } + + #define macro_f_limit_valuess_t_initialize(array, size, used) { array, size, used } + #define macro_f_limit_valuess_t_initialize2(array, length) { array, length, length } + + #define macro_f_limit_valuess_t_clear(valuess) macro_f_memory_structure_clear(valuess); + + #define macro_f_limit_valuess_t_resize(status, valuess, length) status = f_limit_valuess_resize(length, &valuess); + #define macro_f_limit_valuess_t_adjust(status, valuess, length) status = f_limit_valuess_adjust(length, &valuess); + + #define macro_f_limit_valuess_t_delete_simple(valuess) f_limit_valuess_resize(0, &valuess); + #define macro_f_limit_valuess_t_destroy_simple(valuess) f_limit_valuess_adjust(0, &valuess); + + #define macro_f_limit_valuess_t_increase(status, step, valuess) status = f_limit_valuess_increase(step, &valuess); + #define macro_f_limit_valuess_t_increase_by(status, valuess, amount) status = f_limit_valuess_increase_by(amount, &valuess); + #define macro_f_limit_valuess_t_decrease_by(status, valuess, amount) status = f_limit_valuess_decrease_by(amount, &valuess); + #define macro_f_limit_valuess_t_decimate_by(status, valuess, amount) status = f_limit_valuess_decimate_by(amount, &valuess); +#endif // _di_f_limit_valuess_t_ + +/** + * Resize the values array. + * + * @param length + * The new size to use. + * @param values + * The values array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + */ +#ifndef _di_f_limit_values_adjust_ + extern f_status_t f_limit_values_adjust(const f_array_length_t length, f_limit_values_t *values); +#endif // _di_f_limit_values_adjust_ + +/** + * Append the single source value onto the destination. + * + * @param source + * The source value to append. + * @param destination + * The destination values the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_values_append_ + extern f_status_t f_limit_values_append(const f_limit_value_t source, f_limit_values_t *destination); +#endif // _di_f_limit_values_append_ + +/** + * Append the source values onto the destination. + * + * @param source + * The source values to append. + * @param destination + * The destination values the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_values_append_all_ + extern f_status_t f_limit_values_append_all(const f_limit_values_t source, f_limit_values_t *destination); +#endif // _di_f_limit_values_append_all_ + +/** + * Resize the values array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to les than 0. + * + * @param amount + * A positive number representing how much to decimate the size by. + * @param values + * The values array to resize. + * + * @return + * F_none on success. + * F_data_not if amount is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + */ +#ifndef _di_f_limit_values_decimate_by_ + extern f_status_t f_limit_values_decimate_by(const f_array_length_t amount, f_limit_values_t *values); +#endif // _di_f_limit_values_decimate_by_ + +/** + * Resize the values array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to les than 0. + * + * @param amount + * A positive number representing how much to decrease the size by. + * @param values + * The values array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_values_decrease_by_ + extern f_status_t f_limit_values_decrease_by(const f_array_length_t amount, f_limit_values_t *values); +#endif // _di_f_limit_values_decrease_by_ + +/** + * Increase the size of the values array, but only if necesary. + * + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param step + * The allocation step to use. + * Must be greater than 0. + * @param values + * The values array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_values_increase_ + extern f_status_t f_limit_values_increase(const f_array_length_t step, f_limit_values_t *values); +#endif // _di_f_limit_values_increase_ + +/** + * Resize the values array to a larger size. + * + * This will resize making the string larger based on the given length. + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param amount + * A positive number representing how much to increase the size by. + * @param values + * The values array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + amount <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_values_increase_by_ + extern f_status_t f_limit_values_increase_by(const f_array_length_t amount, f_limit_values_t *values); +#endif // _di_f_limit_values_increase_by_ + +/** + * Resize the values array. + * + * @param length + * The new size to use. + * @param values + * The values array to adjust. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_values_resize_ + extern f_status_t f_limit_values_resize(const f_array_length_t length, f_limit_values_t *values); +#endif // _di_f_limit_values_resize_ + +/** + * Resize the valuess array. + * + * @param length + * The new size to use. + * @param valuess + * The valuess array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + * Errors (with error bit) from: f_memory_destroy(). + */ +#ifndef _di_f_limit_valuess_adjust_ + extern f_status_t f_limit_valuess_adjust(const f_array_length_t length, f_limit_valuess_t *valuess); +#endif // _di_f_limit_valuess_adjust_ + +/** + * Append the single source values onto the destination. + * + * @param source + * The source values to append. + * @param destination + * The destination ranges the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_valuess_append_ + extern f_status_t f_limit_valuess_append(const f_limit_values_t source, f_limit_valuess_t *destination); +#endif // _di_f_limit_valuess_append_ + +/** + * Append the source valuess onto the destination. + * + * @param source + * The source valuess to append. + * @param destination + * The destination ranges the source is appended onto. + * + * @return + * F_none on success. + * F_data_not on success, but there is nothing to append (size == 0). + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_valuess_append_all_ + extern f_status_t f_limit_valuess_append_all(const f_limit_valuess_t source, f_limit_valuess_t *destination); +#endif // _di_f_limit_valuess_append_all_ + +/** + * Resize the valuess array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to less than 0. + * + * @param amount + * A positive number representing how much to decimate the size by. + * @param valuess + * The valuess array to resize. + * + * @return + * F_none on success. + * F_data_not if amount is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_adjust(). + * Errors (with error bit) from: f_memory_destroy(). + */ +#ifndef _di_f_limit_valuess_decimate_by_ + extern f_status_t f_limit_valuess_decimate_by(const f_array_length_t amount, f_limit_valuess_t *valuess); +#endif // _di_f_limit_valuess_decimate_by_ + +/** + * Resize the valuess array to a smaller size. + * + * This will resize making the array smaller based on (size - given length). + * If the given length is too small, then the resize will fail. + * This will not shrink the size to less than 0. + * + * @param amount + * A positive number representing how much to decrease the size by. + * @param valuess + * The valuess array to resize. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_delete(). + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_valuess_decrease_by_ + extern f_status_t f_limit_valuess_decrease_by(const f_array_length_t amount, f_limit_valuess_t *valuess); +#endif // _di_f_limit_valuess_decrease_by_ + +/** + * Increase the size of the valuess array, but only if necessary. + * + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param step + * The allocation step to use. + * Must be greater than 0. + * @param valuess + * The valuess array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + 1 <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_valuess_increase_ + extern f_status_t f_limit_valuess_increase(const f_array_length_t step, f_limit_valuess_t *valuess); +#endif // _di_f_limit_valuess_increase_ + +/** + * Resize the valuess array to a larger size. + * + * This will resize making the string larger based on the given length. + * If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d). + * If already set to the maximum buffer size, then the resize will fail. + * + * @param amount + * A positive number representing how much to increase the size by. + * @param valuess + * The valuess array to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + amount <= size). + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_valuess_increase_by_ + extern f_status_t f_limit_valuess_increase_by(const f_array_length_t amount, f_limit_valuess_t *valuess); +#endif // _di_f_limit_valuess_increase_by_ + +/** + * Resize the valuess array. + * + * @param length + * The new size to use. + * @param valuess + * The valuess array to adjust. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_memory_delete(). + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_limit_valuess_resize_ + extern f_status_t f_limit_valuess_resize(const f_array_length_t length, f_limit_valuess_t *valuess); +#endif // _di_f_limit_valuess_resize_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_limit_value_h diff --git a/level_0/f_limit/data/build/dependencies-tests b/level_0/f_limit/data/build/dependencies-tests new file mode 100644 index 0000000..dea3179 --- /dev/null +++ b/level_0/f_limit/data/build/dependencies-tests @@ -0,0 +1,3 @@ +# fss-0001 + +cmocka 1.* diff --git a/level_0/f_limit/data/build/settings b/level_0/f_limit/data/build/settings index c0763a3..cd432bb 100644 --- a/level_0/f_limit/data/build/settings +++ b/level_0/f_limit/data/build/settings @@ -20,9 +20,9 @@ build_language c build_libraries -lc build_libraries-individual -lf_memory -build_sources_library limit.c +build_sources_library limit.c limit/set.c limit/value.c limit/private-set.c limit/private-value.c -build_sources_headers limit.h limit/common.h +build_sources_headers limit.h limit/set.h limit/value.h build_script yes build_shared yes diff --git a/level_0/f_limit/data/build/settings-mocks b/level_0/f_limit/data/build/settings-mocks new file mode 100644 index 0000000..878c1af --- /dev/null +++ b/level_0/f_limit/data/build/settings-mocks @@ -0,0 +1,50 @@ +# fss-0001 + +build_name f_limit + +version_major 0 +version_minor 5 +version_micro 9 +version_file micro +version_target minor + +modes individual clang test +modes_default individual + +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 + +build_sources_library limit.c limit/set.c limit/value.c limit/private-set.c limit/private-value.c ../../tests/unit/c/mock-limit.c + +build_sources_headers limit.h limit/set.h limit/value.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 + +flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses +flags-clang -Wno-logical-op-parentheses +flags-test -fstack-protector + +flags_library -fPIC + +# Inject mocks. +flags -Wl,--wrap=prlimit diff --git a/level_0/f_limit/data/build/settings-tests b/level_0/f_limit/data/build/settings-tests new file mode 100644 index 0000000..2eac7ac --- /dev/null +++ b/level_0/f_limit/data/build/settings-tests @@ -0,0 +1,57 @@ +# 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_limit + +version_major 0 +version_minor 5 +version_micro 9 +version_file major +version_target major + +modes individual clang test +modes_default individual + +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_type_array -lf_utf -lf_limit + +build_sources_program test-limit-process.c +build_sources_program test-limit-sets_adjust.c test-limit-sets_append.c test-limit-sets_append_all.c test-limit-sets_decimate_by.c test-limit-sets_decrease_by.c test-limit-sets_increase.c test-limit-sets_increase_by.c test-limit-sets_resize.c +build_sources_program test-limit-setss_adjust.c test-limit-setss_append.c test-limit-setss_append_all.c test-limit-setss_decimate_by.c test-limit-setss_decrease_by.c test-limit-setss_increase.c test-limit-setss_increase_by.c test-limit-setss_resize.c +build_sources_program test-limit-values_adjust.c test-limit-values_append.c test-limit-values_append_all.c test-limit-values_decimate_by.c test-limit-values_decrease_by.c test-limit-values_increase.c test-limit-values_increase_by.c test-limit-values_resize.c +build_sources_program test-limit-valuess_adjust.c test-limit-valuess_append.c test-limit-valuess_append_all.c test-limit-valuess_decimate_by.c test-limit-valuess_decrease_by.c test-limit-valuess_increase.c test-limit-valuess_increase_by.c test-limit-valuess_resize.c +build_sources_program test-limit.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 + +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_program -fPIE diff --git a/level_0/f_limit/data/build/testfile b/level_0/f_limit/data/build/testfile new file mode 100644 index 0000000..b119737 --- /dev/null +++ b/level_0/f_limit/data/build/testfile @@ -0,0 +1,45 @@ +# fss-0005 iki-0002 + +settings: + load_build yes + fail exit + + environment LD_LIBRARY_PATH + +main: + build settings-mocks + build settings-tests + + operate ld_library_path + + if exists build/programs/shared/test-f_limit + shell build/programs/shared/test-f_limit + + if exists build/programs/static/test-f_limit + shell build/programs/static/test-f_limit + + if not exists build/programs/shared/test-f_limit + and not exists build/programs/static/test-f_limit + 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 + +ld_library_path: + if defined environment LD_LIBRARY_PATH + and defined parameter work + define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"' + + else + if defined environment LD_LIBRARY_PATH + define LD_LIBRARY_PATH 'build/libraries/shared:parameter:define:"LD_LIBRARY_PATH"' + + else + if defined parameter work + define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared' + + else + define LD_LIBRARY_PATH build/libraries/shared diff --git a/level_3/controller/c/rule/private-rule.c b/level_3/controller/c/rule/private-rule.c index 75cd4cf..742af24 100644 --- a/level_3/controller/c/rule/private-rule.c +++ b/level_3/controller/c/rule/private-rule.c @@ -862,7 +862,8 @@ extern "C" { status = f_int32s_append_all(source.groups, &destination->groups); if (F_status_is_error(status)) return status; - status = f_limit_sets_copy(source.limits, &destination->limits); + destination->limits.used = 0; + status = f_limit_sets_append_all(source.limits, &destination->limits); if (F_status_is_error(status)) return status; if (source.items.used) { -- 1.8.3.1