Thu, 10 Oct 2024 18:40:27 +0200
add ucx2.1 style interface for a properties parser
relates to #429
/* * 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