src/cx/json.h

changeset 1675
36c0fb2b60b2
parent 1667
608cc0b25352
--- a/src/cx/json.h	Sun Dec 28 15:45:39 2025 +0100
+++ b/src/cx/json.h	Sun Dec 28 17:31:20 2025 +0100
@@ -43,11 +43,6 @@
 #include "array_list.h"
 #include "map.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
 /**
  * The type of the parsed token.
  */
@@ -115,6 +110,10 @@
      */
     CX_JSON_NOTHING, // this allows us to always return non-NULL values
     /**
+     * No meaningful data.
+     */
+    CX_JSON_UNINITIALIZED,
+    /**
      * A JSON object.
      */
     CX_JSON_OBJECT,
@@ -427,8 +426,8 @@
  *
  * @return new JSON writer settings
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonWriter cxJsonWriterCompact(void);
+CX_EXTERN CX_NODISCARD
+CxJsonWriter cxJsonWriterCompact(void);
 
 /**
  * Creates a default writer configuration for pretty output.
@@ -436,8 +435,8 @@
  * @param use_spaces false if you want tabs, true if you want four spaces instead
  * @return new JSON writer settings
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonWriter cxJsonWriterPretty(bool use_spaces);
+CX_EXTERN CX_NODISCARD
+CxJsonWriter cxJsonWriterPretty(bool use_spaces);
 
 /**
  * Writes a JSON value to a buffer or stream.
@@ -457,8 +456,8 @@
  * @retval zero success
  * @retval non-zero when no or not all data could be written
  */
-cx_attr_nonnull_arg(1, 2, 3)
-CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value,
+CX_EXTERN CX_NONNULL_ARG(1, 2, 3)
+int cxJsonWrite(void* target, const CxJsonValue* value,
         cx_write_func wfunc, const CxJsonWriter* settings);
 
 
@@ -472,8 +471,8 @@
  * @see cxJsonWriterCompact()
  * @see cxJsonToPrettyString()
  */
-cx_attr_nonnull_arg(2)
-CX_EXPORT cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value);
+CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD
+cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value);
 
 /**
  * Produces a pretty string representation of the specified JSON value.
@@ -485,8 +484,8 @@
  * @see cxJsonWriterPretty()
  * @see cxJsonToString()
  */
-cx_attr_nonnull_arg(2)
-CX_EXPORT cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value);
+CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD
+cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value);
 
 /**
  * Initializes the JSON interface.
@@ -495,8 +494,8 @@
  * @param allocator the allocator that shall be used for the produced values
  * @see cxJsonDestroy()
  */
-cx_attr_nonnull_arg(1)
-CX_EXPORT void cxJsonInit(CxJson *json, const CxAllocator *allocator);
+CX_EXTERN CX_NONNULL_ARG(1)
+void cxJsonInit(CxJson *json, const CxAllocator *allocator);
 
 /**
  * Destroys the JSON interface.
@@ -504,8 +503,8 @@
  * @param json the JSON interface
  * @see cxJsonInit()
  */
-cx_attr_nonnull
-CX_EXPORT void cxJsonDestroy(CxJson *json);
+CX_EXTERN CX_NONNULL
+void cxJsonDestroy(CxJson *json);
 
 /**
  * Destroys and re-initializes the JSON interface.
@@ -515,8 +514,8 @@
  *
  * @param json the JSON interface
  */
-cx_attr_nonnull
-CX_EXPORT void cxJsonReset(CxJson *json);
+CX_EXTERN CX_NONNULL
+void cxJsonReset(CxJson *json);
 
 /**
  * Fills the input buffer.
@@ -536,8 +535,8 @@
  * @retval non-zero internal allocation error
  * @see cxJsonFill()
  */
-cx_attr_nonnull_arg(1) cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len);
+CX_EXTERN CX_NONNULL_ARG(1) CX_ACCESS_R(2, 3)
+int cxJsonFilln(CxJson *json, const char *buf, size_t len);
 
 
 /**
@@ -548,8 +547,8 @@
  * @retval zero success
  * @retval non-zero internal allocation error
  */
-cx_attr_nonnull
-CX_INLINE int cx_json_fill(CxJson *json, cxstring str) {
+CX_NONNULL CX_INLINE
+int cx_json_fill(CxJson *json, cxstring str) {
     return cxJsonFilln(json, str.ptr, str.length);
 }
 
@@ -581,8 +580,8 @@
  * @param value a pointer where the JSON value shall be stored to
  * @return status code
  */
-cx_attr_nonnull_arg(3)
-CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator,
+CX_EXTERN CX_NONNULL_ARG(3) CX_ACCESS_W(3)
+CxJsonStatus cx_json_from_string(const CxAllocator *allocator,
             cxstring str, CxJsonValue **value);
 
 /**
@@ -603,6 +602,20 @@
         cx_json_from_string(allocator, cx_strcast(str), value)
 
 /**
+ * Recursively deallocates the memory of a JSON value.
+ *
+ * @remark The type of each deallocated value will be changed
+ * to #CX_JSON_NOTHING, and values of such a type will be skipped
+ * by the deallocation. That means this function protects
+ * you from double-frees when you are accidentally freeing
+ * a nested value and then the parent value (or vice versa).
+ *
+ * @param value the value
+ */
+CX_EXTERN
+void cxJsonValueFree(CxJsonValue *value);
+
+/**
  * Creates a new (empty) JSON object.
  *
  * @param allocator the allocator to use
@@ -610,8 +623,8 @@
  * @see cxJsonObjPutObj()
  * @see cxJsonArrAddValues()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
+CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
 
 /**
  * Creates a new (empty) JSON array.
@@ -624,8 +637,8 @@
  * @see cxJsonObjPutArr()
  * @see cxJsonArrAddValues()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity);
+CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity);
 
 /**
  * Creates a new JSON number value.
@@ -636,8 +649,8 @@
  * @see cxJsonObjPutNumber()
  * @see cxJsonArrAddNumbers()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
+CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
 
 /**
  * Creates a new JSON number value based on an integer.
@@ -648,8 +661,8 @@
  * @see cxJsonObjPutInteger()
  * @see cxJsonArrAddIntegers()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
+CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
 
 /**
  * Creates a new JSON string.
@@ -662,8 +675,8 @@
  * @see cxJsonObjPutString()
  * @see cxJsonArrAddCxStrings()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str);
+CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str);
 
 /**
  * Creates a new JSON string.
@@ -685,8 +698,8 @@
  * @see cxJsonObjPutLiteral()
  * @see cxJsonArrAddLiterals()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
+CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
 
 /**
  * Adds number values to a JSON array.
@@ -697,8 +710,8 @@
  * @retval zero success
  * @retval non-zero allocation failure
  */
-cx_attr_nonnull cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
+CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
+int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
 
 /**
  * Adds number values, of which all are integers, to a JSON array.
@@ -709,8 +722,8 @@
  * @retval zero success
  * @retval non-zero allocation failure
  */
-cx_attr_nonnull cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
+CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
+int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
 
 /**
  * Adds strings to a JSON array.
@@ -724,8 +737,8 @@
  * @retval non-zero allocation failure
  * @see cxJsonArrAddCxStrings()
  */
-cx_attr_nonnull cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
+CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
+int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
 
 /**
  * Adds strings to a JSON array.
@@ -739,8 +752,8 @@
  * @retval non-zero allocation failure
  * @see cxJsonArrAddStrings()
  */
-cx_attr_nonnull cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
+CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
+int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
 
 /**
  * Adds literals to a JSON array.
@@ -751,8 +764,8 @@
  * @retval zero success
  * @retval non-zero allocation failure
  */
-cx_attr_nonnull cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
+CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
+int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
 
 /**
  * Add arbitrary values to a JSON array.
@@ -766,8 +779,8 @@
  * @retval zero success
  * @retval non-zero allocation failure
  */
-cx_attr_nonnull cx_attr_access_r(2, 3)
-CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
+CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
+int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
 
 /**
  * Adds or replaces a value within a JSON object.
@@ -780,8 +793,8 @@
  * @retval zero success
  * @retval non-zero allocation failure
  */
-cx_attr_nonnull
-CX_EXPORT int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child);
+CX_EXTERN CX_NONNULL
+int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child);
 
 /**
  * Adds or replaces a value within a JSON object.
@@ -810,8 +823,8 @@
  * @see cxJsonObjPut()
  * @see cxJsonCreateObj()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name);
+CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name);
 
 /**
  * Creates a new JSON object and adds it to an existing object.
@@ -836,8 +849,8 @@
  * @see cxJsonObjPut()
  * @see cxJsonCreateArr()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity);
+CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity);
 
 /**
  * Creates a new JSON array and adds it to an object.
@@ -863,8 +876,8 @@
  * @see cxJsonObjPut()
  * @see cxJsonCreateNumber()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num);
+CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num);
 
 /**
  * Creates a new JSON number and adds it to an object.
@@ -890,8 +903,8 @@
  * @see cxJsonObjPut()
  * @see cxJsonCreateInteger()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num);
+CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num);
 
 /**
  * Creates a new JSON number, based on an integer, and adds it to an object.
@@ -917,8 +930,8 @@
  * @see cxJsonObjPut()
  * @see cxJsonCreateString()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str);
+CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str);
 
 /**
  * Creates a new JSON string and adds it to an object.
@@ -946,8 +959,8 @@
  * @see cxJsonObjPut()
  * @see cxJsonCreateLiteral()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
+CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
+CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
 
 /**
  * Creates a new JSON literal and adds it to an object.
@@ -962,19 +975,6 @@
 #define cxJsonObjPutLiteral(obj, name, lit) cx_json_obj_put_literal(obj, cx_strcast(name), lit)
 
 /**
- * Recursively deallocates the memory of a JSON value.
- *
- * @remark The type of each deallocated value will be changed
- * to #CX_JSON_NOTHING, and values of such a type will be skipped
- * by the deallocation. That means this function protects
- * you from double-frees when you are accidentally freeing
- * a nested value and then the parent value (or vice versa).
- *
- * @param value the value
- */
-CX_EXPORT void cxJsonValueFree(CxJsonValue *value);
-
-/**
  * Tries to obtain the next JSON value.
  *
  * Before this function can be called, the input buffer needs
@@ -996,8 +996,8 @@
  * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number
  * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error
  */
-cx_attr_nonnull cx_attr_access_w(2)
-CX_EXPORT CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
+CX_EXTERN CX_NONNULL CX_ACCESS_W(2)
+CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
 
 /**
  * Checks if the specified value is a JSON object.
@@ -1006,8 +1006,8 @@
  * @retval true the value is a JSON object
  * @retval false otherwise
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsObject(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsObject(const CxJsonValue *value) {
     return value->type == CX_JSON_OBJECT;
 }
 
@@ -1018,8 +1018,8 @@
  * @retval true the value is a JSON array
  * @retval false otherwise
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsArray(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsArray(const CxJsonValue *value) {
     return value->type == CX_JSON_ARRAY;
 }
 
@@ -1030,8 +1030,8 @@
  * @retval true the value is a string
  * @retval false otherwise
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsString(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsString(const CxJsonValue *value) {
     return value->type == CX_JSON_STRING;
 }
 
@@ -1046,8 +1046,8 @@
  * @retval false otherwise
  * @see cxJsonIsInteger()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsNumber(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsNumber(const CxJsonValue *value) {
     return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER;
 }
 
@@ -1059,8 +1059,8 @@
  * @retval false otherwise
  * @see cxJsonIsNumber()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsInteger(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsInteger(const CxJsonValue *value) {
     return value->type == CX_JSON_INTEGER;
 }
 
@@ -1076,8 +1076,8 @@
  * @see cxJsonIsFalse()
  * @see cxJsonIsNull()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsLiteral(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsLiteral(const CxJsonValue *value) {
     return value->type == CX_JSON_LITERAL;
 }
 
@@ -1090,8 +1090,8 @@
  * @see cxJsonIsTrue()
  * @see cxJsonIsFalse()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsBool(const CxJsonValue *value) {
     return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL;
 }
 
@@ -1107,8 +1107,8 @@
  * @see cxJsonIsBool()
  * @see cxJsonIsFalse()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsTrue(const CxJsonValue *value) {
     return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE;
 }
 
@@ -1124,8 +1124,8 @@
  * @see cxJsonIsBool()
  * @see cxJsonIsTrue()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsFalse(const CxJsonValue *value) {
     return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE;
 }
 
@@ -1137,8 +1137,8 @@
  * @retval false otherwise
  * @see cxJsonIsLiteral()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonIsNull(const CxJsonValue *value) {
     return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL;
 }
 
@@ -1151,8 +1151,8 @@
  * @return the value represented as C string
  * @see cxJsonIsString()
  */
-cx_attr_nonnull  cx_attr_returns_nonnull
-CX_EXPORT char *cxJsonAsString(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
+char *cxJsonAsString(const CxJsonValue *value);
 
 /**
  * Obtains a UCX string from the given JSON value.
@@ -1163,8 +1163,8 @@
  * @return the value represented as UCX string
  * @see cxJsonIsString()
  */
-cx_attr_nonnull
-CX_EXPORT cxstring cxJsonAsCxString(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_NODISCARD
+cxstring cxJsonAsCxString(const CxJsonValue *value);
 
 /**
  * Obtains a mutable UCX string from the given JSON value.
@@ -1175,8 +1175,8 @@
  * @return the value represented as mutable UCX string
  * @see cxJsonIsString()
  */
-cx_attr_nonnull
-CX_EXPORT cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_NODISCARD
+cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value);
 
 /**
  * Obtains a double-precision floating-point value from the given JSON value.
@@ -1187,8 +1187,8 @@
  * @return the value represented as double
  * @see cxJsonIsNumber()
  */
-cx_attr_nonnull
-CX_EXPORT double cxJsonAsDouble(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_NODISCARD
+double cxJsonAsDouble(const CxJsonValue *value);
 
 /**
  * Obtains a 64-bit signed integer from the given JSON value.
@@ -1202,8 +1202,8 @@
  * @see cxJsonIsNumber()
  * @see cxJsonIsInteger()
  */
-cx_attr_nonnull
-CX_EXPORT int64_t cxJsonAsInteger(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_NODISCARD
+int64_t cxJsonAsInteger(const CxJsonValue *value);
 
 /**
  * Obtains a Boolean value from the given JSON value.
@@ -1215,8 +1215,8 @@
  * @return the value represented as double
  * @see cxJsonIsLiteral()
  */
-cx_attr_nonnull
-CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+bool cxJsonAsBool(const CxJsonValue *value) {
     return value->literal == CX_JSON_TRUE;
 }
 
@@ -1229,8 +1229,8 @@
  * @return the size of the array
  * @see cxJsonIsArray()
  */
-cx_attr_nonnull
-CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) {
+CX_NONNULL CX_NODISCARD CX_INLINE
+size_t cxJsonArrSize(const CxJsonValue *value) {
     return value->array.size;
 }
 
@@ -1248,8 +1248,8 @@
  * @return the value at the specified index
  * @see cxJsonIsArray()
  */
-cx_attr_nonnull cx_attr_returns_nonnull
-CX_EXPORT CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
+CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
+CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
 
 /**
  * Removes an element from a JSON array.
@@ -1264,8 +1264,8 @@
  * @return the removed value from the specified index or @c NULL when the index was out of bounds
  * @see cxJsonIsArray()
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index);
+CX_EXTERN CX_NONNULL
+CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index);
 
 /**
  * Returns an iterator over the JSON array elements.
@@ -1278,8 +1278,8 @@
  * @return an iterator over the array elements
  * @see cxJsonIsArray()
  */
-cx_attr_nonnull cx_attr_nodiscard
-CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_NODISCARD
+CxIterator cxJsonArrIter(const CxJsonValue *value);
 
 /**
  * Returns the size of a JSON object.
@@ -1290,8 +1290,8 @@
  * @return the size of the object, i.e., the number of key/value pairs
  * @see cxJsonIsObject()
  */
-cx_attr_nonnull
-CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) {
+CX_NONNULL CX_INLINE
+size_t cxJsonObjSize(const CxJsonValue *value) {
     return cxCollectionSize(value->object);
 }
 
@@ -1307,8 +1307,8 @@
  * @return an iterator over the object members
  * @see cxJsonIsObject()
  */
-cx_attr_nonnull cx_attr_nodiscard
-CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value);
+CX_EXTERN CX_NONNULL CX_NODISCARD
+CxMapIterator cxJsonObjIter(const CxJsonValue *value);
 
 /**
  * Internal function, do not use.
@@ -1316,8 +1316,8 @@
  * @param name the key to look up
  * @return the value corresponding to the key
  */
-cx_attr_nonnull cx_attr_returns_nonnull
-CX_EXPORT CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name);
+CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
+CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name);
 
 /**
  * Returns a value corresponding to a key in a JSON object.
@@ -1341,8 +1341,8 @@
  * @param name the key to look up
  * @return the value corresponding to the key or @c NULL when the key is not part of the object
  */
-cx_attr_nonnull
-CX_EXPORT CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name);
+CX_EXTERN CX_NONNULL
+CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name);
 
 /**
  * Removes and returns a value corresponding to a key in a JSON object.
@@ -1369,7 +1369,8 @@
  * @retval zero the values are equal (except for ordering of object members)
  * @retval non-zero the values differ
  */
-CX_EXPORT int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other);
+CX_EXTERN CX_NODISCARD
+int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other);
 
 
 /**
@@ -1385,11 +1386,10 @@
  * @return the new value or @c NULL if any allocation was unsuccessful
  * @see cxJsonCloneFunc()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cxJsonClone(const CxJsonValue* value,
+CX_EXTERN CX_NODISCARD
+CxJsonValue* cxJsonClone(const CxJsonValue* value,
         const CxAllocator* allocator);
 
-
 /**
  * A @c cx_clone_func compatible version of cxJsonClone().
  *
@@ -1402,8 +1402,8 @@
  * @return the new value or @c NULL if any allocation was unsuccessful
  * @see cxJsonClone()
  */
-cx_attr_nodiscard
-CX_EXPORT CxJsonValue* cx_json_clone_func(
+CX_EXTERN CX_NODISCARD
+CxJsonValue* cx_json_clone_func(
         CxJsonValue* target, const CxJsonValue* source,
         const CxAllocator* allocator, void *data);
 
@@ -1419,9 +1419,5 @@
  */
 #define cxJsonCloneFunc  ((cx_clone_func) cx_json_clone_func)
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* UCX_JSON_H */
 

mercurial