ucx/cx/json.h

changeset 16
04c9f8d8f03b
parent 11
0aa8cbd7912e
child 22
112b85020dc9
--- a/ucx/cx/json.h	Sun Feb 16 17:38:07 2025 +0100
+++ b/ucx/cx/json.h	Tue Feb 25 21:12:11 2025 +0100
@@ -26,11 +26,11 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /**
- * \file json.h
- * \brief Interface for parsing data from JSON files.
- * \author Mike Becker
- * \author Olaf Wintermann
- * \copyright 2-Clause BSD License
+ * @file json.h
+ * @brief Interface for parsing data from JSON files.
+ * @author Mike Becker
+ * @author Olaf Wintermann
+ * @copyright 2-Clause BSD License
  */
 
 #ifndef UCX_JSON_H
@@ -146,15 +146,15 @@
  */
 enum cx_json_literal {
     /**
-     * The \c null literal.
+     * The @c null literal.
      */
     CX_JSON_NULL,
     /**
-     * The \c true literal.
+     * The @c true literal.
      */
     CX_JSON_TRUE,
     /**
-     * The \c false literal.
+     * The @c false literal.
      */
     CX_JSON_FALSE
 };
@@ -264,7 +264,7 @@
     /**
      * The type of this value.
      *
-     * Specifies how the \c value union shall be resolved.
+     * Specifies how the @c value union shall be resolved.
      */
     CxJsonValueType type;
     /**
@@ -309,7 +309,7 @@
      */
     CxJsonTokenType tokentype;
     /**
-     * True, iff the \c content must be passed to cx_strfree().
+     * True, if the @c content must be passed to cx_strfree().
      */
     bool allocated;
     /**
@@ -374,11 +374,6 @@
      * Internally reserved memory for the value buffer stack.
      */
     CxJsonValue* vbuf_internal[8];
-
-    /**
-     * Used internally.
-     */
-    bool tokenizer_escape; // TODO: check if it can be replaced with look-behind
 };
 
 /**
@@ -403,7 +398,7 @@
      * Not used as a status and never returned by any function.
      *
      * You can use this enumerator to check for all "good" status results
-     * by checking if the status is less than \c CX_JSON_OK.
+     * by checking if the status is less than @c CX_JSON_OK.
      *
      * A "good" status means, that you can refill data and continue parsing.
      */
@@ -449,6 +444,8 @@
     bool sort_members;
     /**
      * The maximum number of fractional digits in a number value.
+     * The default value is 6 and values larger than 15 are reduced to 15.
+     * Note, that the actual number of digits may be lower, depending on the concrete number.
      */
     uint8_t frac_max_digits;
     /**
@@ -457,10 +454,14 @@
      */
     bool indent_space;
     /**
-     * If \c indent_space is true, this is the number of spaces per tab.
+     * If @c indent_space is true, this is the number of spaces per tab.
      * Indentation is only used in pretty output.
      */
     uint8_t indent;
+    /**
+     * Set true to enable escaping of the slash character (solidus).
+     */
+    bool escape_slash;
 };
 
 /**
@@ -474,6 +475,7 @@
  * @return new JSON writer settings
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonWriter cxJsonWriterCompact(void);
 
 /**
@@ -483,17 +485,17 @@
  * @return new JSON writer settings
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonWriter cxJsonWriterPretty(bool use_spaces);
 
 /**
  * Writes a JSON value to a buffer or stream.
  *
- * This function blocks until all data is written or an error when trying
- * to write data occurs.
+ * This function blocks until either all data is written, or an error occurs.
  * The write operation is not atomic in the sense that it might happen
  * that the data is only partially written when an error occurs with no
  * way to indicate how much data was written.
- * To avoid this problem, you can use a CxBuffer as \p target which is
+ * To avoid this problem, you can use a CxBuffer as @p target which is
  * unlikely to fail a write operation and either use the buffer's flush
  * feature to relay the data or use the data in the buffer manually to
  * write it to the actual target.
@@ -501,10 +503,12 @@
  * @param target the buffer or stream where to write to
  * @param value the value that shall be written
  * @param wfunc the write function to use
- * @param settings formatting settings (or \c NULL to use a compact default)
- * @return zero on success, non-zero when no or not all data could be written
+ * @param settings formatting settings (or @c NULL to use a compact default)
+ * @retval zero success
+ * @retval non-zero when no or not all data could be written
  */
 cx_attr_nonnull_arg(1, 2, 3)
+cx_attr_export
 int cxJsonWrite(
     void* target,
     const CxJsonValue* value,
@@ -520,6 +524,7 @@
  * @see cxJsonDestroy()
  */
 cx_attr_nonnull_arg(1)
+cx_attr_export
 void cxJsonInit(CxJson *json, const CxAllocator *allocator);
 
 /**
@@ -529,6 +534,7 @@
  * @see cxJsonInit()
  */
 cx_attr_nonnull
+cx_attr_export
 void cxJsonDestroy(CxJson *json);
 
 /**
@@ -560,11 +566,13 @@
  * @param json the json interface
  * @param buf the source buffer
  * @param len the length of the source buffer
- * @return zero on success, non-zero on internal allocation error
+ * @retval zero success
+ * @retval non-zero internal allocation error
  * @see cxJsonFill()
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonFilln(CxJson *json, const char *buf, size_t len);
 
 #ifdef __cplusplus
@@ -600,7 +608,7 @@
 /**
  * Fills the input buffer.
  *
- * @remark The JSON interface tries to avoid copying the input data.
+ * The JSON interface tries to avoid copying the input data.
  * When you use this function and cxJsonNext() interleaving,
  * no copies are performed. However, you must not free the
  * pointer to the data in that case. When you invoke the fill
@@ -609,8 +617,9 @@
  * an allocation of a new buffer and copying the previous contents.
  *
  * @param json the json interface
- * @param buf the source string
- * @return zero on success, non-zero on internal allocation error
+ * @param str the source string
+ * @retval zero success
+ * @retval non-zero internal allocation error
  * @see cxJsonFilln()
  */
 #define cxJsonFill(json, str) _Generic((str), \
@@ -659,18 +668,24 @@
  * Creates a new (empty) JSON object.
  *
  * @param allocator the allocator to use
- * @return the new JSON object or \c NULL if allocation fails
+ * @return the new JSON object or @c NULL if allocation fails
+ * @see cxJsonObjPutObj()
+ * @see cxJsonArrAddValues()
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
 
 /**
  * Creates a new (empty) JSON array.
  *
  * @param allocator the allocator to use
- * @return the new JSON array or \c NULL if allocation fails
+ * @return the new JSON array or @c NULL if allocation fails
+ * @see cxJsonObjPutArr()
+ * @see cxJsonArrAddValues()
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator);
 
 /**
@@ -678,11 +693,12 @@
  *
  * @param allocator the allocator to use
  * @param num the numeric value
- * @return the new JSON value or \c NULL if allocation fails
+ * @return the new JSON value or @c NULL if allocation fails
  * @see cxJsonObjPutNumber()
  * @see cxJsonArrAddNumbers()
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
 
 /**
@@ -690,11 +706,12 @@
  *
  * @param allocator the allocator to use
  * @param num the numeric value
- * @return the new JSON value or \c NULL if allocation fails
+ * @return the new JSON value or @c NULL if allocation fails
  * @see cxJsonObjPutInteger()
  * @see cxJsonArrAddIntegers()
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
 
 /**
@@ -702,14 +719,15 @@
  *
  * @param allocator the allocator to use
  * @param str the string data
- * @return the new JSON value or \c NULL if allocation fails
- * @see cxJsonCreateCxString()
+ * @return the new JSON value or @c NULL if allocation fails
+ * @see cxJsonCreateString()
  * @see cxJsonObjPutString()
  * @see cxJsonArrAddStrings()
  */
 cx_attr_nodiscard
 cx_attr_nonnull_arg(2)
 cx_attr_cstr_arg(2)
+cx_attr_export
 CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char *str);
 
 /**
@@ -717,12 +735,13 @@
  *
  * @param allocator the allocator to use
  * @param str the string data
- * @return the new JSON value or \c NULL if allocation fails
- * @see cxJsonCreateString()
+ * @return the new JSON value or @c NULL if allocation fails
+ * @see cxJsonCreateCxString()
  * @see cxJsonObjPutCxString()
  * @see cxJsonArrAddCxStrings()
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str);
 
 /**
@@ -730,11 +749,12 @@
  *
  * @param allocator the allocator to use
  * @param lit the type of literal
- * @return the new JSON value or \c NULL if allocation fails
+ * @return the new JSON value or @c NULL if allocation fails
  * @see cxJsonObjPutLiteral()
  * @see cxJsonArrAddLiterals()
  */
 cx_attr_nodiscard
+cx_attr_export
 CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
 
 /**
@@ -743,10 +763,12 @@
  * @param arr the JSON array
  * @param num the array of values
  * @param count the number of elements
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
 
 /**
@@ -755,10 +777,12 @@
  * @param arr the JSON array
  * @param num the array of values
  * @param count the number of elements
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
 
 /**
@@ -769,11 +793,13 @@
  * @param arr the JSON array
  * @param str the array of strings
  * @param count the number of elements
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  * @see cxJsonArrAddCxStrings()
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
 
 /**
@@ -784,11 +810,13 @@
  * @param arr the JSON array
  * @param str the array of strings
  * @param count the number of elements
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  * @see cxJsonArrAddStrings()
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
 
 /**
@@ -797,25 +825,29 @@
  * @param arr the JSON array
  * @param lit the array of literal types
  * @param count the number of elements
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
 
 /**
  * Add arbitrary values to a JSON array.
  *
- * \note In contrast to all other add functions, this function adds the values
+ * @attention In contrast to all other add functions, this function adds the values
  * directly to the array instead of copying them.
  *
  * @param arr the JSON array
  * @param val the values
  * @param count the number of elements
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  */
 cx_attr_nonnull
 cx_attr_access_r(2, 3)
+cx_attr_export
 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
 
 /**
@@ -823,15 +855,17 @@
  *
  * The value will be directly added and not copied.
  *
- * \note If a value with the specified \p name already exists,
+ * @note If a value with the specified @p name already exists,
  * it will be (recursively) freed with its own allocator.
  *
  * @param obj the JSON object
  * @param name the name of the value
  * @param child the value
- * @return zero on success, non-zero on allocation failure
+ * @retval zero success
+ * @retval non-zero allocation failure
  */
 cx_attr_nonnull
+cx_attr_export
 int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child);
 
 /**
@@ -839,11 +873,12 @@
  *
  * @param obj the target JSON object
  * @param name the name of the new value
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateObj()
  */
 cx_attr_nonnull
+cx_attr_export
 CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name);
 
 /**
@@ -851,11 +886,12 @@
  *
  * @param obj the target JSON object
  * @param name the name of the new value
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateArr()
  */
 cx_attr_nonnull
+cx_attr_export
 CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name);
 
 /**
@@ -864,11 +900,12 @@
  * @param obj the target JSON object
  * @param name the name of the new value
  * @param num the numeric value
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateNumber()
  */
 cx_attr_nonnull
+cx_attr_export
 CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num);
 
 /**
@@ -877,11 +914,12 @@
  * @param obj the target JSON object
  * @param name the name of the new value
  * @param num the numeric value
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateInteger()
  */
 cx_attr_nonnull
+cx_attr_export
 CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num);
 
 /**
@@ -892,12 +930,13 @@
  * @param obj the target JSON object
  * @param name the name of the new value
  * @param str the string data
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateString()
  */
 cx_attr_nonnull
 cx_attr_cstr_arg(3)
+cx_attr_export
 CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str);
 
 /**
@@ -908,11 +947,12 @@
  * @param obj the target JSON object
  * @param name the name of the new value
  * @param str the string data
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateCxString()
  */
 cx_attr_nonnull
+cx_attr_export
 CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str);
 
 /**
@@ -921,17 +961,18 @@
  * @param obj the target JSON object
  * @param name the name of the new value
  * @param lit the type of literal
- * @return the new value or \c NULL if allocation fails
+ * @return the new value or @c NULL if allocation fails
  * @see cxJsonObjPut()
  * @see cxJsonCreateLiteral()
  */
 cx_attr_nonnull
+cx_attr_export
 CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
 
 /**
  * Recursively deallocates the memory of a JSON value.
  *
- * \remark The type of each deallocated value will be changed
+ * @remark The type of each deallocated value will be changed
  * to #CX_JSON_NOTHING and values of such type will be skipped
  * by the de-allocation. That means, this function protects
  * you from double-frees when you are accidentally freeing
@@ -939,25 +980,42 @@
  *
  * @param value the value
  */
+cx_attr_export
 void cxJsonValueFree(CxJsonValue *value);
 
 /**
  * Tries to obtain the next JSON value.
  *
+ * Before this function can be called, the input buffer needs
+ * to be filled with cxJsonFill().
+ *
+ * When this function returns #CX_JSON_INCOMPLETE_DATA, you can
+ * add the missing data with another invocation of cxJsonFill()
+ * and then repeat the call to cxJsonNext().
  *
  * @param json the json interface
  * @param value a pointer where the next value shall be stored
- * @return a status code
+ * @retval CX_JSON_NO_ERROR successfully retrieve the @p value
+ * @retval CX_JSON_NO_DATA there is no (more) data in the buffer to read from
+ * @retval CX_JSON_INCOMPLETE_DATA an incomplete value was read
+ * and more data needs to be filled
+ * @retval CX_JSON_NULL_DATA the buffer was never initialized
+ * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed
+ * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for a CxJsonValue failed
+ * @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_attr_export
 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
 
 /**
  * Checks if the specified value is a JSON object.
  *
  * @param value a pointer to the value
- * @return true if the value is a JSON object, false otherwise
+ * @retval true the value is a JSON object
+ * @retval false otherwise
  */
 cx_attr_nonnull
 static inline bool cxJsonIsObject(const CxJsonValue *value) {
@@ -968,7 +1026,8 @@
  * Checks if the specified value is a JSON array.
  *
  * @param value a pointer to the value
- * @return true if the value is a JSON array, false otherwise
+ * @retval true the value is a JSON array
+ * @retval false otherwise
  */
 cx_attr_nonnull
 static inline bool cxJsonIsArray(const CxJsonValue *value) {
@@ -979,7 +1038,8 @@
  * Checks if the specified value is a string.
  *
  * @param value a pointer to the value
- * @return true if the value is a string, false otherwise
+ * @retval true the value is a string
+ * @retval false otherwise
  */
 cx_attr_nonnull
 static inline bool cxJsonIsString(const CxJsonValue *value) {
@@ -993,7 +1053,8 @@
  * integer numbers.
  *
  * @param value a pointer to the value
- * @return true if the value is a JSON number, false otherwise
+ * @retval true the value is a JSON number
+ * @retval false otherwise
  * @see cxJsonIsInteger()
  */
 cx_attr_nonnull
@@ -1005,7 +1066,8 @@
  * Checks if the specified value is an integer number.
  *
  * @param value a pointer to the value
- * @return true if the value is an integer number, false otherwise
+ * @retval true the value is an integer number
+ * @retval false otherwise
  * @see cxJsonIsNumber()
  */
 cx_attr_nonnull
@@ -1016,10 +1078,11 @@
 /**
  * Checks if the specified value is a JSON literal.
  *
- * JSON literals are \c true, \c false, and \c null.
+ * JSON literals are @c true, @c false, and @c null.
  *
  * @param value a pointer to the value
- * @return true if the value is a JSON literal, false otherwise
+ * @retval true the value is a JSON literal
+ * @retval false otherwise
  * @see cxJsonIsTrue()
  * @see cxJsonIsFalse()
  * @see cxJsonIsNull()
@@ -1033,7 +1096,8 @@
  * Checks if the specified value is a Boolean literal.
  *
  * @param value a pointer to the value
- * @return true if the value is either \c true or \c false, false otherwise
+ * @retval true the value is either @c true or @c false
+ * @retval false otherwise
  * @see cxJsonIsTrue()
  * @see cxJsonIsFalse()
  */
@@ -1043,13 +1107,14 @@
 }
 
 /**
- * Checks if the specified value is \c true.
+ * Checks if the specified value is @c true.
  *
- * \remark Be advised, that this is not the same as
- * testing \c !cxJsonIsFalse(v).
+ * @remark Be advised, that this is not the same as
+ * testing @c !cxJsonIsFalse(v).
  *
  * @param value a pointer to the value
- * @return true if the value is \c true, false otherwise
+ * @retval true the value is @c true
+ * @retval false otherwise
  * @see cxJsonIsBool()
  * @see cxJsonIsFalse()
  */
@@ -1059,13 +1124,14 @@
 }
 
 /**
- * Checks if the specified value is \c false.
+ * Checks if the specified value is @c false.
  *
- * \remark Be advised, that this is not the same as
- * testing \c !cxJsonIsTrue(v).
+ * @remark Be advised, that this is not the same as
+ * testing @c !cxJsonIsTrue(v).
  *
  * @param value a pointer to the value
- * @return true if the value is \c false, false otherwise
+ * @retval true the value is @c false
+ * @retval false otherwise
  * @see cxJsonIsBool()
  * @see cxJsonIsTrue()
  */
@@ -1075,10 +1141,11 @@
 }
 
 /**
- * Checks if the specified value is \c null.
+ * Checks if the specified value is @c null.
  *
  * @param value a pointer to the value
- * @return true if the value is \c null, false otherwise
+ * @retval true the value is @c null
+ * @retval false otherwise
  * @see cxJsonIsLiteral()
  */
 cx_attr_nonnull
@@ -1089,7 +1156,7 @@
 /**
  * Obtains a C string from the given JSON value.
  *
- * If the \p value is not a string, the behavior is undefined.
+ * If the @p value is not a string, the behavior is undefined.
  *
  * @param value the JSON value
  * @return the value represented as C string
@@ -1104,7 +1171,7 @@
 /**
  * Obtains a UCX string from the given JSON value.
  *
- * If the \p value is not a string, the behavior is undefined.
+ * If the @p value is not a string, the behavior is undefined.
  *
  * @param value the JSON value
  * @return the value represented as UCX string
@@ -1118,7 +1185,7 @@
 /**
  * Obtains a mutable UCX string from the given JSON value.
  *
- * If the \p value is not a string, the behavior is undefined.
+ * If the @p value is not a string, the behavior is undefined.
  *
  * @param value the JSON value
  * @return the value represented as mutable UCX string
@@ -1132,7 +1199,7 @@
 /**
  * Obtains a double-precision floating point value from the given JSON value.
  *
- * If the \p value is not a JSON number, the behavior is undefined.
+ * If the @p value is not a JSON number, the behavior is undefined.
  *
  * @param value the JSON value
  * @return the value represented as double
@@ -1150,7 +1217,7 @@
 /**
  * Obtains a 64-bit signed integer from the given JSON value.
  *
- * If the \p value is not a JSON number, the behavior is undefined.
+ * If the @p value is not a JSON number, the behavior is undefined.
  * If it is a JSON number, but not an integer, the value will be
  * converted to an integer, possibly losing precision.
  *
@@ -1171,8 +1238,8 @@
 /**
  * Obtains a Boolean value from the given JSON value.
  *
- * If the \p value is not a JSON literal, the behavior is undefined.
- * The \c null literal is interpreted as \c false.
+ * If the @p value is not a JSON literal, the behavior is undefined.
+ * The @c null literal is interpreted as @c false.
  *
  * @param value the JSON value
  * @return the value represented as double
@@ -1186,7 +1253,7 @@
 /**
  * Returns the size of a JSON array.
  *
- * If the \p value is not a JSON array, the behavior is undefined.
+ * If the @p value is not a JSON array, the behavior is undefined.
  *
  * @param value the JSON value
  * @return the size of the array
@@ -1200,11 +1267,11 @@
 /**
  * Returns an element from a JSON array.
  *
- * If the \p value is not a JSON array, the behavior is undefined.
+ * If the @p value is not a JSON array, the behavior is undefined.
  *
  * This function guarantees to return a value. If the index is
  * out of bounds, the returned value will be of type
- * #CX_JSON_NOTHING, but never \c NULL.
+ * #CX_JSON_NOTHING, but never @c NULL.
  *
  * @param value the JSON value
  * @param index the index in the array
@@ -1213,14 +1280,15 @@
  */
 cx_attr_nonnull
 cx_attr_returns_nonnull
+cx_attr_export
 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
 
 /**
  * Returns an iterator over the JSON array elements.
  *
- * The iterator yields values of type \c CxJsonValue* .
+ * The iterator yields values of type @c CxJsonValue* .
  *
- * If the \p value is not a JSON array, the behavior is undefined.
+ * If the @p value is not a JSON array, the behavior is undefined.
  *
  * @param value the JSON value
  * @return an iterator over the array elements
@@ -1228,15 +1296,16 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
+cx_attr_export
 CxIterator cxJsonArrIter(const CxJsonValue *value);
 
 /**
  * Returns an iterator over the JSON object members.
  *
- * The iterator yields values of type \c CxJsonObjValue* which
+ * The iterator yields values of type @c CxJsonObjValue* which
  * contain the name and value of the member.
  *
- * If the \p value is not a JSON object, the behavior is undefined.
+ * If the @p value is not a JSON object, the behavior is undefined.
  *
  * @param value the JSON value
  * @return an iterator over the object members
@@ -1244,6 +1313,7 @@
  */
 cx_attr_nonnull
 cx_attr_nodiscard
+cx_attr_export
 CxIterator cxJsonObjIter(const CxJsonValue *value);
 
 /**
@@ -1251,20 +1321,21 @@
  */
 cx_attr_nonnull
 cx_attr_returns_nonnull
+cx_attr_export
 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name);
 
 #ifdef __cplusplus
 } // extern "C"
 
-CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxstring name) {
+static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxstring name) {
     return cx_json_obj_get_cxstr(value, name);
 }
 
-CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxmutstr name) {
+static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxmutstr name) {
     return cx_json_obj_get_cxstr(value, cx_strcast(name));
 }
 
-CxJsonValue *cxJsonObjGet(const CxJsonValue *value, const char *name) {
+static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, const char *name) {
     return cx_json_obj_get_cxstr(value, cx_str(name));
 }
 
@@ -1273,11 +1344,11 @@
 /**
  * Returns a value corresponding to a key in a JSON object.
  *
- * If the \p value is not a JSON object, the behavior is undefined.
+ * If the @p value is not a JSON object, the behavior is undefined.
  *
  * This function guarantees to return a JSON value. If the
- * object does not contain \p name, the returned JSON value
- * will be of type #CX_JSON_NOTHING, but never \c NULL.
+ * object does not contain @p name, the returned JSON value
+ * will be of type #CX_JSON_NOTHING, but never @c NULL.
  *
  * @param value the JSON object
  * @param name the key to look up

mercurial