Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libs/utils/gtest/src/PropertiesTestSuite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PropertiesTestSuite : public ::testing::Test {
public:
PropertiesTestSuite() { celix_err_resetErrors(); }

void printStats(const celix_properties_statistics_t* stats) {
static void printStats(const celix_properties_statistics_t* stats) {
printf("Properties statistics:\n");
printf("|- nr of entries: %zu\n", stats->mapStatistics.nrOfEntries);
printf("|- nr of buckets: %zu\n", stats->mapStatistics.nrOfBuckets);
Expand Down Expand Up @@ -951,4 +951,4 @@ TEST_F(PropertiesTestSuite, EmptyStringKeyTest) {
celix_properties_set(props, "", "value"); // "" is a valid key (nullptr is not)
EXPECT_EQ(1, celix_properties_size(props));
EXPECT_STREQ("value", celix_properties_getString(props, ""));
}
}
219 changes: 116 additions & 103 deletions libs/utils/include/celix_array_list.h

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions libs/utils/include/celix_array_list_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ extern "C" {
*/

/**
* @brief Flag to indicate that the encoding should be pretty printed. e.g. encoded with additional whitespaces, newlines and indentation.
* @brief Flag to indicate that the encoding should be pretty printed, e.g., encoded with additional whitespaces, newlines and indentation.
*
* If this flag is not set, the encoding will be compact. e.g. without additional whitespaces, newlines and indentation.
* If this flag is not set, the encoding will be compact, e.g., without additional whitespaces, newlines and indentation.
*/
#define CELIX_ARRAY_LIST_ENCODE_PRETTY 0x01

/**
* @brief Flag to indicate that the encoding should fail if an empty array is encountered.
*
* If this flag is not set, an empty array will be encoded as an empty json array representation("[]").
* If this flag is not set, an empty array will be encoded as an empty JSON array representation("[]").
*
* Although empty arrays are valid in json, they cannot decoded to a valid celix_array_list_t.
* Although empty arrays are valid in JSON, they cannot be decoded to a valid celix_array_list_t.
*/
#define CELIX_ARRAY_LIST_ENCODE_ERROR_ON_EMPTY_ARRAYS 0x10

Expand All @@ -56,12 +56,12 @@ extern "C" {
*
* If this flag is not set, the encoding will not fail and the NaN and Inf value will be ignored.
*
* NaN and Inf values are not valid in json, as such celix_array_list_t with these values cannot be encoded to json.
* NaN and Inf values are not valid in JSON, as such celix_array_list_t with these values cannot be encoded to JSON.
*/
#define CELIX_ARRAY_LIST_ENCODE_ERROR_ON_NAN_INF 0x20

/**
* @brief Flag to indicate that the encoding should be strict. e.g. fail on empty arrays and NaN/Inf values.
* @brief Flag to indicate that the encoding should be strict, e.g., fail on empty arrays and NaN/Inf values.
*/
#define CELIX_ARRAY_LIST_ENCODE_STRICT \
(CELIX_ARRAY_LIST_ENCODE_ERROR_ON_EMPTY_ARRAYS | CELIX_ARRAY_LIST_ENCODE_ERROR_ON_NAN_INF)
Expand All @@ -70,7 +70,7 @@ extern "C" {


/**
* @brief Encode the given celix_array_list_t as a JSON representationand write it to the given stream.
* @brief Encode the given celix_array_list_t as a JSON representation and write it to the given stream.
*
* The caller is the owner of the stream and is responsible for closing it.
*
Expand All @@ -96,7 +96,7 @@ CELIX_UTILS_EXPORT
celix_status_t celix_arrayList_saveToStream(const celix_array_list_t* list, int encodeFlags, FILE* stream);

/**
* @brief Encode the given celix_array_list_t as a JSON representation, and write it to the given file.
* @brief Encode the given celix_array_list_t as a JSON representation and write it to the given file.
*
* For more information about the encoding, see celix_arrayList_saveToStream.
*
Expand Down Expand Up @@ -138,19 +138,19 @@ celix_status_t celix_arrayList_saveToString(const celix_array_list_t* list, int
/**
* @brief Flag to indicate that the decoding should fail if an empty array is encountered.
*
* If this flag is not set, the decoding will not fail and the empty json array representation("[]") will be ignored, then a NULL celix_array_list_t* will be returned.
* If this flag is not set, the decoding will not fail, and the empty JSON array representation("[]") will be ignored, then a NULL celix_array_list_t* will be returned.
*/
#define CELIX_ARRAY_LIST_DECODE_ERROR_ON_EMPTY_ARRAYS 0x01

/**
* @brief Flag to indicate that the decoding should fail if an unsupported array type is encountered.
*
* If this flag is not set, the decoding will not fail and the unsupported array type will be ignored, then a NULL celix_array_list_t* will be returned.
* If this flag is not set, the decoding will not fail, and the unsupported array type will be ignored, then a NULL celix_array_list_t* will be returned.
*/
#define CELIX_ARRAY_LIST_DECODE_ERROR_ON_UNSUPPORTED_ARRAYS 0x02

/**
* @brief Flag to indicate that the decoding should be strict. e.g. fail on empty arrays and unsupported array types.
* @brief Flag to indicate that the decoding should be strict, e.g., fail on empty arrays and unsupported array types.
*
*/
#define CELIX_ARRAY_LIST_DECODE_STRICT \
Expand Down
4 changes: 2 additions & 2 deletions libs/utils/include/celix_cleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ extern "C" {
*/
#ifdef __cplusplus
#define celix_steal_ptr(p) \
({ auto __ptr = (p); (p) = NULL; __ptr; })
({ auto celix_ptr_ = (p); (p) = NULL; celix_ptr_; })
#else
#define celix_steal_ptr(p) \
({ __auto_type __ptr = (p); (p) = NULL; __ptr; })
({ __auto_type celix_ptr_ = (p); (p) = NULL; celix_ptr_; })
#endif


Expand Down
89 changes: 89 additions & 0 deletions libs/utils/include/celix_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,95 @@ extern "C" {

#define CELIX_UNIQUE_ID(prefix) CELIX_PASTE(CELIX_PASTE(__UNIQUE_ID_, prefix), __COUNTER__)

/**
* A wrapper around `__has_attribute()`, which tests for support for `__attribute__(())`s.
*
* See also:
* clang: https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
* gcc: https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html
*/
#if defined(__has_attribute)
#define CELIX_HAS_ATTRIBUTE(x) __has_attribute(x)
#else
#define CELIX_HAS_ATTRIBUTE(x) 0
#endif

/**
* CELIX_OWNERSHIP_TAKES(type, idx)
*
* Expands to the compiler attribute `__attribute__((ownership_takes(type, idx)))`
* when the compiler supports the `ownership_takes` attribute. This attribute
* marks a function as a deallocating function.
*
* See also:
* clang: https://clang.llvm.org/docs/AttributeReference.html#ownership-holds-ownership-returns-ownership-takes-clang-static-analyzer
*
* Parameters:
* - `type`: the type of the allocation: malloc, new, etc. to allow for catching mismatched deallocation bugs.
* - `idx`: 1-based index of the parameter that is being deallocated.
*
* Example:
* ```C
* void CELIX_OWNERSHIP_TAKES(owner, 1) free_string(char* ptr);
* ```
*/

#if CELIX_HAS_ATTRIBUTE(ownership_takes)
#define CELIX_OWNERSHIP_TAKES(type, idx) __attribute__((ownership_takes(type, idx)))
#else
#define CELIX_OWNERSHIP_TAKES(type, idx)
#endif

/**
* CELIX_OWNERSHIP_RETURNS(type)
*
* Expands to the compiler attribute `__attribute__((ownership_returns(type, idx)))`
* when the compiler supports the `ownership_returns` attribute. This attribute
* marks a function as an allocating function.
*
* See also:
* clang: https://clang.llvm.org/docs/AttributeReference.html#ownership-holds-ownership-returns-ownership-takes-clang-static-analyzer
*
* Parameters:
* - `type`: the type of the allocation: malloc, new, etc. to allow for catching mismatched deallocation bugs.
*
* Example:
* ```C
* char CELIX_OWNERSHIP_RETURNS(owner)* allocate_string(void);
* ```
*/
#if CELIX_HAS_ATTRIBUTE(ownership_returns)
#define CELIX_OWNERSHIP_RETURNS(type) __attribute__((ownership_returns(type)))
#else
#define CELIX_OWNERSHIP_RETURNS(type)
#endif

/**
* CELIX_OWNERSHIP_HOLDS(type, idx)
*
* Expands to the compiler attribute `__attribute__((ownership_holds(type, idx)))`
* when the compiler supports the `ownership_holds` attribute. This attribute
* marks that a function takes over the ownership of a piece of memory and will free it
* at some unspecified point in the future.
*
* See also:
* clang: https://clang.llvm.org/docs/AttributeReference.html#ownership-holds-ownership-returns-ownership-takes-clang-static-analyzer
*
* Parameters:
* - `type`: the type of the allocation: malloc, new, etc. to allow for catching mismatched deallocation bugs.
* - `idx`: 1-based index of the parameter whose ownership will be taken over.
*
* Example:
* ```C
* void CELIX_OWNERSHIP_HOLDS(owner, 1) hold_string(char* ptr);
* ```
*/
#if CELIX_HAS_ATTRIBUTE(ownership_holds)
#define CELIX_OWNERSHIP_HOLDS(type, idx) __attribute__((ownership_holds(type, idx)))
#else
#define CELIX_OWNERSHIP_HOLDS(type, idx)
#endif

#ifdef __cplusplus
}
#endif
Expand Down
37 changes: 18 additions & 19 deletions libs/utils/include/celix_convert_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <stdbool.h>

#include "celix_array_list.h"
#include "celix_compiler.h"
#include "celix_errno.h"
#include "celix_utils_export.h"
#include "celix_version.h"
Expand All @@ -39,8 +40,7 @@ extern "C" {
/**
* @brief Convert a string to a boolean.
*
* Converts a string to a boolean. White space is ignored and the following values are considered booleans (case
* insensitive): "true', "false".
* Converts a string to a boolean. White space is ignored, and the following values are considered booleans (case-insensitive): "true", "false".
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid boolean.
Expand All @@ -60,7 +60,7 @@ CELIX_UTILS_EXPORT bool celix_utils_convertStringToBool(const char* val, bool de
CELIX_UTILS_EXPORT double celix_utils_convertStringToDouble(const char* val, double defaultValue, bool* converted);

/**
* @brief Convert a string to a long.
* @brief Convert a string to a long integer.
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid long.
Expand All @@ -75,13 +75,13 @@ CELIX_UTILS_EXPORT long celix_utils_convertStringToLong(const char* val, long de
* In case of an error, an error message is added to celix_err.
*
* @note This convert function will only convert version strings in the format major.minor.micro(.qualifier)?.
* So the major, minor and micro are required, the qualifier is optional.
* So the major, minor, and micro are required, and the qualifier is optional.
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid celix_version_t.
* @param[out] version The converted version. If the string is not a valid version, the version will be set to a copy of
* the defaultValue.
* @return CELIX_SUCCESS if the string is a valid version, CELIX_ILLEGAL_ARGUMENT if the string is not a valid version
* @return CELIX_SUCCESS if the string is a valid version, CELIX_ILLEGAL_ARGUMENT if the string is not a valid version,
* and CELIX_ENOMEM if memory could not be allocated. Note that on a CELIX_ILLEGAL_ARGUMENT the version will be set to a
* copy of the defaultValue.
*/
Expand All @@ -101,7 +101,7 @@ CELIX_UTILS_EXPORT celix_status_t celix_utils_convertStringToVersion(const char*
* @param[in] defaultValue The default value if the string is not a valid "," separated list of longs.
* @param[out] list The converted list. If the string is not a valid list, the list will be set to a copy of the
* defaultValue.
* @return CELIX_SUCCESS if the string is a valid array list of specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* @return CELIX_SUCCESS if the string is a valid array list of the specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* and CELIX_ENOMEM if memory could not be allocated.
* Note that on a CELIX_ILLEGAL_ARGUMENT the list will be set to a copy of the defaultValue.
*/
Expand All @@ -119,10 +119,10 @@ celix_status_t celix_utils_convertStringToLongArrayList(const char* val,
* In case of an error, an error message is added to celix_err.
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid "," separated list of doubles.
* @param[in] defaultValue The default value if the string is not a valid comma-separated list of doubles.
* @param[out] list The converted list. If the string is not a valid list, the list will be set to a copy of the
* defaultValue.
* @return CELIX_SUCCESS if the string is a valid array list of specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* @return CELIX_SUCCESS if the string is a valid array list of the specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* and CELIX_ENOMEM if memory could not be allocated.
* Note that on a CELIX_ILLEGAL_ARGUMENT the list will be set to a copy of the defaultValue.
*/
Expand All @@ -140,10 +140,10 @@ celix_status_t celix_utils_convertStringToDoubleArrayList(const char* val,
* In case of an error, an error message is added to celix_err.
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid "," separated list of booleans.
* @param[in] defaultValue The default value if the string is not a valid comma-separated list of booleans.
* @param[out] list The converted list. If the string is not a valid list, the list will be set to a copy of the
* defaultValue.
* @return CELIX_SUCCESS if the string is a valid array list of specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* @return CELIX_SUCCESS if the string is a valid array list of the specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* and CELIX_ENOMEM if memory could not be allocated.
* Note that on a CELIX_ILLEGAL_ARGUMENT the list will be set to a copy of the defaultValue.
*/
Expand All @@ -164,13 +164,13 @@ celix_status_t celix_utils_convertStringToBoolArrayList(const char* val,
* In case of an error, an error message is added to celix_err.
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid "," separated list of strings.
* Note that the defaultValue is copied if the string is not a valid list of string entries
* @param[in] defaultValue The default value if the string is not a valid comma-separated list of strings.
* Note that the defaultValue is copied if the string is not a valid list of string entries,
* and the defaultValue is expected to be configured with a removed entry callback so the
* strings are freed.
* strings are freed.
* @param[out] list The converted list. If the string is not a valid list, the list will be set to a copy of the
* defaultValue.
* @return CELIX_SUCCESS if the string is a valid array list of specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* @return CELIX_SUCCESS if the string is a valid array list of the specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* and CELIX_ENOMEM if memory could not be allocated.
* Note that on a CELIX_ILLEGAL_ARGUMENT the list will be set to a copy of the defaultValue.
*/
Expand All @@ -183,19 +183,19 @@ celix_status_t celix_utils_convertStringToStringArrayList(const char* val,
* @brief Convert a string to a celix_array_list_t* with celix_version_t* entries.
*
* The expected format of the string is a "," separated list of celix_version_t* entries. Whitespace is ignored.
* Version entries are created using celix_utils_convertStringToVersion and the returned list will be configured to call
* Version entries are created using `celix_utils_convertStringToVersion` and the returned list will be configured to call
* celix_version_destroy when entries are removed.
*
* In case of an error, an error message is added to celix_err.
*
* @param[in] val The string to convert.
* @param[in] defaultValue The default value if the string is not a valid "," separated list of string parseable to
* celix_version_t entries. Note that the defaultValue is copied if the string is not a valid
* list of version entries and the defaultValue
* list of version entries, and the defaultValue
* is expected to be configured with a removed entry callback so the versions are freed.
* @param[out] list The converted list. If the string is not a valid list, the list will be set to a copy of the
* defaultValue.
* @return CELIX_SUCCESS if the string is a valid array list of specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* @return CELIX_SUCCESS if the string is a valid array list of the specified entry type, CELIX_ILLEGAL_ARGUMENT if otherwise,
* and CELIX_ENOMEM if memory could not be allocated.
* Note that on a CELIX_ILLEGAL_ARGUMENT the list will be set to a copy of the defaultValue.
*/
Expand All @@ -219,10 +219,9 @@ celix_status_t celix_utils_convertStringToVersionArrayList(const char* val,
* CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER.
*/
CELIX_UTILS_EXPORT
CELIX_OWNERSHIP_RETURNS(malloc)
char* celix_utils_arrayListToString(const celix_array_list_t* list);



#ifdef __cplusplus
}
#endif
Expand Down
Loading
Loading