*** /dev/null Sat Nov 23 01:26:37 2024
--- - Sat Nov 23 01:26:51 2024
***************
*** 0 ****
--- 1,248 ----
+ /*
+ ** OSSP cfg - Configuration Parsing
+ ** Copyright (c) 1999-2002 Ralf S. Engelschall <rse@engelschall.com>
+ ** Copyright (c) 1999-2002 The OSSP Project (http://www.ossp.org/)
+ ** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/)
+ **
+ ** This file is part of OSSP cfg, a configuration parsing
+ ** library which can be found at http://www.ossp.org/pkg/lib/cfg/.
+ **
+ ** Permission to use, copy, modify, and distribute this software for
+ ** any purpose with or without fee is hereby granted, provided that
+ ** the above copyright notice and this permission notice appear in all
+ ** copies.
+ **
+ ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ** 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 CONTRCFG, 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.
+ **
+ ** cfg_data.c: configuration annotational data
+ */
+
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+
+ #include "cfg.h"
+ #include "cfg_data.h"
+
+ cfg_rc_t cfg_data_create(cfg_data_t **data)
+ {
+ cfg_rc_t rc;
+
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ if ((*data = (cfg_data_t *)malloc(sizeof(cfg_data_t))) == NULL)
+ return CFG_ERR_SYS;
+ if ((rc = cfg_data_init(*data)) != CFG_OK) {
+ free(*data);
+ return rc;
+ }
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_init(cfg_data_t *data)
+ {
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ data->type = CFG_DATA_TYPE_INT;
+ data->value.i = 0;
+ data->ctrl = cfg_data_ctrl_default;
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_kill(cfg_data_t *data)
+ {
+ cfg_rc_t rc;
+
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ if (data->ctrl != NULL)
+ if ((rc = data->ctrl(data, CFG_DATA_CTRL_DESTROY)) != CFG_OK)
+ return rc;
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_destroy(cfg_data_t *data)
+ {
+ cfg_rc_t rc;
+
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ if ((rc = cfg_data_kill(data)) != CFG_OK)
+ return rc;
+ free(data);
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_clone(cfg_data_t *data, cfg_data_t **clone)
+ {
+ cfg_rc_t rc;
+
+ if (data == NULL || clone == NULL)
+ return CFG_ERR_ARG;
+ if ((*clone = (cfg_data_t *)malloc(sizeof(cfg_data_t))) == NULL)
+ return CFG_ERR_SYS;
+ (*clone)->type = data->type;
+ (*clone)->ctrl = data->ctrl;
+ if ((rc = data->ctrl(data, CFG_DATA_CTRL_CLONE, *clone)) != CFG_OK) {
+ free(*clone);
+ return rc;
+ }
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_ctrl_default(cfg_data_t *data, cfg_data_ctrl_t ctrl, ...)
+ {
+ cfg_data_t *data2;
+ va_list ap;
+
+ va_start(ap, ctrl);
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ if (ctrl == CFG_DATA_CTRL_CLONE) {
+ if ((data2 = (cfg_data_t *)va_arg(ap, void *)) == NULL)
+ return CFG_ERR_ARG;
+ if (data->type == CFG_DATA_TYPE_STR) {
+ if (data->value.s != NULL)
+ data2->value.s = strdup(data->value.s);
+ else
+ data2->value.s = NULL;
+ }
+ else {
+ memcpy((void *)&(data2->value),
+ (void *)&(data->value), sizeof(cfg_data_value_t));
+ }
+ }
+ else if (ctrl == CFG_DATA_CTRL_DESTROY) {
+ if (data->type == CFG_DATA_TYPE_STR)
+ if (data->value.s != NULL)
+ free(data->value.s);
+ }
+ va_end(ap);
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_set(cfg_data_t *data, cfg_data_id_t id, ...)
+ {
+ va_list ap;
+
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ va_start(ap, id);
+ switch (id) {
+ case CFG_DATA_TYPE: {
+ cfg_data_type_t t = (cfg_data_type_t)va_arg(ap, int);
+ if (!( t == CFG_DATA_TYPE_PTR
+ || t == CFG_DATA_TYPE_STR
+ || t == CFG_DATA_TYPE_INT
+ || t == CFG_DATA_TYPE_FLT))
+ return CFG_ERR_ARG;
+ data->type = t;
+ break;
+ }
+ case CFG_DATA_VALUE: {
+ switch (data->type) {
+ case CFG_DATA_TYPE_PTR: {
+ data->value.p = (void *)va_arg(ap, void *);
+ break;
+ }
+ case CFG_DATA_TYPE_STR: {
+ char *s = (char *)va_arg(ap, void *);
+ if (data->value.s != NULL)
+ free(data->value.s);
+ if (s != NULL)
+ s = strdup(s);
+ data->value.s = s;
+ break;
+ }
+ case CFG_DATA_TYPE_INT: {
+ data->value.i = (int)va_arg(ap, int);
+ break;
+ }
+ case CFG_DATA_TYPE_FLT: {
+ data->value.f = (double)va_arg(ap, double);
+ break;
+ }
+ }
+ break;
+ }
+ case CFG_DATA_CTRL: {
+ cfg_data_ctrl_cb_t ctrl = (cfg_data_ctrl_cb_t)va_arg(ap, void (*)(void));
+ data->ctrl = ctrl;
+ break;
+ }
+ }
+ va_end(ap);
+ return CFG_OK;
+ }
+
+ cfg_rc_t cfg_data_get(cfg_data_t *data, cfg_data_id_t id, ...)
+ {
+ va_list ap;
+
+ if (data == NULL)
+ return CFG_ERR_ARG;
+ va_start(ap, id);
+ switch (id) {
+ case CFG_DATA_TYPE: {
+ cfg_data_type_t *pt = (cfg_data_type_t *)va_arg(ap, int *);
+ if (pt == NULL)
+ return CFG_ERR_ARG;
+ *pt = data->type;
+ break;
+ }
+ case CFG_DATA_VALUE: {
+ switch (data->type) {
+ case CFG_DATA_TYPE_PTR: {
+ void **p = (void **)va_arg(ap, void *);
+ if (p == NULL)
+ return CFG_ERR_ARG;
+ *p = data->value.p;
+ break;
+ }
+ case CFG_DATA_TYPE_STR: {
+ char **p = (char **)va_arg(ap, void *);
+ if (p == NULL)
+ return CFG_ERR_ARG;
+ *p = data->value.s;
+ break;
+ }
+ case CFG_DATA_TYPE_INT: {
+ int *p = (int *)va_arg(ap, void *);
+ if (p == NULL)
+ return CFG_ERR_ARG;
+ *p = data->value.i;
+ break;
+ }
+ case CFG_DATA_TYPE_FLT: {
+ double *p = (double *)va_arg(ap, void *);
+ if (p == NULL)
+ return CFG_ERR_ARG;
+ *p = data->value.f;
+ break;
+ }
+ }
+ break;
+ }
+ case CFG_DATA_CTRL: {
+ cfg_data_ctrl_cb_t *pcb = (cfg_data_ctrl_cb_t *)va_arg(ap, void *);
+ if (pcb == NULL)
+ return CFG_ERR_ARG;
+ *pcb = data->ctrl;
+ break;
+ }
+ }
+ va_end(ap);
+ return CFG_OK;
+ }
+
|