ucx/cx/properties.h

changeset 16
04c9f8d8f03b
parent 11
0aa8cbd7912e
child 21
5ea41679e15d
equal deleted inserted replaced
15:862ab606ee06 16:04c9f8d8f03b
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
57 * This is '=' by default. 57 * This is '=' by default.
58 */ 58 */
59 char delimiter; 59 char delimiter;
60 60
61 /** 61 /**
62 * The first comment character.
63 * This is '#' by default.
64 */
65 char comment1;
66
67 /**
68 * The second comment character.
69 * This is not set by default.
70 */
71 char comment2;
72
73 /**
74 * The third comment character.
75 * This is not set by default.
76 */
77 char comment3;
78
79 /*
62 * The character, when appearing at the end of a line, continues that line. 80 * The character, when appearing at the end of a line, continues that line.
63 * This is '\' by default. 81 * This is '\' by default.
64 */ 82 */
65 // char continuation; // TODO: line continuation in properties 83 /**
66 84 * Reserved for future use.
67 /** 85 */
68 * The first comment character. 86 char continuation;
69 * This is '#' by default.
70 */
71 char comment1;
72
73 /**
74 * The second comment character.
75 * This is not set by default.
76 */
77 char comment2;
78
79 /**
80 * The third comment character.
81 * This is not set by default.
82 */
83 char comment3;
84 }; 87 };
85 88
86 /** 89 /**
87 * Typedef for the properties config. 90 * Typedef for the properties config.
88 */ 91 */
89 typedef struct cx_properties_config_s CxPropertiesConfig; 92 typedef struct cx_properties_config_s CxPropertiesConfig;
90 93
91 /** 94 /**
92 * Default properties configuration. 95 * Default properties configuration.
93 */ 96 */
97 cx_attr_export
94 extern const CxPropertiesConfig cx_properties_config_default; 98 extern const CxPropertiesConfig cx_properties_config_default;
95 99
96 /** 100 /**
97 * Status codes for the properties interface. 101 * Status codes for the properties interface.
98 */ 102 */
114 CX_PROPERTIES_INCOMPLETE_DATA, 118 CX_PROPERTIES_INCOMPLETE_DATA,
115 /** 119 /**
116 * Not used as a status and never returned by any function. 120 * Not used as a status and never returned by any function.
117 * 121 *
118 * You can use this enumerator to check for all "good" status results 122 * 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. 123 * by checking if the status is less than @c CX_PROPERTIES_OK.
120 * 124 *
121 * A "good" status means, that you can refill data and continue parsing. 125 * A "good" status means, that you can refill data and continue parsing.
122 */ 126 */
123 CX_PROPERTIES_OK, 127 CX_PROPERTIES_OK,
124 /** 128 /**
125 * Input buffer is \c NULL. 129 * Input buffer is @c NULL.
126 */ 130 */
127 CX_PROPERTIES_NULL_INPUT, 131 CX_PROPERTIES_NULL_INPUT,
128 /** 132 /**
129 * The line contains a delimiter, but no key. 133 * The line contains a delimiter, but no key.
130 */ 134 */
201 * 205 *
202 * @param prop the properties interface that wants to sink a k/v-pair 206 * @param prop the properties interface that wants to sink a k/v-pair
203 * @param sink the sink 207 * @param sink the sink
204 * @param key the key 208 * @param key the key
205 * @param value the value 209 * @param value the value
206 * @return zero on success, non-zero when sinking the k/v-pair failed 210 * @retval zero success
211 * @retval non-zero sinking the k/v-pair failed
207 */ 212 */
208 cx_attr_nonnull 213 cx_attr_nonnull
209 typedef int(*cx_properties_sink_func)( 214 typedef int(*cx_properties_sink_func)(
210 CxProperties *prop, 215 CxProperties *prop,
211 CxPropertiesSink *sink, 216 CxPropertiesSink *sink,
239 244
240 /** 245 /**
241 * A function that reads data from a source. 246 * A function that reads data from a source.
242 * 247 *
243 * When the source is depleted, implementations SHALL provide an empty 248 * When the source is depleted, implementations SHALL provide an empty
244 * string in the \p target and return zero. 249 * string in the @p target and return zero.
245 * A non-zero return value is only permitted in case of an error. 250 * A non-zero return value is only permitted in case of an error.
246 * 251 *
247 * The meaning of the optional parameters is implementation-dependent. 252 * The meaning of the optional parameters is implementation-dependent.
248 * 253 *
249 * @param prop the properties interface that wants to read from the source 254 * @param prop the properties interface that wants to read from the source
250 * @param src the source 255 * @param src the source
251 * @param target a string buffer where the read data shall be stored 256 * @param target a string buffer where the read data shall be stored
252 * @return zero on success, non-zero when reading data failed 257 * @retval zero success
258 * @retval non-zero reading the data failed
253 */ 259 */
254 cx_attr_nonnull 260 cx_attr_nonnull
255 typedef int(*cx_properties_read_func)( 261 typedef int(*cx_properties_read_func)(
256 CxProperties *prop, 262 CxProperties *prop,
257 CxPropertiesSource *src, 263 CxPropertiesSource *src,
261 /** 267 /**
262 * A function that may initialize additional memory for the source. 268 * A function that may initialize additional memory for the source.
263 * 269 *
264 * @param prop the properties interface that wants to read from the source 270 * @param prop the properties interface that wants to read from the source
265 * @param src the source 271 * @param src the source
266 * @return zero when initialization was successful, non-zero otherwise 272 * @retval zero initialization was successful
273 * @retval non-zero otherwise
267 */ 274 */
268 cx_attr_nonnull 275 cx_attr_nonnull
269 typedef int(*cx_properties_read_init_func)( 276 typedef int(*cx_properties_read_init_func)(
270 CxProperties *prop, 277 CxProperties *prop,
271 CxPropertiesSource *src 278 CxPropertiesSource *src
322 * @param prop the properties interface 329 * @param prop the properties interface
323 * @param config the properties configuration 330 * @param config the properties configuration
324 * @see cxPropertiesInitDefault() 331 * @see cxPropertiesInitDefault()
325 */ 332 */
326 cx_attr_nonnull 333 cx_attr_nonnull
334 cx_attr_export
327 void cxPropertiesInit(CxProperties *prop, CxPropertiesConfig config); 335 void cxPropertiesInit(CxProperties *prop, CxPropertiesConfig config);
328 336
329 /** 337 /**
330 * Destroys the properties interface. 338 * Destroys the properties interface.
331 * 339 *
332 * \note Even when you are certain that you did not use the interface in a 340 * @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. 341 * 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 342 * 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 343 * and you really don't want to search the entire code where you might need
336 * add call to this function. 344 * add call to this function.
337 * 345 *
338 * @param prop the properties interface 346 * @param prop the properties interface
339 */ 347 */
340 cx_attr_nonnull 348 cx_attr_nonnull
349 cx_attr_export
341 void cxPropertiesDestroy(CxProperties *prop); 350 void cxPropertiesDestroy(CxProperties *prop);
342 351
343 /** 352 /**
344 * Destroys and re-initializes the properties interface. 353 * Destroys and re-initializes the properties interface.
345 * 354 *
356 } 365 }
357 366
358 /** 367 /**
359 * Initialize a properties parser with the default configuration. 368 * Initialize a properties parser with the default configuration.
360 * 369 *
361 * @param prop the properties interface 370 * @param prop (@c CxProperties*) the properties interface
362 * @see cxPropertiesInit() 371 * @see cxPropertiesInit()
363 */ 372 */
364 #define cxPropertiesInitDefault(prop) \ 373 #define cxPropertiesInitDefault(prop) \
365 cxPropertiesInit(prop, cx_properties_config_default) 374 cxPropertiesInit(prop, cx_properties_config_default)
366 375
379 * an allocation of a new buffer and copying the previous contents. 388 * an allocation of a new buffer and copying the previous contents.
380 * 389 *
381 * @param prop the properties interface 390 * @param prop the properties interface
382 * @param buf a pointer to the data 391 * @param buf a pointer to the data
383 * @param len the length of the data 392 * @param len the length of the data
384 * @return non-zero when a memory allocation was necessary but failed 393 * @retval zero success
394 * @retval non-zero a memory allocation was necessary but failed
385 * @see cxPropertiesFill() 395 * @see cxPropertiesFill()
386 */ 396 */
387 cx_attr_nonnull 397 cx_attr_nonnull
388 cx_attr_access_r(2, 3) 398 cx_attr_access_r(2, 3)
399 cx_attr_export
389 int cxPropertiesFilln( 400 int cxPropertiesFilln(
390 CxProperties *prop, 401 CxProperties *prop,
391 const char *buf, 402 const char *buf,
392 size_t len 403 size_t len
393 ); 404 );
435 * the additional data is appended - inevitably leading to 446 * the additional data is appended - inevitably leading to
436 * an allocation of a new buffer and copying the previous contents. 447 * an allocation of a new buffer and copying the previous contents.
437 * 448 *
438 * @param prop the properties interface 449 * @param prop the properties interface
439 * @param str the text to fill in 450 * @param str the text to fill in
440 * @return non-zero when a memory allocation was necessary but failed 451 * @retval zero success
452 * @retval non-zero a memory allocation was necessary but failed
441 * @see cxPropertiesFilln() 453 * @see cxPropertiesFilln()
442 */ 454 */
443 #define cxPropertiesFill(prop, str) _Generic((str), \ 455 #define cxPropertiesFill(prop, str) _Generic((str), \
444 cxstring: cx_properties_fill_cxstr, \ 456 cxstring: cx_properties_fill_cxstr, \
445 cxmutstr: cx_properties_fill_mutstr, \ 457 cxmutstr: cx_properties_fill_mutstr, \
488 * @param prop the properties interface 500 * @param prop the properties interface
489 * @param buf a pointer to stack memory 501 * @param buf a pointer to stack memory
490 * @param capacity the capacity of the stack memory 502 * @param capacity the capacity of the stack memory
491 */ 503 */
492 cx_attr_nonnull 504 cx_attr_nonnull
505 cx_attr_export
493 void cxPropertiesUseStack( 506 void cxPropertiesUseStack(
494 CxProperties *prop, 507 CxProperties *prop,
495 char *buf, 508 char *buf,
496 size_t capacity 509 size_t capacity
497 ); 510 );
503 * If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA is returned. 516 * If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA is returned.
504 * 517 *
505 * When an incomplete line is encountered, #CX_PROPERTIES_INCOMPLETE_DATA is 518 * When an incomplete line is encountered, #CX_PROPERTIES_INCOMPLETE_DATA is
506 * returned, and you can add more data with #cxPropertiesFill(). 519 * returned, and you can add more data with #cxPropertiesFill().
507 * 520 *
508 * \remark The incomplete line will be stored in an internal buffer, which is 521 * @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, 522 * allocated on the heap, by default. If you want to avoid allocations,
510 * you can specify sufficient space with cxPropertiesUseStack() after 523 * you can specify sufficient space with cxPropertiesUseStack() after
511 * initialization with cxPropertiesInit(). 524 * initialization with cxPropertiesInit().
512 * 525 *
513 * \attention The returned strings will point into a buffer that might not be 526 * @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 527 * available later. It is strongly recommended to copy the strings for further
515 * use. 528 * use.
516 * 529 *
517 * @param prop the properties interface 530 * @param prop the properties interface
518 * @param key a pointer to the cxstring that shall contain the property name 531 * @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 532 * @param value a pointer to the cxstring that shall contain the property value
520 * @return the status code as defined above 533 * @retval CX_PROPERTIES_NO_ERROR (zero) a key/value pair was found
521 * @see cxPropertiesFill() 534 * @retval CX_PROPERTIES_NO_DATA there is no (more) data in the input buffer
535 * @retval CX_PROPERTIES_INCOMPLETE_DATA the data in the input buffer is incomplete
536 * (fill more data and try again)
537 * @retval CX_PROPERTIES_NULL_INPUT the input buffer was never filled
538 * @retval CX_PROPERTIES_INVALID_EMPTY_KEY the properties data contains an illegal empty key
539 * @retval CX_PROPERTIES_INVALID_MISSING_DELIMITER the properties data contains a line without delimiter
540 * @retval CX_PROPERTIES_BUFFER_ALLOC_FAILED an internal allocation was necessary but failed
522 */ 541 */
523 cx_attr_nonnull 542 cx_attr_nonnull
524 cx_attr_nodiscard 543 cx_attr_nodiscard
544 cx_attr_export
525 CxPropertiesStatus cxPropertiesNext( 545 CxPropertiesStatus cxPropertiesNext(
526 CxProperties *prop, 546 CxProperties *prop,
527 cxstring *key, 547 cxstring *key,
528 cxstring *value 548 cxstring *value
529 ); 549 );
532 * Creates a properties sink for an UCX map. 552 * Creates a properties sink for an UCX map.
533 * 553 *
534 * The values stored in the map will be pointers to strings allocated 554 * The values stored in the map will be pointers to strings allocated
535 * by #cx_strdup_a(). 555 * by #cx_strdup_a().
536 * The default stdlib allocator will be used, unless you specify a custom 556 * The default stdlib allocator will be used, unless you specify a custom
537 * allocator in the optional \c data of the sink. 557 * allocator in the optional @c data of the sink.
538 * 558 *
539 * @param map the map that shall consume the k/v-pairs. 559 * @param map the map that shall consume the k/v-pairs.
540 * @return the sink 560 * @return the sink
541 * @see cxPropertiesLoad() 561 * @see cxPropertiesLoad()
542 */ 562 */
543 cx_attr_nonnull 563 cx_attr_nonnull
544 cx_attr_nodiscard 564 cx_attr_nodiscard
565 cx_attr_export
545 CxPropertiesSink cxPropertiesMapSink(CxMap *map); 566 CxPropertiesSink cxPropertiesMapSink(CxMap *map);
546 567
547 /** 568 /**
548 * Creates a properties source based on an UCX string. 569 * Creates a properties source based on an UCX string.
549 * 570 *
550 * @param str the string 571 * @param str the string
551 * @return the properties source 572 * @return the properties source
552 * @see cxPropertiesLoad() 573 * @see cxPropertiesLoad()
553 */ 574 */
554 cx_attr_nodiscard 575 cx_attr_nodiscard
576 cx_attr_export
555 CxPropertiesSource cxPropertiesStringSource(cxstring str); 577 CxPropertiesSource cxPropertiesStringSource(cxstring str);
556 578
557 /** 579 /**
558 * Creates a properties source based on C string with the specified length. 580 * Creates a properties source based on C string with the specified length.
559 * 581 *
563 * @see cxPropertiesLoad() 585 * @see cxPropertiesLoad()
564 */ 586 */
565 cx_attr_nonnull 587 cx_attr_nonnull
566 cx_attr_nodiscard 588 cx_attr_nodiscard
567 cx_attr_access_r(1, 2) 589 cx_attr_access_r(1, 2)
590 cx_attr_export
568 CxPropertiesSource cxPropertiesCstrnSource(const char *str, size_t len); 591 CxPropertiesSource cxPropertiesCstrnSource(const char *str, size_t len);
569 592
570 /** 593 /**
571 * Creates a properties source based on a C string. 594 * Creates a properties source based on a C string.
572 * 595 *
578 * @see cxPropertiesLoad() 601 * @see cxPropertiesLoad()
579 */ 602 */
580 cx_attr_nonnull 603 cx_attr_nonnull
581 cx_attr_nodiscard 604 cx_attr_nodiscard
582 cx_attr_cstr_arg(1) 605 cx_attr_cstr_arg(1)
606 cx_attr_export
583 CxPropertiesSource cxPropertiesCstrSource(const char *str); 607 CxPropertiesSource cxPropertiesCstrSource(const char *str);
584 608
585 /** 609 /**
586 * Creates a properties source based on an FILE. 610 * Creates a properties source based on an FILE.
587 * 611 *
592 * @see cxPropertiesLoad() 616 * @see cxPropertiesLoad()
593 */ 617 */
594 cx_attr_nonnull 618 cx_attr_nonnull
595 cx_attr_nodiscard 619 cx_attr_nodiscard
596 cx_attr_access_r(1) 620 cx_attr_access_r(1)
621 cx_attr_export
597 CxPropertiesSource cxPropertiesFileSource(FILE *file, size_t chunk_size); 622 CxPropertiesSource cxPropertiesFileSource(FILE *file, size_t chunk_size);
598 623
599 624
600 /** 625 /**
601 * Loads properties data from a source and transfers it to a sink. 626 * Loads properties data from a source and transfers it to a sink.
603 * This function tries to read as much data from the source as possible. 628 * This function tries to read as much data from the source as possible.
604 * When the source was completely consumed and at least on k/v-pair was found, 629 * When the source was completely consumed and at least on k/v-pair was found,
605 * the return value will be #CX_PROPERTIES_NO_ERROR. 630 * the return value will be #CX_PROPERTIES_NO_ERROR.
606 * When the source was consumed but no k/v-pairs were found, the return value 631 * When the source was consumed but no k/v-pairs were found, the return value
607 * will be #CX_PROPERTIES_NO_DATA. 632 * will be #CX_PROPERTIES_NO_DATA.
633 * In case the source data ends unexpectedly, the #CX_PROPERTIES_INCOMPLETE_DATA
634 * is returned. In that case you should call this function again with the same
635 * sink and either an updated source or the same source if the source is able to
636 * yield the missing data.
637 *
608 * The other result codes apply, according to their description. 638 * The other result codes apply, according to their description.
609 * 639 *
610 * @param prop the properties interface 640 * @param prop the properties interface
611 * @param sink the sink 641 * @param sink the sink
612 * @param source the source 642 * @param source the source
613 * @return the status of the last operation 643 * @retval CX_PROPERTIES_NO_ERROR (zero) a key/value pair was found
614 */ 644 * @retval CX_PROPERTIES_READ_INIT_FAILED initializing the source failed
615 cx_attr_nonnull 645 * @retval CX_PROPERTIES_READ_FAILED reading from the source failed
646 * @retval CX_PROPERTIES_SINK_FAILED sinking the properties into the sink failed
647 * @retval CX_PROPERTIES_NO_DATA the source did not provide any key/value pairs
648 * @retval CX_PROPERTIES_INCOMPLETE_DATA the source did not provide enough data
649 * @retval CX_PROPERTIES_INVALID_EMPTY_KEY the properties data contains an illegal empty key
650 * @retval CX_PROPERTIES_INVALID_MISSING_DELIMITER the properties data contains a line without delimiter
651 * @retval CX_PROPERTIES_BUFFER_ALLOC_FAILED an internal allocation was necessary but failed
652 */
653 cx_attr_nonnull
654 cx_attr_export
616 CxPropertiesStatus cxPropertiesLoad( 655 CxPropertiesStatus cxPropertiesLoad(
617 CxProperties *prop, 656 CxProperties *prop,
618 CxPropertiesSink sink, 657 CxPropertiesSink sink,
619 CxPropertiesSource source 658 CxPropertiesSource source
620 ); 659 );

mercurial