Thu, 10 Oct 2024 18:40:27 +0200
add ucx2.1 style interface for a properties parser
relates to #429
src/Makefile | file | annotate | diff | comparison | revisions | |
src/cx/properties.h | file | annotate | diff | comparison | revisions | |
src/properties.c | file | annotate | diff | comparison | revisions |
--- a/src/Makefile Tue Oct 08 19:52:09 2024 +0200 +++ b/src/Makefile Thu Oct 10 18:40:27 2024 +0200 @@ -25,7 +25,7 @@ SRC = allocator.c array_list.c buffer.c compare.c hash_key.c hash_map.c \ iterator.c linked_list.c list.c map.c mempool.c printf.c string.c tree.c \ - utils.c + utils.c properties.c OBJ_EXT=.o OBJ=$(SRC:%.c=$(build_dir)/%$(OBJ_EXT)) @@ -125,6 +125,10 @@ @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< +$(build_dir)/properties$(OBJ_EXT): properties.c cx/properties.h + @echo "Compiling $<" + $(CC) -o $@ $(CFLAGS) -c $< + $(build_dir)/string$(OBJ_EXT): string.c cx/string.h cx/common.h \ cx/allocator.h cx/utils.h @echo "Compiling $<"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cx/properties.h Thu Oct 10 18:40:27 2024 +0200 @@ -0,0 +1,208 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/** + * \file properties.h + * \brief Interface for parsing data from properties files. + * \author Mike Becker + * \author Olaf Wintermann + * \copyright 2-Clause BSD License + */ + +#ifndef UCX_PROPERTIES +#define UCX_PROPERTIES + +#include "common.h" +#include "string.h" + +struct cx_properties_config_s { + /** + * The key/value delimiter that shall be used. + * This is '=' by default. + */ + char delimiter; + + /** + * The character, when appearing at the end of a line, continues that line. + * This is '\' by default. + */ + char continuation; + + /** + * The first comment character. + * This is '#' by default. + */ + char comment1; + + /** + * The second comment character. + * This is not set by default. + */ + char comment2; + + /** + * The third comment character. + * This is not set by default. + */ + char comment3; +}; + +/** + * Typedef for the properties config. + */ +typedef struct cx_properties_config_s CxPropertiesConfig; + +/** + * Default properties configuration. + */ +extern const CxPropertiesConfig cx_properties_config_default; + +/** + * Status codes for the properties interface. + */ +enum cx_properties_status { + /** + * Everything is fine. + */ + CX_PROPERTIES_NO_ERROR, + /** + * The input buffer does not contain more data. + */ + CX_PROPERTIES_NO_DATA, + /** + * The input ends unexpectedly. + * + * This either happens when the last line does not terminate with a line + * break, or when the input ends with a parsed key but no value. + */ + CX_PROPERTIES_INCOMPLETE_DATA, + /** + * Input buffer is \c NULL. + */ + CX_PROPERTIES_NULL_INPUT, +}; + +/** + * Interface for working with properties data. + */ +struct cx_properties_s { + /** + * The configuration. + */ + CxPropertiesConfig config; + + /** + * The text buffer. + */ + const char *text; + + /** + * Length of the text buffer. + */ + size_t text_len; + + /** + * Position in the text buffer. + */ + size_t text_pos; +}; + +/** + * Typedef for the properties interface. + */ +typedef struct cx_properties_s CxProperties; + + +/** + * Initialize a properties parser. + * + * @param prop the properties interface + * @param config the properties configuration + * @see cxPropertiesInitDefault() + */ + __attribute__((__nonnull__)) +static inline void cxPropertiesInit( + CxProperties *prop, + CxPropertiesConfig config +) { + prop->config = config; + prop->text = NULL; + } + +/** + * Initialize a properties parser with the default configuration. + * + * @param prop the properties interface + * @see cxPropertiesInit() + */ +#define cxPropertiesInitDefault(prop) \ + cxPropertiesInit(prop, cx_properties_config_default) + +/** + * Sets an input buffer. + * + * After calling this function, you can parse the data by calling + * cxPropertiesNext() until the status is #CX_PROPERTIES_NO_DATA. + * + * @param prop the properties interface + * @param buf a pointer to data + * @param len the length of the data + */ +__attribute__((__nonnull__)) +static inline void cxPropertiesInput( + CxProperties *prop, + const void *buf, + size_t len +) { + prop->text = buf; + prop->text_len = len; + prop->text_pos = 0; +} + +/** + * Retrieves the next key/value-pair. + * + * This function returns zero as long as there are key/value-pairs + * found. If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA + * is returned. You may refill the input buffer with cxPropertiesInput(). + * + * When an invalid line is encountered, #CX_PROPERTIES_INVALID_LINE is returned + * and the position of the input buffer will be the start of the affected line. + * + * @param prop the properties interface + * @param name a pointer to the cxstring that shall contain the property name + * @param value a pointer to the cxstring that shall contain the property value + * @return Nonzero, if a key/value-pair was successfully retrieved + * @see ucx_properties_fill() + */ +enum cx_properties_status cxPropertiesNext( + CxProperties *prop, + cxstring *name, + cxstring *value +); + +#endif // UCX_PROPERTIES
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/properties.c Thu Oct 10 18:40:27 2024 +0200 @@ -0,0 +1,37 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cx/properties.h" + +const CxPropertiesConfig cx_properties_config_default = { + '=', + '\\', + '#', + '\0', + '\0' +};