/* ---------------------------------------------------------------------------- libconfig - A library for processing structured configuration files Copyright (C) 2005-2010 Mark A Lindner This file is part of libconfig. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, see . ---------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include "ac_config.h" #endif #include "libconfig.h" #include "grammar.h" #include "scanner.h" #include "scanctx.h" #include "parsectx.h" #include "wincompat.h" #include #ifdef HAVE_XLOCALE_H #include #endif #include #include #include #define PATH_TOKENS ":./" #define CHUNK_SIZE 16 #define FLOAT_PRECISION 10 #define _new(T) (T *)calloc(sizeof(T), 1) /* zeroed */ #define _delete(P) free((void *)(P)) /* ------------------------------------------------------------------------- */ #ifndef LIBCONFIG_STATIC #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { return(TRUE); } #endif /* WIN32 */ #endif /* LIBCONFIG_STATIC */ /* ------------------------------------------------------------------------- */ static const char *__io_error = "file I/O error"; static void __config_list_destroy(config_list_t *list); static void __config_write_setting(const config_setting_t *setting, FILE *stream, int depth, unsigned short tab_width); extern int libconfig_yyparse(void *scanner, struct parse_context *ctx, struct scan_context *scan_ctx); extern int libconfig_yylex_init_extra(struct scan_context *scan_ctx, yyscan_t *scanner); /* ------------------------------------------------------------------------- */ static void __config_locale_override(void) { #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \ && ! defined(__MINGW32__) _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); setlocale(LC_NUMERIC, "C"); #elif defined(__APPLE__) locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL); uselocale(loc); #elif ((defined HAVE_NEWLOCALE) && (defined HAVE_USELOCALE)) locale_t loc = newlocale(LC_NUMERIC, "C", NULL); uselocale(loc); #else #warning "No way to modify calling thread's locale!" #endif } /* ------------------------------------------------------------------------- */ static void __config_locale_restore(void) { #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \ && ! defined(__MINGW32__) _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); #elif ((defined HAVE_USELOCALE) && (defined HAVE_FREELOCALE)) locale_t loc = uselocale(LC_GLOBAL_LOCALE); freelocale(loc); #else #warning "No way to modify calling thread's locale!" #endif } /* ------------------------------------------------------------------------- */ static int __config_name_compare(const char *a, const char *b) { const char *p, *q; for(p = a, q = b; ; p++, q++) { int pd = ((! *p) || strchr(PATH_TOKENS, *p)); int qd = ((! *q) || strchr(PATH_TOKENS, *q)); if(pd && qd) break; else if(pd) return(-1); else if(qd) return(1); else if(*p < *q) return(-1); else if(*p > *q) return(1); } return(0); } /* ------------------------------------------------------------------------- */ static void __config_indent(FILE *stream, int depth, unsigned short w) { if(w) fprintf(stream, "%*s", (depth - 1) * w, " "); else { int i; for(i = 0; i < (depth - 1); ++i) fputc('\t', stream); } } /* ------------------------------------------------------------------------- */ static void __config_write_value(const config_value_t *value, int type, int format, int depth, unsigned short tab_width, FILE *stream) { char fbuf[64]; switch(type) { /* boolean */ case CONFIG_TYPE_BOOL: fputs(value->ival ? "true" : "false", stream); break; /* int */ case CONFIG_TYPE_INT: switch(format) { case CONFIG_FORMAT_HEX: fprintf(stream, "0x%X", value->ival); break; case CONFIG_FORMAT_DEFAULT: default: fprintf(stream, "%d", value->ival); break; } break; /* 64-bit int */ case CONFIG_TYPE_INT64: switch(format) { case CONFIG_FORMAT_HEX: fprintf(stream, "0x" INT64_HEX_FMT "L", value->llval); break; case CONFIG_FORMAT_DEFAULT: default: fprintf(stream, INT64_FMT "L", value->llval); break; } break; /* float */ case CONFIG_TYPE_FLOAT
/*
 * section and descriptor parser
 *
 * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
 * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

#ifndef _UCSI_MPEG4_VIDEO_DESCRIPTOR
#define _UCSI_MPEG4_VIDEO_DESCRIPTOR 1

#ifdef __cplusplus
extern "C"
{
#endif

#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>

/**
 * mpeg4_video_descriptor structure.
 */
struct mpeg4_video_descriptor {
	struct descriptor d;

	uint8_t mpeg4_visual_profile_and_level;
} __ucsi_packed;

/**
 * Process an mpeg4_video_descriptor structure.
 *
 * @param d Pointer to generic descriptor structure.
 * @return Pointer to mpeg4_video_descriptor structure, or NULL on error.
 */
static inline struct mpeg4_video_descriptor*
	mpeg4_video_descriptor_codec(struct descriptor* d)
{
	if (d->len != (sizeof(struct mpeg4_video_descriptor) - 2))
		return NULL;

	return (struct mpeg4_video_descriptor*) d;
}

#ifdef __cplusplus
}
#endif

#endif
tic void __config_write_setting(const config_setting_t *setting, FILE *stream, int depth, unsigned short tab_width) { if(depth > 1) __config_indent(stream, depth, tab_width); if(setting->name) { fputs(setting->name, stream); fprintf(stream, " %c ", (setting->type == CONFIG_TYPE_GROUP ? ':' : '=')); } __config_write_value(&(setting->value), setting->type, config_setting_get_format(setting), depth, tab_width, stream); if(depth > 0) { fputc(';', stream); fputc('\n', stream); } } /* ------------------------------------------------------------------------- */ void config_write(const config_t *config, FILE *stream) { __config_locale_override(); __config_write_setting(config->root, stream, 0, config->tab_width); __config_locale_restore(); } /* ------------------------------------------------------------------------- */ int config_read_file(config_t *config, const char *filename) { int ret; FILE *stream = fopen(filename, "rt"); if(! stream) { config->error_text = __io_error; config->error_type = CONFIG_ERR_FILE_IO; return(CONFIG_FALSE); } ret = __config_read(config, stream, filename, NULL); fclose(stream); return(ret); } /* ------------------------------------------------------------------------- */ int config_write_file(config_t *config, const char *filename) { FILE *f = fopen(filename, "wt"); if(! f) { config->error_text = __io_error; config->error_type = CONFIG_ERR_FILE_IO; return(CONFIG_FALSE); } config_write(config, f); fclose(f); config->error_type = CONFIG_ERR_NONE; return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ void config_destroy(config_t *config) { unsigned int count = config->num_filenames; const char **f; __config_setting_destroy(config->root); for(f = config->filenames; count > 0; ++f, --count) _delete(*f); _delete(config->filenames); _delete(config->include_dir); memset((void *)config, 0, sizeof(config_t)); } /* ------------------------------------------------------------------------- */ void config_init(config_t *config) { memset((void *)config, 0, sizeof(config_t)); config->root = _new(config_setting_t); config->root->type = CONFIG_TYPE_GROUP; config->root->config = config; config->tab_width = 2; } /* ------------------------------------------------------------------------- */ void config_set_auto_convert(config_t *config, int flag) { if(flag) config->flags |= CONFIG_OPTION_AUTOCONVERT; else config->flags &= ~CONFIG_OPTION_AUTOCONVERT; } /* ------------------------------------------------------------------------- */ int config_get_auto_convert(const config_t *config) { return((config->flags & CONFIG_OPTION_AUTOCONVERT) != 0); } /* ------------------------------------------------------------------------- */ static config_setting_t *config_setting_create(config_setting_t *parent, const char *name, int type) { config_setting_t *setting; config_list_t *list; if((parent->type != CONFIG_TYPE_GROUP) && (parent->type != CONFIG_TYPE_ARRAY) && (parent->type != CONFIG_TYPE_LIST)) return(NULL); setting = _new(config_setting_t); setting->parent = parent; setting->name = (name == NULL) ? NULL : strdup(name); setting->type = type; setting->config = parent->config; setting->hook = NULL; setting->line = 0; list = parent->value.list; if(! list) list = parent->value.list = _new(config_list_t); __config_list_add(list, setting); return(setting); } /* ------------------------------------------------------------------------- */ static int __config_setting_get_int(const config_setting_t *setting, int *value) { switch(setting->type) { case CONFIG_TYPE_INT: *value = setting->value.ival; return(CONFIG_TRUE); case CONFIG_TYPE_INT64: if((setting->value.llval > INT32_MAX) || (setting->value.llval < INT32_MIN)) *value = 0; else *value = (int)(setting->value.llval); return(CONFIG_TRUE); case CONFIG_TYPE_FLOAT: if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0) { *value = (int)(setting->value.fval); return(CONFIG_TRUE); } else { /* fall through */ } default: return(CONFIG_FALSE); } } /* ------------------------------------------------------------------------- */ int config_setting_get_int(const config_setting_t *setting) { int value = 0; __config_setting_get_int(setting, &value); return(value); } /* ------------------------------------------------------------------------- */ static int __config_setting_get_int64(const config_setting_t *setting, long long *value) { switch(setting->type) { case CONFIG_TYPE_INT64: *value = setting->value.llval; return(CONFIG_TRUE); case CONFIG_TYPE_INT: *value = (long long)(setting->value.ival); return(CONFIG_TRUE); case CONFIG_TYPE_FLOAT: if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0) { *value = (long long)(setting->value.fval); return(CONFIG_TRUE); } else { /* fall through */ } default: return(CONFIG_FALSE); } } /* ------------------------------------------------------------------------- */ long long config_setting_get_int64(const config_setting_t *setting) { long long value = 0; __config_setting_get_int64(setting, &value); return(value); } /* ------------------------------------------------------------------------- */ int config_setting_lookup_int(const config_setting_t *setting, const char *name, int *value) { config_setting_t *member = config_setting_get_member(setting, name); if(! member) return(CONFIG_FALSE); return(__config_setting_get_int(member, value)); } /* ------------------------------------------------------------------------- */ int config_setting_lookup_int64(const config_setting_t *setting, const char *name, long long *value) { config_setting_t *member = config_setting_get_member(setting, name); if(! member) return(CONFIG_FALSE); return(__config_setting_get_int64(member, value)); } /* ------------------------------------------------------------------------- */ static int __config_setting_get_float(const config_setting_t *setting, double *value) { switch(setting->type) { case CONFIG_TYPE_FLOAT: *value = setting->value.fval; return(CONFIG_TRUE); case CONFIG_TYPE_INT: if(config_get_auto_convert(setting->config)) { *value = (double)(setting->value.ival); return(CONFIG_TRUE); } else return(CONFIG_FALSE); case CONFIG_TYPE_INT64: if(config_get_auto_convert(setting->config)) { *value = (double)(setting->value.llval); return(CONFIG_TRUE); } else { /* fall through */ } default: return(CONFIG_FALSE); } } /* ------------------------------------------------------------------------- */ double config_setting_get_float(const config_setting_t *setting) { double value = 0.0; __config_setting_get_float(setting, &value); return(value); } /* ------------------------------------------------------------------------- */ int config_setting_lookup_float(const config_setting_t *setting, const char *name, double *value) { config_setting_t *member = config_setting_get_member(setting, name); if(! member) return(CONFIG_FALSE); return(__config_setting_get_float(member, value)); } /* ------------------------------------------------------------------------- */ int config_setting_lookup_string(const config_setting_t *setting, const char *name, const char **value) { config_setting_t *member = config_setting_get_member(setting, name); if(! member) return(CONFIG_FALSE); if(config_setting_type(member) != CONFIG_TYPE_STRING) return(CONFIG_FALSE); *value = config_setting_get_string(member); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_setting_lookup_bool(const config_setting_t *setting, const char *name, int *value) { config_setting_t *member = config_setting_get_member(setting, name); if(! member) return(CONFIG_FALSE); if(config_setting_type(member) != CONFIG_TYPE_BOOL) return(CONFIG_FALSE); *value = config_setting_get_bool(member); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_setting_set_int(config_setting_t *setting, int value) { switch(setting->type) { case CONFIG_TYPE_NONE: setting->type = CONFIG_TYPE_INT; /* fall through */ case CONFIG_TYPE_INT: setting->value.ival = value; return(CONFIG_TRUE); case CONFIG_TYPE_FLOAT: if(config_get_auto_convert(setting->config)) { setting->value.fval = (float)value; return(CONFIG_TRUE); } else return(CONFIG_FALSE); default: return(CONFIG_FALSE); } } /* ------------------------------------------------------------------------- */ int config_setting_set_int64(config_setting_t *setting, long long value) { switch(setting->type) { case CONFIG_TYPE_NONE: setting->type = CONFIG_TYPE_INT64; /* fall through */ case CONFIG_TYPE_INT64: setting->value.llval = value; return(CONFIG_TRUE); case CONFIG_TYPE_INT: if((value > INT32_MAX) || (value < INT32_MIN)) setting->value.ival = 0; else setting->value.ival = (int)value; return(CONFIG_TRUE); case CONFIG_TYPE_FLOAT: if(config_get_auto_convert(setting->config)) { setting->value.fval = (float)value; return(CONFIG_TRUE); } else return(CONFIG_FALSE); default: return(CONFIG_FALSE); } } /* ------------------------------------------------------------------------- */ int config_setting_set_float(config_setting_t *setting, double value) { switch(setting->type) { case CONFIG_TYPE_NONE: setting->type = CONFIG_TYPE_FLOAT; /* fall through */ case CONFIG_TYPE_FLOAT: setting->value.fval = value; return(CONFIG_TRUE); case CONFIG_TYPE_INT: if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0) { setting->value.ival = (int)value; return(CONFIG_TRUE); } else return(CONFIG_FALSE); case CONFIG_TYPE_INT64: if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0) { setting->value.llval = (long long)value; return(CONFIG_TRUE); } else return(CONFIG_FALSE); default: return(CONFIG_FALSE); } } /* ------------------------------------------------------------------------- */ int config_setting_get_bool(const config_setting_t *setting) { return((setting->type == CONFIG_TYPE_BOOL) ? setting->value.ival : 0); } /* ------------------------------------------------------------------------- */ int config_setting_set_bool(config_setting_t *setting, int value) { if(setting->type == CONFIG_TYPE_NONE) setting->type = CONFIG_TYPE_BOOL; else if(setting->type != CONFIG_TYPE_BOOL) return(CONFIG_FALSE); setting->value.ival = value; return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ const char *config_setting_get_string(const config_setting_t *setting) { return((setting->type == CONFIG_TYPE_STRING) ? setting->value.sval : NULL); } /* ------------------------------------------------------------------------- */ int config_setting_set_string(config_setting_t *setting, const char *value) { if(setting->type == CONFIG_TYPE_NONE) setting->type = CONFIG_TYPE_STRING; else if(setting->type != CONFIG_TYPE_STRING) return(CONFIG_FALSE); if(setting->value.sval) _delete(setting->value.sval); setting->value.sval = (value == NULL) ? NULL : strdup(value); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_setting_set_format(config_setting_t *setting, short format) { if(((setting->type != CONFIG_TYPE_INT) && (setting->type != CONFIG_TYPE_INT64)) || ((format != CONFIG_FORMAT_DEFAULT) && (format != CONFIG_FORMAT_HEX))) return(CONFIG_FALSE); setting->format = format; return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ short config_setting_get_format(const config_setting_t *setting) { return(setting->format != 0 ? setting->format : setting->config->default_format); } /* ------------------------------------------------------------------------- */ config_setting_t *config_lookup_from(config_setting_t *setting, const char *path) { const char *p = path; config_setting_t *found; for(;;) { while(*p && strchr(PATH_TOKENS, *p)) p++; if(! *p) break; if(*p == '[') found = config_setting_get_elem(setting, atoi(++p)); else found = config_setting_get_member(setting, p); if(! found) break; setting = found; while(! strchr(PATH_TOKENS, *p)) p++; } return(*p ? NULL : setting); } /* ------------------------------------------------------------------------- */ config_setting_t *config_lookup(const config_t *config, const char *path) { return(config_lookup_from(config->root, path)); } /* ------------------------------------------------------------------------- */ int config_lookup_string(const config_t *config, const char *path, const char **value) { const config_setting_t *s = config_lookup(config, path); if(! s) return(CONFIG_FALSE); if(config_setting_type(s) != CONFIG_TYPE_STRING) return(CONFIG_FALSE); *value = config_setting_get_string(s); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_lookup_int(const config_t *config, const char *path, int *value) { const config_setting_t *s = config_lookup(config, path); if(! s) return(CONFIG_FALSE); return(__config_setting_get_int(s, value)); } /* ------------------------------------------------------------------------- */ int config_lookup_int64(const config_t *config, const char *path, long long *value) { const config_setting_t *s = config_lookup(config, path); if(! s) return(CONFIG_FALSE); return(__config_setting_get_int64(s, value)); } /* ------------------------------------------------------------------------- */ int config_lookup_float(const config_t *config, const char *path, double *value) { const config_setting_t *s = config_lookup(config, path); if(! s) return(CONFIG_FALSE); return(__config_setting_get_float(s, value)); } /* ------------------------------------------------------------------------- */ int config_lookup_bool(const config_t *config, const char *path, int *value) { const config_setting_t *s = config_lookup(config, path); if(! s) return(CONFIG_FALSE); if(config_setting_type(s) != CONFIG_TYPE_BOOL) return(CONFIG_FALSE); *value = config_setting_get_bool(s); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_setting_get_int_elem(const config_setting_t *vector, int idx) { const config_setting_t *element = config_setting_get_elem(vector, idx); return(element ? config_setting_get_int(element) : 0); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_set_int_elem(config_setting_t *vector, int idx, int value) { config_setting_t *element = NULL; if((vector->type != CONFIG_TYPE_ARRAY) && (vector->type != CONFIG_TYPE_LIST)) return(NULL); if(idx < 0) { if(! __config_vector_checktype(vector, CONFIG_TYPE_INT)) return(NULL); element = config_setting_create(vector, NULL, CONFIG_TYPE_INT); } else { element = config_setting_get_elem(vector, idx); if(! element) return(NULL); } if(! config_setting_set_int(element, value)) return(NULL); return(element); } /* ------------------------------------------------------------------------- */ long long config_setting_get_int64_elem(const config_setting_t *vector, int idx) { const config_setting_t *element = config_setting_get_elem(vector, idx); return(element ? config_setting_get_int64(element) : 0); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_set_int64_elem(config_setting_t *vector, int idx, long long value) { config_setting_t *element = NULL; if((vector->type != CONFIG_TYPE_ARRAY) && (vector->type != CONFIG_TYPE_LIST)) return(NULL); if(idx < 0) { if(! __config_vector_checktype(vector, CONFIG_TYPE_INT64)) return(NULL); element = config_setting_create(vector, NULL, CONFIG_TYPE_INT64); } else { element = config_setting_get_elem(vector, idx); if(! element) return(NULL); } if(! config_setting_set_int64(element, value)) return(NULL); return(element); } /* ------------------------------------------------------------------------- */ double config_setting_get_float_elem(const config_setting_t *vector, int idx) { config_setting_t *element = config_setting_get_elem(vector, idx); return(element ? config_setting_get_float(element) : 0.0); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_set_float_elem(config_setting_t *vector, int idx, double value) { config_setting_t *element = NULL; if((vector->type != CONFIG_TYPE_ARRAY) && (vector->type != CONFIG_TYPE_LIST)) return(NULL); if(idx < 0) { if(! __config_vector_checktype(vector, CONFIG_TYPE_FLOAT)) return(NULL); element = config_setting_create(vector, NULL, CONFIG_TYPE_FLOAT); } else element = config_setting_get_elem(vector, idx); if(! element) return(NULL); if(! config_setting_set_float(element, value)) return(NULL); return(element); } /* ------------------------------------------------------------------------- */ int config_setting_get_bool_elem(const config_setting_t *vector, int idx) { config_setting_t *element = config_setting_get_elem(vector, idx); if(! element) return(CONFIG_FALSE); if(element->type != CONFIG_TYPE_BOOL) return(CONFIG_FALSE); return(element->value.ival); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_set_bool_elem(config_setting_t *vector, int idx, int value) { config_setting_t *element = NULL; if((vector->type != CONFIG_TYPE_ARRAY) && (vector->type != CONFIG_TYPE_LIST)) return(NULL); if(idx < 0) { if(! __config_vector_checktype(vector, CONFIG_TYPE_BOOL)) return(NULL); element = config_setting_create(vector, NULL, CONFIG_TYPE_BOOL); } else element = config_setting_get_elem(vector, idx); if(! element) return(NULL); if(! config_setting_set_bool(element, value)) return(NULL); return(element); } /* ------------------------------------------------------------------------- */ const char *config_setting_get_string_elem(const config_setting_t *vector, int idx) { config_setting_t *element = config_setting_get_elem(vector, idx); if(! element) return(NULL); if(element->type != CONFIG_TYPE_STRING) return(NULL); return(element->value.sval); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_set_string_elem(config_setting_t *vector, int idx, const char *value) { config_setting_t *element = NULL; if((vector->type != CONFIG_TYPE_ARRAY) && (vector->type != CONFIG_TYPE_LIST)) return(NULL); if(idx < 0) { if(! __config_vector_checktype(vector, CONFIG_TYPE_STRING)) return(NULL); element = config_setting_create(vector, NULL, CONFIG_TYPE_STRING); } else element = config_setting_get_elem(vector, idx); if(! element) return(NULL); if(! config_setting_set_string(element, value)) return(NULL); return(element); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_get_elem(const config_setting_t *vector, unsigned int idx) { config_list_t *list = vector->value.list; if(((vector->type != CONFIG_TYPE_ARRAY) && (vector->type != CONFIG_TYPE_LIST) && (vector->type != CONFIG_TYPE_GROUP)) || ! list) return(NULL); if(idx >= list->length) return(NULL); return(list->elements[idx]); } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_get_member(const config_setting_t *setting, const char *name) { if(setting->type != CONFIG_TYPE_GROUP) return(NULL); return(__config_list_search(setting->value.list, name, NULL)); } /* ------------------------------------------------------------------------- */ void config_set_destructor(config_t *config, void (*destructor)(void *)) { config->destructor = destructor; } /* ------------------------------------------------------------------------- */ void config_set_include_dir(config_t *config, const char *include_dir) { _delete(config->include_dir); config->include_dir = strdup(include_dir); } /* ------------------------------------------------------------------------- */ int config_setting_length(const config_setting_t *setting) { if((setting->type != CONFIG_TYPE_GROUP) && (setting->type != CONFIG_TYPE_ARRAY) && (setting->type != CONFIG_TYPE_LIST)) return(0); if(! setting->value.list) return(0); return(setting->value.list->length); } /* ------------------------------------------------------------------------- */ void config_setting_set_hook(config_setting_t *setting, void *hook) { setting->hook = hook; } /* ------------------------------------------------------------------------- */ config_setting_t *config_setting_add(config_setting_t *parent, const char *name, int type) { if((type < CONFIG_TYPE_NONE) || (type > CONFIG_TYPE_LIST)) return(NULL); if(! parent) return(NULL); if((parent->type == CONFIG_TYPE_ARRAY) || (parent->type == CONFIG_TYPE_LIST)) name = NULL; if(name) { if(! __config_validate_name(name)) return(NULL); } if(config_setting_get_member(parent, name) != NULL) return(NULL); /* already exists */ return(config_setting_create(parent, name, type)); } /* ------------------------------------------------------------------------- */ int config_setting_remove(config_setting_t *parent, const char *name) { unsigned int idx; config_setting_t *setting; if(! parent) return(CONFIG_FALSE); if(parent->type != CONFIG_TYPE_GROUP) return(CONFIG_FALSE); if(! (setting = __config_list_search(parent->value.list, name, &idx))) return(CONFIG_FALSE); __config_list_remove(parent->value.list, idx); __config_setting_destroy(setting); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_setting_remove_elem(config_setting_t *parent, unsigned int idx) { config_list_t *list; config_setting_t *removed = NULL; if(! parent) return(CONFIG_FALSE); list = parent->value.list; if(((parent->type != CONFIG_TYPE_ARRAY) && (parent->type != CONFIG_TYPE_LIST) && (parent->type != CONFIG_TYPE_GROUP)) || ! list) return(CONFIG_FALSE); if(idx >= list->length) return(CONFIG_FALSE); removed = __config_list_remove(list, idx); __config_setting_destroy(removed); return(CONFIG_TRUE); } /* ------------------------------------------------------------------------- */ int config_setting_index(const config_setting_t *setting) { config_setting_t **found = NULL; config_list_t *list; int i; if(! setting->parent) return(-1); list = setting->parent->value.list; for(i = 0, found = list->elements; i < (int)list->length; ++i, ++found) { if(*found == setting) return(i); } return(-1); } /* ------------------------------------------------------------------------- */ /* eof */