| 24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
| 25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
| 26  * POSSIBILITY OF SUCH DAMAGE. | 26  * POSSIBILITY OF SUCH DAMAGE. | 
| 27  */ | 27  */ | 
| 28 /** | 28 /** | 
| 29  * \file properties.h | 29  * @file properties.h | 
| 30  * \brief Interface for parsing data from properties files. | 30  * @brief Interface for parsing data from properties files. | 
| 31  * \author Mike Becker | 31  * @author Mike Becker | 
| 32  * \author Olaf Wintermann | 32  * @author Olaf Wintermann | 
| 33  * \copyright 2-Clause BSD License | 33  * @copyright 2-Clause BSD License | 
| 34  */ | 34  */ | 
| 35 | 35 | 
| 36 #ifndef UCX_PROPERTIES_H | 36 #ifndef UCX_PROPERTIES_H | 
| 37 #define UCX_PROPERTIES_H | 37 #define UCX_PROPERTIES_H | 
| 38 | 38 | 
| 114     CX_PROPERTIES_INCOMPLETE_DATA, | 114     CX_PROPERTIES_INCOMPLETE_DATA, | 
| 115     /** | 115     /** | 
| 116      * Not used as a status and never returned by any function. | 116      * Not used as a status and never returned by any function. | 
| 117      * | 117      * | 
| 118      * You can use this enumerator to check for all "good" status results | 118      * You can use this enumerator to check for all "good" status results | 
| 119      * by checking if the status is less than \c CX_PROPERTIES_OK. | 119      * by checking if the status is less than @c CX_PROPERTIES_OK. | 
| 120      * | 120      * | 
| 121      * A "good" status means, that you can refill data and continue parsing. | 121      * A "good" status means, that you can refill data and continue parsing. | 
| 122      */ | 122      */ | 
| 123     CX_PROPERTIES_OK, | 123     CX_PROPERTIES_OK, | 
| 124     /** | 124     /** | 
| 125      * Input buffer is \c NULL. | 125      * Input buffer is @c NULL. | 
| 126      */ | 126      */ | 
| 127     CX_PROPERTIES_NULL_INPUT, | 127     CX_PROPERTIES_NULL_INPUT, | 
| 128     /** | 128     /** | 
| 129      * The line contains a delimiter, but no key. | 129      * The line contains a delimiter, but no key. | 
| 130      */ | 130      */ | 
| 201  * | 201  * | 
| 202  * @param prop the properties interface that wants to sink a k/v-pair | 202  * @param prop the properties interface that wants to sink a k/v-pair | 
| 203  * @param sink the sink | 203  * @param sink the sink | 
| 204  * @param key the key | 204  * @param key the key | 
| 205  * @param value the value | 205  * @param value the value | 
| 206  * @return zero on success, non-zero when sinking the k/v-pair failed | 206  * @retval zero success | 
|  | 207  * @retval non-zero sinking the k/v-pair failed | 
| 207  */ | 208  */ | 
| 208 cx_attr_nonnull | 209 cx_attr_nonnull | 
| 209 typedef int(*cx_properties_sink_func)( | 210 typedef int(*cx_properties_sink_func)( | 
| 210         CxProperties *prop, | 211         CxProperties *prop, | 
| 211         CxPropertiesSink *sink, | 212         CxPropertiesSink *sink, | 
| 239 | 240 | 
| 240 /** | 241 /** | 
| 241  * A function that reads data from a source. | 242  * A function that reads data from a source. | 
| 242  * | 243  * | 
| 243  * When the source is depleted, implementations SHALL provide an empty | 244  * When the source is depleted, implementations SHALL provide an empty | 
| 244  * string in the \p target and return zero. | 245  * string in the @p target and return zero. | 
| 245  * A non-zero return value is only permitted in case of an error. | 246  * A non-zero return value is only permitted in case of an error. | 
| 246  * | 247  * | 
| 247  * The meaning of the optional parameters is implementation-dependent. | 248  * The meaning of the optional parameters is implementation-dependent. | 
| 248  * | 249  * | 
| 249  * @param prop the properties interface that wants to read from the source | 250  * @param prop the properties interface that wants to read from the source | 
| 250  * @param src the source | 251  * @param src the source | 
| 251  * @param target a string buffer where the read data shall be stored | 252  * @param target a string buffer where the read data shall be stored | 
| 252  * @return zero on success, non-zero when reading data failed | 253  * @retval zero success | 
|  | 254  * @retval non-zero reading the data failed | 
| 253  */ | 255  */ | 
| 254 cx_attr_nonnull | 256 cx_attr_nonnull | 
| 255 typedef int(*cx_properties_read_func)( | 257 typedef int(*cx_properties_read_func)( | 
| 256         CxProperties *prop, | 258         CxProperties *prop, | 
| 257         CxPropertiesSource *src, | 259         CxPropertiesSource *src, | 
| 261 /** | 263 /** | 
| 262  * A function that may initialize additional memory for the source. | 264  * A function that may initialize additional memory for the source. | 
| 263  * | 265  * | 
| 264  * @param prop the properties interface that wants to read from the source | 266  * @param prop the properties interface that wants to read from the source | 
| 265  * @param src the source | 267  * @param src the source | 
| 266  * @return zero when initialization was successful, non-zero otherwise | 268  * @retval zero initialization was successful | 
|  | 269  * @retval non-zero otherwise | 
| 267  */ | 270  */ | 
| 268 cx_attr_nonnull | 271 cx_attr_nonnull | 
| 269 typedef int(*cx_properties_read_init_func)( | 272 typedef int(*cx_properties_read_init_func)( | 
| 270         CxProperties *prop, | 273         CxProperties *prop, | 
| 271         CxPropertiesSource *src | 274         CxPropertiesSource *src | 
| 327 void cxPropertiesInit(CxProperties *prop, CxPropertiesConfig config); | 330 void cxPropertiesInit(CxProperties *prop, CxPropertiesConfig config); | 
| 328 | 331 | 
| 329 /** | 332 /** | 
| 330  * Destroys the properties interface. | 333  * Destroys the properties interface. | 
| 331  * | 334  * | 
| 332  * \note Even when you are certain that you did not use the interface in a | 335  * @note Even when you are certain that you did not use the interface in a | 
| 333  * way that caused a memory allocation, you should call this function anyway. | 336  * way that caused a memory allocation, you should call this function anyway. | 
| 334  * Future versions of the library might add features that need additional memory | 337  * Future versions of the library might add features that need additional memory | 
| 335  * and you really don't want to search the entire code where you might need | 338  * and you really don't want to search the entire code where you might need | 
| 336  * add call to this function. | 339  * add call to this function. | 
| 337  * | 340  * | 
| 356 } | 359 } | 
| 357 | 360 | 
| 358 /** | 361 /** | 
| 359  * Initialize a properties parser with the default configuration. | 362  * Initialize a properties parser with the default configuration. | 
| 360  * | 363  * | 
| 361  * @param prop the properties interface | 364  * @param prop (@c CxProperties*) the properties interface | 
| 362  * @see cxPropertiesInit() | 365  * @see cxPropertiesInit() | 
| 363  */ | 366  */ | 
| 364 #define cxPropertiesInitDefault(prop) \ | 367 #define cxPropertiesInitDefault(prop) \ | 
| 365     cxPropertiesInit(prop, cx_properties_config_default) | 368     cxPropertiesInit(prop, cx_properties_config_default) | 
| 366 | 369 | 
| 379  * an allocation of a new buffer and copying the previous contents. | 382  * an allocation of a new buffer and copying the previous contents. | 
| 380  * | 383  * | 
| 381  * @param prop the properties interface | 384  * @param prop the properties interface | 
| 382  * @param buf a pointer to the data | 385  * @param buf a pointer to the data | 
| 383  * @param len the length of the data | 386  * @param len the length of the data | 
| 384  * @return non-zero when a memory allocation was necessary but failed | 387  * @retval zero success | 
|  | 388  * @retval non-zero a memory allocation was necessary but failed | 
| 385  * @see cxPropertiesFill() | 389  * @see cxPropertiesFill() | 
| 386  */ | 390  */ | 
| 387 cx_attr_nonnull | 391 cx_attr_nonnull | 
| 388 cx_attr_access_r(2, 3) | 392 cx_attr_access_r(2, 3) | 
| 389 int cxPropertiesFilln( | 393 int cxPropertiesFilln( | 
| 435  * the additional data is appended - inevitably leading to | 439  * the additional data is appended - inevitably leading to | 
| 436  * an allocation of a new buffer and copying the previous contents. | 440  * an allocation of a new buffer and copying the previous contents. | 
| 437  * | 441  * | 
| 438  * @param prop the properties interface | 442  * @param prop the properties interface | 
| 439  * @param str the text to fill in | 443  * @param str the text to fill in | 
| 440  * @return non-zero when a memory allocation was necessary but failed | 444  * @retval zero success | 
|  | 445  * @retval non-zero a memory allocation was necessary but failed | 
| 441  * @see cxPropertiesFilln() | 446  * @see cxPropertiesFilln() | 
| 442  */ | 447  */ | 
| 443 #define cxPropertiesFill(prop, str) _Generic((str), \ | 448 #define cxPropertiesFill(prop, str) _Generic((str), \ | 
| 444     cxstring: cx_properties_fill_cxstr,             \ | 449     cxstring: cx_properties_fill_cxstr,             \ | 
| 445     cxmutstr: cx_properties_fill_mutstr,            \ | 450     cxmutstr: cx_properties_fill_mutstr,            \ | 
| 503  * If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA is returned. | 508  * If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA is returned. | 
| 504  * | 509  * | 
| 505  * When an incomplete line is encountered, #CX_PROPERTIES_INCOMPLETE_DATA is | 510  * When an incomplete line is encountered, #CX_PROPERTIES_INCOMPLETE_DATA is | 
| 506  * returned, and you can add more data with #cxPropertiesFill(). | 511  * returned, and you can add more data with #cxPropertiesFill(). | 
| 507  * | 512  * | 
| 508  * \remark The incomplete line will be stored in an internal buffer, which is | 513  * @remark The incomplete line will be stored in an internal buffer, which is | 
| 509  * allocated on the heap, by default. If you want to avoid allocations, | 514  * allocated on the heap, by default. If you want to avoid allocations, | 
| 510  * you can specify sufficient space with cxPropertiesUseStack() after | 515  * you can specify sufficient space with cxPropertiesUseStack() after | 
| 511  * initialization with cxPropertiesInit(). | 516  * initialization with cxPropertiesInit(). | 
| 512  * | 517  * | 
| 513  * \attention The returned strings will point into a buffer that might not be | 518  * @attention The returned strings will point into a buffer that might not be | 
| 514  * available later. It is strongly recommended to copy the strings for further | 519  * available later. It is strongly recommended to copy the strings for further | 
| 515  * use. | 520  * use. | 
| 516  * | 521  * | 
| 517  * @param prop the properties interface | 522  * @param prop the properties interface | 
| 518  * @param key a pointer to the cxstring that shall contain the property name | 523  * @param key a pointer to the cxstring that shall contain the property name | 
| 519  * @param value a pointer to the cxstring that shall contain the property value | 524  * @param value a pointer to the cxstring that shall contain the property value | 
| 520  * @return the status code as defined above | 525  * @retval CX_PROPERTIES_NO_ERROR (zero) a key/value pair was found | 
| 521  * @see cxPropertiesFill() | 526  * @retval CX_PROPERTIES_NO_DATA there is no (more) data in the input buffer | 
|  | 527  * @retval CX_PROPERTIES_INCOMPLETE_DATA the data in the input buffer is incomplete | 
|  | 528  * (fill more data and try again) | 
|  | 529  * @retval CX_PROPERTIES_NULL_INPUT the input buffer was never filled | 
|  | 530  * @retval CX_PROPERTIES_INVALID_EMPTY_KEY the properties data contains an illegal empty key | 
|  | 531  * @retval CX_PROPERTIES_INVALID_MISSING_DELIMITER the properties data contains a line without delimiter | 
|  | 532  * @retval CX_PROPERTIES_BUFFER_ALLOC_FAILED an internal allocation was necessary but failed | 
| 522  */ | 533  */ | 
| 523 cx_attr_nonnull | 534 cx_attr_nonnull | 
| 524 cx_attr_nodiscard | 535 cx_attr_nodiscard | 
| 525 CxPropertiesStatus cxPropertiesNext( | 536 CxPropertiesStatus cxPropertiesNext( | 
| 526         CxProperties *prop, | 537         CxProperties *prop, | 
| 532  * Creates a properties sink for an UCX map. | 543  * Creates a properties sink for an UCX map. | 
| 533  * | 544  * | 
| 534  * The values stored in the map will be pointers to strings allocated | 545  * The values stored in the map will be pointers to strings allocated | 
| 535  * by #cx_strdup_a(). | 546  * by #cx_strdup_a(). | 
| 536  * The default stdlib allocator will be used, unless you specify a custom | 547  * The default stdlib allocator will be used, unless you specify a custom | 
| 537  * allocator in the optional \c data of the sink. | 548  * allocator in the optional @c data of the sink. | 
| 538  * | 549  * | 
| 539  * @param map the map that shall consume the k/v-pairs. | 550  * @param map the map that shall consume the k/v-pairs. | 
| 540  * @return the sink | 551  * @return the sink | 
| 541  * @see cxPropertiesLoad() | 552  * @see cxPropertiesLoad() | 
| 542  */ | 553  */ | 
| 608  * The other result codes apply, according to their description. | 619  * The other result codes apply, according to their description. | 
| 609  * | 620  * | 
| 610  * @param prop the properties interface | 621  * @param prop the properties interface | 
| 611  * @param sink the sink | 622  * @param sink the sink | 
| 612  * @param source the source | 623  * @param source the source | 
| 613  * @return the status of the last operation | 624  * @retval CX_PROPERTIES_NO_ERROR (zero) a key/value pair was found | 
|  | 625  * @retval CX_PROPERTIES_READ_INIT_FAILED initializing the source failed | 
|  | 626  * @retval CX_PROPERTIES_READ_FAILED reading from the source failed | 
|  | 627  * @retval CX_PROPERTIES_SINK_FAILED sinking the properties into the sink failed | 
|  | 628  * @retval CX_PROPERTIES_NO_DATA the source did not provide any key/value pairs | 
|  | 629  * @retval CX_PROPERTIES_INVALID_EMPTY_KEY the properties data contains an illegal empty key | 
|  | 630  * @retval CX_PROPERTIES_INVALID_MISSING_DELIMITER the properties data contains a line without delimiter | 
|  | 631  * @retval CX_PROPERTIES_BUFFER_ALLOC_FAILED an internal allocation was necessary but failed | 
| 614  */ | 632  */ | 
| 615 cx_attr_nonnull | 633 cx_attr_nonnull | 
| 616 CxPropertiesStatus cxPropertiesLoad( | 634 CxPropertiesStatus cxPropertiesLoad( | 
| 617         CxProperties *prop, | 635         CxProperties *prop, | 
| 618         CxPropertiesSink sink, | 636         CxPropertiesSink sink, |