aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJonathan McCrohan <jmccrohan@gmail.com>2011-12-01 22:54:16 +0000
committerJonathan McCrohan <jmccrohan@gmail.com>2011-12-01 22:54:16 +0000
commit58bf1382be0cbcf3f9649286fd2719b789a1595f (patch)
treeb73665275a2d44879a8230c913b1ef21a42e57da /lib
downloadlibconfig-58bf1382be0cbcf3f9649286fd2719b789a1595f.tar.gz
Imported Upstream version 1.3.2upstream/1.3.2
Diffstat (limited to '')
-rw-r--r--libconfig++.pc.in14
-rw-r--r--libconfig++.vcproj229
-rw-r--r--libconfig++_stub.vcproj184
-rw-r--r--libconfig.c1489
-rw-r--r--libconfig.h266
-rw-r--r--libconfig.h++424
-rw-r--r--libconfig.hh23
-rw-r--r--libconfig.pc.in14
-rw-r--r--libconfig.sln38
-rw-r--r--libconfig.spec84
-rw-r--r--libconfig.spec.in84
-rw-r--r--libconfig.vcproj212
-rw-r--r--libconfig_stub.vcproj184
-rw-r--r--libconfigcpp.c++1112
-rw-r--r--libconfigcpp.cc23
15 files changed, 4380 insertions, 0 deletions
diff --git a/libconfig++.pc.in b/libconfig++.pc.in
new file mode 100644
index 0000000..2771cc9
--- /dev/null
+++ b/libconfig++.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libconfig++
+Description: C++ Configuration File Library
+Version: @VERSION@
+URL: http://www.hyperrealm.com/main.php?s=libconfig
+Requires:
+Conflicts:
+Libs: -L${libdir} -lconfig++
+Libs.private: @LIBS@
+Cflags: -I${includedir}
diff --git a/libconfig++.vcproj b/libconfig++.vcproj
new file mode 100644
index 0000000..232849b
--- /dev/null
+++ b/libconfig++.vcproj
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libconfig++"
+ ProjectGUID="{A0C36CE7-D908-4573-8B69-249EEEB7D2BE}"
+ RootNamespace="libconfig_c"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBCONFIG_EXPORTS;YY_NO_UNISTD_H"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="LIBCONFIG_EXPORTS;YY_NO_UNISTD_H;_CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\grammar.c"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfig.c"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfigcpp.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\scanner.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\ac_config.h"
+ >
+ </File>
+ <File
+ RelativePath=".\config.tab.h"
+ >
+ </File>
+ <File
+ RelativePath=".\grammar.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfig.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfig.h++"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfig.hh"
+ >
+ </File>
+ <File
+ RelativePath=".\private.h"
+ >
+ </File>
+ <File
+ RelativePath=".\scanner.h"
+ >
+ </File>
+ <File
+ RelativePath=".\wincompat.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/libconfig++_stub.vcproj b/libconfig++_stub.vcproj
new file mode 100644
index 0000000..c89b53e
--- /dev/null
+++ b/libconfig++_stub.vcproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libconfig++_stub"
+ ProjectGUID="{2A94C9E9-A7C7-4770-A24C-694312ADB850}"
+ RootNamespace="libconfig_stub"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ RuntimeLibrary="3"
+ WarningLevel="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="false"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <ProjectReference
+ ReferencedProjectIdentifier="{A0C36CE7-D908-4573-8B69-249EEEB7D2BE}"
+ RelativePathToProject=".\libconfig++.vcproj"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\samples\c++\stubcpp.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/libconfig.c b/libconfig.c
new file mode 100644
index 0000000..c09921d
--- /dev/null
+++ b/libconfig.c
@@ -0,0 +1,1489 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ Copyright (C) 2005-2009 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
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "ac_config.h"
+#endif
+
+#include "libconfig.h"
+#include "grammar.h"
+#include "scanner.h"
+#include "private.h"
+#include "wincompat.h"
+
+#include <locale.h>
+
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#define PATH_TOKENS ":./"
+#define CHUNK_SIZE 10
+#define FLOAT_PRECISION 10
+
+#define _new(T) (T *)calloc(sizeof(T), 1) /* zeroed */
+#define _delete(P) free((void *)(P))
+
+/* ------------------------------------------------------------------------- */
+
+#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ return(TRUE);
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+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);
+
+extern int libconfig_yyparse(void *scanner, struct parse_context *ctx);
+
+/* ------------------------------------------------------------------------- */
+
+static void __config_locale_override()
+{
+#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()
+{
+#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_write_value(const config_value_t *value, int type,
+ int format, int depth, 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%lX", value->ival);
+ break;
+
+ case CONFIG_FORMAT_DEFAULT:
+ default:
+ fprintf(stream, "%ld", 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:
+ {
+ char *q;
+
+ snprintf(fbuf, sizeof(fbuf) - 3, "%.*g", FLOAT_PRECISION, value->fval);
+
+ /* check for exponent */
+
+ q = strchr(fbuf, 'e');
+ if(! q)
+ {
+ /* no exponent */
+
+ if(! strchr(fbuf, '.')) /* no decimal point */
+ strcat(fbuf, ".0");
+ else
+ {
+ /* has decimal point */
+
+ char *p;
+
+ for(p = fbuf + strlen(fbuf) - 1; p > fbuf; --p)
+ {
+ if(*p != '0')
+ {
+ *(++p) = '\0';
+ break;
+ }
+ }
+ }
+ }
+
+ fputs(fbuf, stream);
+ break;
+ }
+
+ /* string */
+ case CONFIG_TYPE_STRING:
+ {
+ char *p;
+
+ fputc('\"', stream);
+
+ if(value->sval)
+ {
+ for(p = value->sval; *p; p++)
+ {
+ switch(*p)
+ {
+ case '\"':
+ case '\\':
+ fputc('\\', stream);
+ fputc(*p, stream);
+ break;
+
+ case '\n':
+ fputs("\\n", stream);
+ break;
+
+ case '\r':
+ fputs("\\r", stream);
+ break;
+
+ case '\f':
+ fputs("\\f", stream);
+ break;
+
+ case '\t':
+ fputs("\\t", stream);
+ break;
+
+ default:
+ fputc(*p, stream);
+ }
+ }
+ }
+ fputc('\"', stream);
+ break;
+ }
+
+ /* list */
+ case CONFIG_TYPE_LIST:
+ {
+ config_list_t *list = value->list;
+
+ fprintf(stream, "( ");
+
+ if(list)
+ {
+ int len = list->length;
+ config_setting_t **s;
+
+ for(s = list->elements; len--; s++)
+ {
+ __config_write_value(&((*s)->value), (*s)->type, (*s)->format,
+ depth + 1, stream);
+
+ if(len)
+ fputc(',', stream);
+
+ fputc(' ', stream);
+ }
+ }
+
+ fputc(')', stream);
+ break;
+ }
+
+ /* array */
+ case CONFIG_TYPE_ARRAY:
+ {
+ config_list_t *list = value->list;
+
+ fprintf(stream, "[ ");
+
+ if(list)
+ {
+ int len = list->length;
+ config_setting_t **s;
+
+ for(s = list->elements; len--; s++)
+ {
+ __config_write_value(&((*s)->value), (*s)->type, (*s)->format,
+ depth + 1, stream);
+
+ if(len)
+ fputc(',', stream);
+
+ fputc(' ', stream);
+ }
+ }
+
+ fputc(']', stream);
+ break;
+ }
+
+ /* group */
+ case CONFIG_TYPE_GROUP:
+ {
+ config_list_t *list = value->list;
+
+ if(depth > 0)
+ {
+#ifdef K_AND_R_STYLE /* Horrendous, but many people like it. */
+ fputc(' ', stream);
+#else
+ fputc('\n', stream);
+
+ if(depth > 1)
+ fprintf(stream, "%*s", (depth - 1) * 2, " ");
+#endif
+ fprintf(stream, "{\n");
+ }
+
+ if(list)
+ {
+ int len = list->length;
+ config_setting_t **s;
+
+ for(s = list->elements; len--; s++)
+ __config_write_setting(*s, stream, depth + 1);
+ }
+
+ if(depth > 1)
+ fprintf(stream, "%*s", (depth - 1) * 2, " ");
+
+ if(depth > 0)
+ fputc('}', stream);
+
+ break;
+ }
+
+ default:
+ /* this shouldn't happen, but handle it gracefully... */
+ fputs("???", stream);
+ break;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void __config_list_add(config_list_t *list, config_setting_t *setting)
+{
+ if(list->length == list->capacity)
+ {
+ list->capacity += CHUNK_SIZE;
+ list->elements = (config_setting_t **)realloc(
+ list->elements, list->capacity * sizeof(config_setting_t *));
+ }
+
+ list->elements[list->length] = setting;
+ list->length++;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static config_setting_t *__config_list_search(config_list_t *list,
+ const char *name,
+ unsigned int *idx)
+{
+ config_setting_t **found = NULL;
+ unsigned int i;
+
+ if(! list)
+ return(NULL);
+
+ for(i = 0, found = list->elements; i < list->length; i++, found++)
+ {
+ if(! (*found)->name)
+ continue;
+
+ if(! __config_name_compare(name, (*found)->name))
+ {
+ if(idx)
+ *idx = i;
+
+ return(*found);
+ }
+ }
+
+ return(NULL);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static config_setting_t *__config_list_remove(config_list_t *list, int idx)
+{
+ config_setting_t *removed = *(list->elements + idx);
+ int offset = (idx * sizeof(config_setting_t *));
+ int len = list->length - 1 - idx;
+ char *base = (char *)list->elements + offset;
+
+ memmove(base, base + sizeof(config_setting_t *),
+ len * sizeof(config_setting_t *));
+
+ list->length--;
+
+ if((list->capacity - list->length) >= CHUNK_SIZE)
+ {
+ /* realloc smaller? */
+ }
+
+ return(removed);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void __config_setting_destroy(config_setting_t *setting)
+{
+ if(setting)
+ {
+ if(setting->name)
+ _delete(setting->name);
+
+ if(setting->type == CONFIG_TYPE_STRING)
+ _delete(setting->value.sval);
+
+ else if((setting->type == CONFIG_TYPE_GROUP)
+ || (setting->type == CONFIG_TYPE_ARRAY)
+ || (setting->type == CONFIG_TYPE_LIST))
+ {
+ if(setting->value.list)
+ __config_list_destroy(setting->value.list);
+ }
+
+ if(setting->hook && setting->config->destructor)
+ setting->config->destructor(setting->hook);
+
+ _delete(setting);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void __config_list_destroy(config_list_t *list)
+{
+ config_setting_t **p;
+ unsigned int i;
+
+ if(! list)
+ return;
+
+ if(list->elements)
+ {
+ for(p = list->elements, i = 0; i < list->length; p++, i++)
+ __config_setting_destroy(*p);
+
+ _delete(list->elements);
+ }
+
+ _delete(list);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int __config_vector_checktype(const config_setting_t *vector, int type)
+{
+ /* if the array is empty, then it has no type yet */
+
+ if(! vector->value.list)
+ return(CONFIG_TRUE);
+
+ if(vector->value.list->length == 0)
+ return(CONFIG_TRUE);
+
+ /* if it's a list, any type is allowed */
+
+ if(vector->type == CONFIG_TYPE_LIST)
+ return(CONFIG_TRUE);
+
+ /* otherwise the first element added determines the type of the array */
+
+ return((vector->value.list->elements[0]->type == type)
+ ? CONFIG_TRUE : CONFIG_FALSE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int __config_validate_name(const char *name)
+{
+ const char *p = name;
+
+ if(*p == '\0')
+ return(CONFIG_FALSE);
+
+ if(! isalpha(*p) && (*p != '*'))
+ return(CONFIG_FALSE);
+
+ for(++p; *p; ++p)
+ {
+ if(! (isalpha(*p) || isdigit(*p) || strchr("*_-", (int)*p)))
+ return(CONFIG_FALSE);
+ }
+
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int config_read(config_t *config, FILE *stream)
+{
+ yyscan_t scanner;
+ struct parse_context ctx;
+ int r;
+
+ /* Reinitialize the config (keep the destructor) */
+ void (*destructor)(void *) = config->destructor;
+ config_destroy(config);
+ config_init(config);
+ config->destructor = destructor;
+
+ ctx.config = config;
+ ctx.parent = config->root;
+ ctx.setting = config->root;
+
+ __config_locale_override();
+
+ libconfig_yylex_init(&scanner);
+ libconfig_yyrestart(stream, scanner);
+ r = libconfig_yyparse(scanner, &ctx);
+ libconfig_yylex_destroy(scanner);
+
+ __config_locale_restore();
+
+ return(r == 0 ? CONFIG_TRUE : CONFIG_FALSE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void __config_write_setting(const config_setting_t *setting,
+ FILE *stream, int depth)
+{
+ if(depth > 1)
+ fprintf(stream, "%*s", (depth - 1) * 2, " ");
+
+ if(setting->name)
+ {
+ fputs(setting->name, stream);
+ fprintf(stream, " %c ", (setting->type == CONFIG_TYPE_GROUP ? ':' : '='));
+ }
+
+ __config_write_value(&(setting->value), setting->type, setting->format,
+ depth, 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_locale_restore();
+}
+
+/* ------------------------------------------------------------------------- */
+
+int config_read_file(config_t *config, const char *filename)
+{
+ int ret;
+ FILE *f = fopen(filename, "rt");
+ if(! f)
+ {
+ config->error_text = __io_error;
+ return(CONFIG_FALSE);
+ }
+
+ ret = config_read(config, f);
+ fclose(f);
+ return(ret);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int config_write_file(config_t *config, const char *filename)
+{
+ FILE *f = fopen(filename, "wt");
+ if(! f)
+ {
+ config->error_text = __io_error;
+ return(CONFIG_FALSE);
+ }
+
+ config_write(config, f);
+ fclose(f);
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void config_destroy(config_t *config)
+{
+ __config_setting_destroy(config->root);
+
+ 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;
+}
+
+/* ------------------------------------------------------------------------- */
+
+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);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long config_setting_get_int(const config_setting_t *setting)
+{
+ switch(setting->type)
+ {
+ case CONFIG_TYPE_INT:
+ return(setting->value.ival);
+
+ case CONFIG_TYPE_INT64:
+ if((setting->value.llval > INT32_MAX)
+ || (setting->value.llval < INT32_MIN))
+ return(0);
+ else
+ return((long)setting->value.llval);
+
+ case CONFIG_TYPE_FLOAT:
+ if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0)
+ return((long)(setting->value.fval));
+ else
+ /* fall through */;
+
+ default:
+ return(0);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+long long config_setting_get_int64(const config_setting_t *setting)
+{
+ switch(setting->type)
+ {
+ case CONFIG_TYPE_INT64:
+ return(setting->value.llval);
+
+ case CONFIG_TYPE_INT:
+ return((long long)setting->value.ival);
+
+ case CONFIG_TYPE_FLOAT:
+ if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0)
+ return((long long)(setting->value.fval));
+ else
+ /* fall through */;
+
+ default:
+ return(0);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+int config_setting_lookup_int(const config_setting_t *setting,
+ const char *name, long *value)
+{
+ config_setting_t *member = config_setting_get_member(setting, name);
+ if(! member)
+ return(CONFIG_FALSE);
+
+ if(config_setting_type(member) != CONFIG_TYPE_INT)
+ return(CONFIG_FALSE);
+
+ *value = config_setting_get_int(member);
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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);
+
+ if(config_setting_type(member) != CONFIG_TYPE_INT64)
+ return(CONFIG_FALSE);
+
+ *value = config_setting_get_int64(member);
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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);
+
+ if(config_setting_type(member) != CONFIG_TYPE_FLOAT)
+ return(CONFIG_FALSE);
+
+ *value = config_setting_get_float(member);
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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, long 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 = (long)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);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+double config_setting_get_float(const config_setting_t *setting)
+{
+ switch(setting->type)
+ {
+ case CONFIG_TYPE_FLOAT:
+ return(setting->value.fval);
+
+ case CONFIG_TYPE_INT:
+ if(config_get_auto_convert(setting->config))
+ return((double)(setting->value.ival));
+ else
+ return(0.0);
+
+ case CONFIG_TYPE_INT64:
+ if(config_get_auto_convert(setting->config))
+ return((double)(setting->value.llval));
+ else
+ return(0.0);
+
+ default:
+ return(0.0);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+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 = (long)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(config_setting_t *setting)
+{
+ return(setting->format);
+}
+
+/* ------------------------------------------------------------------------- */
+
+config_setting_t *config_lookup(const config_t *config, const char *path)
+{
+ const char *p = path;
+ config_setting_t *setting = config->root, *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);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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,
+ long *value)
+{
+ const config_setting_t *s = config_lookup(config, path);
+ if(! s)
+ return(CONFIG_FALSE);
+
+ if(config_setting_type(s) != CONFIG_TYPE_INT)
+ return(CONFIG_FALSE);
+
+ *value = config_setting_get_int(s);
+
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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);
+
+ if(config_setting_type(s) != CONFIG_TYPE_INT64)
+ return(CONFIG_FALSE);
+
+ *value = config_setting_get_int64(s);
+
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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);
+
+ if(config_setting_type(s) != CONFIG_TYPE_FLOAT)
+ return(CONFIG_FALSE);
+
+ *value = config_setting_get_float(s);
+ return(CONFIG_TRUE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+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);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long 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, 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_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;
+}
+
+/* ------------------------------------------------------------------------- */
+
+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 < list->length; ++i, ++found)
+ {
+ if(*found == setting)
+ return(i);
+ }
+
+ return(-1);
+}
+
+/* ------------------------------------------------------------------------- */
+/* eof */
diff --git a/libconfig.h b/libconfig.h
new file mode 100644
index 0000000..cf6c67a
--- /dev/null
+++ b/libconfig.h
@@ -0,0 +1,266 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ Copyright (C) 2005-2009 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
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#ifndef __libconfig_h
+#define __libconfig_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+#if defined(LIBCONFIG_STATIC)
+#define LIBCONFIG_API
+#elif defined(LIBCONFIG_EXPORTS)
+#define LIBCONFIG_API __declspec(dllexport)
+#else /* ! LIBCONFIG_EXPORTS */
+#define LIBCONFIG_API __declspec(dllimport)
+#endif /* LIBCONFIG_STATIC */
+#else /* ! WIN32 */
+#define LIBCONFIG_API
+#endif /* WIN32 */
+
+#include <stdio.h>
+
+#define CONFIG_TYPE_NONE 0
+#define CONFIG_TYPE_GROUP 1
+#define CONFIG_TYPE_INT 2
+#define CONFIG_TYPE_INT64 3
+#define CONFIG_TYPE_FLOAT 4
+#define CONFIG_TYPE_STRING 5
+#define CONFIG_TYPE_BOOL 6
+#define CONFIG_TYPE_ARRAY 7
+#define CONFIG_TYPE_LIST 8
+
+#define CONFIG_FORMAT_DEFAULT 0
+#define CONFIG_FORMAT_HEX 1
+
+#define CONFIG_OPTION_AUTOCONVERT 0x01
+
+#define CONFIG_TRUE (1)
+#define CONFIG_FALSE (0)
+
+typedef union config_value_t
+{
+ long ival;
+ long long llval;
+ double fval;
+ char *sval;
+ struct config_list_t *list;
+} config_value_t;
+
+typedef struct config_setting_t
+{
+ char *name;
+ short type;
+ short format;
+ config_value_t value;
+ struct config_setting_t *parent;
+ struct config_t *config;
+ void *hook;
+ unsigned int line;
+} config_setting_t;
+
+typedef struct config_list_t
+{
+ unsigned int length;
+ unsigned int capacity;
+ config_setting_t **elements;
+} config_list_t;
+
+typedef struct config_t
+{
+ config_setting_t *root;
+ void (*destructor)(void *);
+ int flags;
+ const char *error_text;
+ int error_line;
+} config_t;
+
+extern LIBCONFIG_API int config_read(config_t *config, FILE *stream);
+extern LIBCONFIG_API void config_write(const config_t *config, FILE *stream);
+
+extern LIBCONFIG_API void config_set_auto_convert(config_t *config, int flag);
+extern LIBCONFIG_API int config_get_auto_convert(const config_t *config);
+
+extern LIBCONFIG_API int config_read_file(config_t *config,
+ const char *filename);
+extern LIBCONFIG_API int config_write_file(config_t *config,
+ const char *filename);
+
+extern LIBCONFIG_API void config_set_destructor(config_t *config,
+ void (*destructor)(void *));
+
+extern LIBCONFIG_API void config_init(config_t *config);
+extern LIBCONFIG_API void config_destroy(config_t *config);
+
+extern LIBCONFIG_API long config_setting_get_int(
+ const config_setting_t *setting);
+extern LIBCONFIG_API long long config_setting_get_int64(
+ const config_setting_t *setting);
+extern LIBCONFIG_API double config_setting_get_float(
+ const config_setting_t *setting);
+extern LIBCONFIG_API int config_setting_get_bool(
+ const config_setting_t *setting);
+extern LIBCONFIG_API const char *config_setting_get_string(
+ const config_setting_t *setting);
+
+extern LIBCONFIG_API int config_setting_lookup_int(
+ const config_setting_t *setting, const char *name, long *value);
+extern LIBCONFIG_API int config_setting_lookup_int64(
+ const config_setting_t *setting, const char *name, long long *value);
+extern LIBCONFIG_API int config_setting_lookup_float(
+ const config_setting_t *setting, const char *name, double *value);
+extern LIBCONFIG_API int config_setting_lookup_bool(
+ const config_setting_t *setting, const char *name, int *value);
+extern LIBCONFIG_API int config_setting_lookup_string(
+ const config_setting_t *setting, const char *name, const char **value);
+
+extern LIBCONFIG_API int config_setting_set_int(config_setting_t *setting,
+ long value);
+extern LIBCONFIG_API int config_setting_set_int64(config_setting_t *setting,
+ long long value);
+extern LIBCONFIG_API int config_setting_set_float(config_setting_t *setting,
+ double value);
+extern LIBCONFIG_API int config_setting_set_bool(config_setting_t *setting,
+ int value);
+extern LIBCONFIG_API int config_setting_set_string(config_setting_t *setting,
+ const char *value);
+
+extern LIBCONFIG_API int config_setting_set_format(config_setting_t *setting,
+ short format);
+extern LIBCONFIG_API short config_setting_get_format(config_setting_t *setting);
+
+extern LIBCONFIG_API long config_setting_get_int_elem(
+ const config_setting_t *setting, int idx);
+extern LIBCONFIG_API long long config_setting_get_int64_elem(
+ const config_setting_t *setting, int idx);
+extern LIBCONFIG_API double config_setting_get_float_elem(
+ const config_setting_t *setting, int idx);
+extern LIBCONFIG_API int config_setting_get_bool_elem(
+ const config_setting_t *setting, int idx);
+extern LIBCONFIG_API const char *config_setting_get_string_elem(
+ const config_setting_t *setting, int idx);
+
+extern LIBCONFIG_API config_setting_t *config_setting_set_int_elem(
+ config_setting_t *setting, int idx, long value);
+extern LIBCONFIG_API config_setting_t *config_setting_set_int64_elem(
+ config_setting_t *setting, int idx, long long value);
+extern LIBCONFIG_API config_setting_t *config_setting_set_float_elem(
+ config_setting_t *setting, int idx, double value);
+extern LIBCONFIG_API config_setting_t *config_setting_set_bool_elem(
+ config_setting_t *setting, int idx, int value);
+extern LIBCONFIG_API config_setting_t *config_setting_set_string_elem(
+ config_setting_t *setting, int idx, const char *value);
+
+#define /* int */ config_setting_type(/* const config_setting_t * */ S) \
+ ((S)->type)
+
+#define /* int */ config_setting_is_group(/* const config_setting_t * */ S) \
+ ((S)->type == CONFIG_TYPE_GROUP)
+#define /* int */ config_setting_is_array(/* const config_setting_t * */ S) \
+ ((S)->type == CONFIG_TYPE_ARRAY)
+#define /* int */ config_setting_is_list(/* const config_setting_t * */ S) \
+ ((S)->type == CONFIG_TYPE_LIST)
+
+#define /* int */ config_setting_is_aggregate( \
+ /* const config_setting_t * */ S) \
+ (((S)->type == CONFIG_TYPE_GROUP) || ((S)->type == CONFIG_TYPE_LIST) \
+ || ((S)->type == CONFIG_TYPE_ARRAY))
+
+#define /* int */ config_setting_is_number(/* const config_setting_t * */ S) \
+ (((S)->type == CONFIG_TYPE_INT) \
+ || ((S)->type == CONFIG_TYPE_INT64) \
+ || ((S)->type == CONFIG_TYPE_FLOAT))
+
+#define /* int */ config_setting_is_scalar(/* const config_setting_t * */ S) \
+ (((S)->type == CONFIG_TYPE_BOOL) || ((S)->type == CONFIG_TYPE_STRING) \
+ || config_setting_is_number(S))
+
+#define /* const char * */ config_setting_name( \
+ /* const config_setting_t * */ S) \
+ ((S)->name)
+
+#define /* config_setting_t * */ config_setting_parent( \
+ /* const config_setting_t * */ S) \
+ ((S)->parent)
+
+#define /* int */ config_setting_is_root( \
+ /* const config_setting_t * */ S) \
+ ((S)->parent ? CONFIG_FALSE : CONFIG_TRUE)
+
+extern LIBCONFIG_API int config_setting_index(const config_setting_t *setting);
+
+extern LIBCONFIG_API int config_setting_length(
+ const config_setting_t *setting);
+extern LIBCONFIG_API config_setting_t *config_setting_get_elem(
+ const config_setting_t *setting, unsigned int idx);
+
+extern LIBCONFIG_API config_setting_t *config_setting_get_member(
+ const config_setting_t *setting, const char *name);
+
+extern LIBCONFIG_API config_setting_t *config_setting_add(
+ config_setting_t *parent, const char *name, int type);
+extern LIBCONFIG_API int config_setting_remove(config_setting_t *parent,
+ const char *name);
+extern LIBCONFIG_API int config_setting_remove_elem(config_setting_t *parent,
+ unsigned int idx);
+extern LIBCONFIG_API void config_setting_set_hook(config_setting_t *setting,
+ void *hook);
+
+#define config_setting_get_hook(S) ((S)->hook)
+
+extern LIBCONFIG_API config_setting_t *config_lookup(const config_t *config,
+ const char *path);
+
+extern LIBCONFIG_API int config_lookup_int(const config_t *config,
+ const char *path, long *value);
+extern LIBCONFIG_API int config_lookup_int64(const config_t *config,
+ const char *path,
+ long long *value);
+extern LIBCONFIG_API int config_lookup_float(const config_t *config,
+ const char *path, double *value);
+extern LIBCONFIG_API int config_lookup_bool(const config_t *config,
+ const char *path, int *value);
+extern LIBCONFIG_API int config_lookup_string(const config_t *config,
+ const char *path,
+ const char **value);
+
+#define /* config_setting_t * */ config_root_setting( \
+ /* const config_t * */ C) \
+ ((C)->root)
+
+#define /* unsigned short */ config_setting_source_line( \
+ /* const config_t */ C) \
+ ((C)->line)
+
+#define /* const char * */ config_error_text(/* const config_t * */ C) \
+ ((C)->error_text)
+
+#define /* int */ config_error_line(/* const config_t * */ C) \
+ ((C)->error_line)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __libconfig_h */
diff --git a/libconfig.h++ b/libconfig.h++
new file mode 100644
index 0000000..0a3b4b2
--- /dev/null
+++ b/libconfig.h++
@@ -0,0 +1,424 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ Copyright (C) 2005-2009 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
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#ifndef __libconfig_hpp
+#define __libconfig_hpp
+
+#include <stdio.h>
+#include <string>
+#include <map>
+
+namespace libconfig
+{
+
+#include <libconfig.h>
+
+ class LIBCONFIG_API ConfigException : public std::exception { };
+
+ class Setting; // fwd decl
+
+ class LIBCONFIG_API SettingException : public ConfigException
+ {
+ friend class Config;
+
+ public:
+
+ SettingException(const SettingException &other);
+ SettingException& operator=(const SettingException &other);
+
+ virtual ~SettingException() throw();
+
+ const char *getPath() const;
+
+ virtual const char *what() const throw();
+
+ protected:
+
+ SettingException(const Setting &setting);
+ SettingException(const Setting &setting, int idx);
+ SettingException(const Setting &setting, const char *name);
+ SettingException(const char *path);
+
+ private:
+
+ char *_path;
+ };
+
+ class LIBCONFIG_API SettingTypeException : public SettingException
+ {
+ friend class Config;
+ friend class Setting;
+
+ const char *what() const throw();
+
+ private:
+
+ SettingTypeException(const Setting &setting);
+ SettingTypeException(const Setting &setting, int idx);
+ SettingTypeException(const Setting &setting, const char *name);
+ };
+
+ class LIBCONFIG_API SettingNotFoundException : public SettingException
+ {
+ friend class Config;
+ friend class Setting;
+
+ const char *what() const throw();
+
+ private:
+
+ SettingNotFoundException(const Setting &setting, int idx);
+ SettingNotFoundException(const Setting &setting, const char *name);
+ SettingNotFoundException(const char *path);
+ };
+
+ class LIBCONFIG_API SettingNameException : public SettingException
+ {
+ friend class Config;
+ friend class Setting;
+
+ const char *what() const throw();
+
+ private:
+
+ SettingNameException(const Setting &setting, const char *name);
+ };
+
+ class LIBCONFIG_API FileIOException : public ConfigException
+ {
+ const char *what() const throw();
+ };
+
+ class LIBCONFIG_API ParseException : public ConfigException
+ {
+ friend class Config;
+
+ public:
+
+ virtual ~ParseException() throw();
+
+ inline int getLine() throw()
+ { return(_line); }
+
+ inline const char *getError() throw()
+ { return(_error); }
+
+ const char *what() const throw();
+
+ private:
+
+ ParseException(int line, const char *error);
+
+ int _line;
+ const char *_error;
+ };
+
+ class LIBCONFIG_API Setting
+ {
+ friend class Config;
+
+ public:
+
+ enum Type
+ {
+ TypeNone = 0,
+ // scalar types
+ TypeInt,
+ TypeInt64,
+ TypeFloat,
+ TypeString,
+ TypeBoolean,
+ // aggregate types
+ TypeGroup,
+ TypeArray,
+ TypeList
+ };
+
+ enum Format
+ {
+ FormatDefault = 0,
+ FormatHex = 1
+ };
+
+ private:
+
+ config_setting_t *_setting;
+ Type _type;
+ Format _format;
+
+ Setting(config_setting_t *setting);
+
+ void assertType(Type type) const
+ throw(SettingTypeException);
+ static Setting & wrapSetting(config_setting_t *setting);
+
+ Setting(const Setting& other); // not supported
+ Setting& operator=(const Setting& other); // not supported
+
+ public:
+
+ virtual ~Setting() throw();
+
+ inline Type getType() const throw() { return(_type); }
+
+ inline Format getFormat() const throw() { return(_format); }
+ void setFormat(Format format) throw();
+
+ operator bool() const throw(SettingTypeException);
+ operator long() const throw(SettingTypeException);
+ operator unsigned long() const throw(SettingTypeException);
+ operator int() const throw(SettingTypeException);
+ operator unsigned int() const throw(SettingTypeException);
+ operator long long() const throw(SettingTypeException);
+ operator unsigned long long() const throw(SettingTypeException);
+ operator double() const throw(SettingTypeException);
+ operator float() const throw(SettingTypeException);
+ operator const char *() const throw(SettingTypeException);
+ operator std::string() const throw(SettingTypeException);
+
+ Setting & operator=(bool value) throw(SettingTypeException);
+ Setting & operator=(long value) throw(SettingTypeException);
+ Setting & operator=(int value) throw(SettingTypeException);
+ Setting & operator=(const long long &value) throw(SettingTypeException);
+ Setting & operator=(const double &value) throw(SettingTypeException);
+ Setting & operator=(float value) throw(SettingTypeException);
+ Setting & operator=(const char *value) throw(SettingTypeException);
+ Setting & operator=(const std::string &value) throw(SettingTypeException);
+
+ Setting & operator[](const char * key) const
+ throw(SettingTypeException, SettingNotFoundException);
+
+ inline Setting & operator[](const std::string & key) const
+ throw(SettingTypeException, SettingNotFoundException)
+ { return(operator[](key.c_str())); }
+
+ Setting & operator[](int index) const
+ throw(SettingTypeException, SettingNotFoundException);
+
+ bool lookupValue(const char *name, bool &value) const throw();
+ bool lookupValue(const char *name, long &value) const throw();
+ bool lookupValue(const char *name, unsigned long &value) const throw();
+ bool lookupValue(const char *name, int &value) const throw();
+ bool lookupValue(const char *name, unsigned int &value) const throw();
+ bool lookupValue(const char *name, long long &value) const throw();
+ bool lookupValue(const char *name, unsigned long long &value)
+ const throw();
+ bool lookupValue(const char *name, double &value) const throw();
+ bool lookupValue(const char *name, float &value) const throw();
+ bool lookupValue(const char *name, const char *&value) const throw();
+ bool lookupValue(const char *name, std::string &value) const throw();
+
+ inline bool lookupValue(const std::string &name, bool &value)
+ const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, long &value)
+ const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, unsigned long &value)
+ const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, int &value) const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, unsigned int &value)
+ const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, long long &value)
+ const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name,
+ unsigned long long &value) const throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, double &value) const
+ throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, float &value) const
+ throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, const char *&value) const
+ throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &name, std::string &value) const
+ throw()
+ { return(lookupValue(name.c_str(), value)); }
+
+ void remove(const char *name)
+ throw(SettingTypeException, SettingNotFoundException);
+
+ inline void remove(const std::string & name)
+ throw(SettingTypeException, SettingNotFoundException)
+ { remove(name.c_str()); }
+
+ void remove(unsigned int idx)
+ throw(SettingTypeException, SettingNotFoundException);
+
+ inline Setting & add(const std::string & name, Type type)
+ throw(SettingNameException, SettingTypeException)
+ { return(add(name.c_str(), type)); }
+
+ Setting & add(const char *name, Type type)
+ throw(SettingNameException, SettingTypeException);
+
+ Setting & add(Type type) throw(SettingTypeException);
+
+ inline bool exists(const std::string & name) const throw()
+ { return(exists(name.c_str())); }
+
+ bool exists(const char *name) const throw();
+
+ int getLength() const throw();
+ const char *getName() const throw();
+ std::string getPath() const;
+ int getIndex() const throw();
+
+ const Setting & getParent() const throw(SettingNotFoundException);
+ Setting & getParent() throw(SettingNotFoundException);
+
+ bool isRoot() const throw();
+
+ inline bool isGroup() const throw()
+ { return(_type == TypeGroup); }
+
+ inline bool isArray() const throw()
+ { return(_type == TypeArray); }
+
+ inline bool isList() const throw()
+ { return(_type == TypeList); }
+
+ inline bool isAggregate() const throw()
+ { return(_type >= TypeGroup); }
+
+ inline bool isScalar() const throw()
+ { return((_type > TypeNone) && (_type < TypeGroup)); }
+
+ inline bool isNumber() const throw()
+ { return((_type == TypeInt) || (_type == TypeInt64)
+ || (_type == TypeFloat)); }
+
+ inline unsigned int getSourceLine() const throw()
+ { return(config_setting_source_line(_setting)); }
+ };
+
+ class LIBCONFIG_API Config
+ {
+ private:
+
+ config_t _config;
+
+ static void ConfigDestructor(void *arg);
+ Config(const Config& other); // not supported
+ Config& operator=(const Config& other); // not supported
+
+ public:
+
+ Config();
+ virtual ~Config();
+
+ void setAutoConvert(bool flag);
+ bool getAutoConvert() const;
+
+ void read(FILE *stream) throw(ParseException);
+ void write(FILE *stream) const;
+
+ void readFile(const char *filename) throw(FileIOException, ParseException);
+ void writeFile(const char *filename) throw(FileIOException);
+
+ inline Setting & lookup(const std::string &path) const
+ throw(SettingNotFoundException)
+ { return(lookup(path.c_str())); }
+
+ Setting & lookup(const char *path) const throw(SettingNotFoundException);
+
+ inline bool exists(const std::string & path) const throw()
+ { return(exists(path.c_str())); }
+
+ bool exists(const char *path) const throw();
+
+ bool lookupValue(const char *path, bool &value) const throw();
+ bool lookupValue(const char *path, long &value) const throw();
+ bool lookupValue(const char *path, unsigned long &value) const throw();
+ bool lookupValue(const char *path, int &value) const throw();
+ bool lookupValue(const char *path, unsigned int &value) const throw();
+ bool lookupValue(const char *path, long long &value) const throw();
+ bool lookupValue(const char *path, unsigned long long &value)
+ const throw();
+ bool lookupValue(const char *path, double &value) const throw();
+ bool lookupValue(const char *path, float &value) const throw();
+ bool lookupValue(const char *path, const char *&value) const throw();
+ bool lookupValue(const char *path, std::string &value) const throw();
+
+ inline bool lookupValue(const std::string &path, bool &value) const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, long &value) const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, unsigned long &value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, int &value) const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, unsigned int &value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, long long &value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path,
+ unsigned long long &value) const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, double &value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, float &value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, const char *&value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ inline bool lookupValue(const std::string &path, std::string &value)
+ const throw()
+ { return(lookupValue(path.c_str(), value)); }
+
+ Setting & getRoot() const;
+ };
+
+} // namespace libconfig
+
+#endif // __libconfig_hpp
diff --git a/libconfig.hh b/libconfig.hh
new file mode 100644
index 0000000..8b3b2d5
--- /dev/null
+++ b/libconfig.hh
@@ -0,0 +1,23 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A structured configuration file parsing library
+ Copyright (C) 2005-2008 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 Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ----------------------------------------------------------------------------
+*/
+
+#include <libconfig.h++>
diff --git a/libconfig.pc.in b/libconfig.pc.in
new file mode 100644
index 0000000..4f7628b
--- /dev/null
+++ b/libconfig.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libconfig
+Description: C Configuration File Library
+Version: @VERSION@
+URL: http://www.hyperrealm.com/main.php?s=libconfig
+Requires:
+Conflicts:
+Libs: -L${libdir} -lconfig
+Libs.private: @LIBS@
+Cflags: -I${includedir}
diff --git a/libconfig.sln b/libconfig.sln
new file mode 100644
index 0000000..8a6c989
--- /dev/null
+++ b/libconfig.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig++_stub", "libconfig++_stub.vcproj", "{2A94C9E9-A7C7-4770-A24C-694312ADB850}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig++", "libconfig++.vcproj", "{A0C36CE7-D908-4573-8B69-249EEEB7D2BE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig", "libconfig.vcproj", "{1A234565-926D-49B2-83E4-D56E0C38C9F2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig_stub", "libconfig_stub.vcproj", "{6CD5E648-E434-4C9A-9872-AF884149CE93}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2A94C9E9-A7C7-4770-A24C-694312ADB850}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2A94C9E9-A7C7-4770-A24C-694312ADB850}.Debug|Win32.Build.0 = Debug|Win32
+ {2A94C9E9-A7C7-4770-A24C-694312ADB850}.Release|Win32.ActiveCfg = Release|Win32
+ {2A94C9E9-A7C7-4770-A24C-694312ADB850}.Release|Win32.Build.0 = Release|Win32
+ {A0C36CE7-D908-4573-8B69-249EEEB7D2BE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A0C36CE7-D908-4573-8B69-249EEEB7D2BE}.Debug|Win32.Build.0 = Debug|Win32
+ {A0C36CE7-D908-4573-8B69-249EEEB7D2BE}.Release|Win32.ActiveCfg = Release|Win32
+ {A0C36CE7-D908-4573-8B69-249EEEB7D2BE}.Release|Win32.Build.0 = Release|Win32
+ {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|Win32.Build.0 = Debug|Win32
+ {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|Win32.ActiveCfg = Release|Win32
+ {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|Win32.Build.0 = Release|Win32
+ {6CD5E648-E434-4C9A-9872-AF884149CE93}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6CD5E648-E434-4C9A-9872-AF884149CE93}.Debug|Win32.Build.0 = Debug|Win32
+ {6CD5E648-E434-4C9A-9872-AF884149CE93}.Release|Win32.ActiveCfg = Release|Win32
+ {6CD5E648-E434-4C9A-9872-AF884149CE93}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/libconfig.spec b/libconfig.spec
new file mode 100644
index 0000000..95e89c7
--- /dev/null
+++ b/libconfig.spec
@@ -0,0 +1,84 @@
+Name: libconfig
+Version: 1.3.2
+Release: 1
+Summary: C/C++ Configuration File Library
+
+Group: System Environment/Libraries
+License: LGPL
+URL: http://hyperrealm.com/main.php?s=libconfig
+Source0: %{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id} -u -n)
+
+Packager: Deneys S. Maartens <dsm@tlabs.ac.za>
+
+BuildRequires: texinfo
+
+%description
+%{name} is a simple library for manipulating structured configuration
+files. The file format is more compact and more readable than XML. And
+unlike XML, it is type-aware, so it is not necessary to do string
+parsing in application code.
+
+%{name} is very compact -- just 25K for the stripped C shared library
+(one-fifth the size of the expat XML parser library) and 39K for the
+stripped C++ shared library. This makes it well-suited for
+memory-constrained systems like handheld devices.
+
+The library includes bindings for both the C and C++ languages. It works
+on POSIX-compliant UNIX systems.
+
+%package devel
+Summary: %{name} development package
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description devel
+Development files for %{name}.
+
+%prep
+%setup -q
+
+%build
+%configure
+make %{?_smp_mflags}
+make html
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+ldconfig
+
+%postun
+ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING.LIB ChangeLog INSTALL NEWS README
+%{_libdir}/%{name}.so*
+%{_libdir}/%{name}++.so*
+
+%files devel
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING.LIB ChangeLog INSTALL NEWS README
+%doc doc/%{name}.html
+%doc test.cfg
+%doc samples/c/*.c
+%doc samples/c++/*.cpp
+%{_infodir}
+%{_includedir}
+%{_libdir}/pkgconfig
+%{_libdir}/%{name}.a
+%{_libdir}/%{name}.la
+%{_libdir}/%{name}++.a
+%{_libdir}/%{name}++.la
+
+%changelog
+* Wed Aug 19 2007 Deneys S. Maartens <dsm@tlabs.ac.za> 1.1.3-1
+- create spec file
+
+# -fin-
diff --git a/libconfig.spec.in b/libconfig.spec.in
new file mode 100644
index 0000000..963e4de
--- /dev/null
+++ b/libconfig.spec.in
@@ -0,0 +1,84 @@
+Name: @PACKAGE@
+Version: @VERSION@
+Release: 1
+Summary: C/C++ Configuration File Library
+
+Group: System Environment/Libraries
+License: LGPL
+URL: http://hyperrealm.com/main.php?s=libconfig
+Source0: %{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id} -u -n)
+
+Packager: Deneys S. Maartens <dsm@tlabs.ac.za>
+
+BuildRequires: texinfo
+
+%description
+%{name} is a simple library for manipulating structured configuration
+files. The file format is more compact and more readable than XML. And
+unlike XML, it is type-aware, so it is not necessary to do string
+parsing in application code.
+
+%{name} is very compact -- just 25K for the stripped C shared library
+(one-fifth the size of the expat XML parser library) and 39K for the
+stripped C++ shared library. This makes it well-suited for
+memory-constrained systems like handheld devices.
+
+The library includes bindings for both the C and C++ languages. It works
+on POSIX-compliant UNIX systems.
+
+%package devel
+Summary: %{name} development package
+Group: Development/Libraries
+Requires: %{name} = %{version}
+
+%description devel
+Development files for %{name}.
+
+%prep
+%setup -q
+
+%build
+%configure
+make %{?_smp_mflags}
+make html
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+ldconfig
+
+%postun
+ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING.LIB ChangeLog INSTALL NEWS README
+%{_libdir}/%{name}.so*
+%{_libdir}/%{name}++.so*
+
+%files devel
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING.LIB ChangeLog INSTALL NEWS README
+%doc doc/%{name}.html
+%doc test.cfg
+%doc samples/c/*.c
+%doc samples/c++/*.cpp
+%{_infodir}
+%{_includedir}
+%{_libdir}/pkgconfig
+%{_libdir}/%{name}.a
+%{_libdir}/%{name}.la
+%{_libdir}/%{name}++.a
+%{_libdir}/%{name}++.la
+
+%changelog
+* Wed Aug 19 2007 Deneys S. Maartens <dsm@tlabs.ac.za> 1.1.3-1
+- create spec file
+
+# -fin-
diff --git a/libconfig.vcproj b/libconfig.vcproj
new file mode 100644
index 0000000..219f694
--- /dev/null
+++ b/libconfig.vcproj
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libconfig"
+ ProjectGUID="{1A234565-926D-49B2-83E4-D56E0C38C9F2}"
+ RootNamespace="libconfig"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBCONFIG_EXPORTS;YY_NO_UNISTD_H"
+ RuntimeLibrary="3"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ GenerateMapFile="true"
+ MapExports="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="LIBCONFIG_EXPORTS;YY_NO_UNISTD_H;_CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\grammar.c"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfig.c"
+ >
+ </File>
+ <File
+ RelativePath=".\scanner.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\ac_config.h"
+ >
+ </File>
+ <File
+ RelativePath=".\config.tab.h"
+ >
+ </File>
+ <File
+ RelativePath=".\grammar.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libconfig.h"
+ >
+ </File>
+ <File
+ RelativePath=".\private.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\scanner.h"
+ >
+ </File>
+ <File
+ RelativePath=".\wincompat.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/libconfig_stub.vcproj b/libconfig_stub.vcproj
new file mode 100644
index 0000000..dc3e31f
--- /dev/null
+++ b/libconfig_stub.vcproj
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libconfig_stub"
+ ProjectGUID="{6CD5E648-E434-4C9A-9872-AF884149CE93}"
+ RootNamespace="libconfig_stub"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ RuntimeLibrary="3"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ProjectName).$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <ProjectReference
+ ReferencedProjectIdentifier="{1A234565-926D-49B2-83E4-D56E0C38C9F2}"
+ RelativePathToProject=".\libconfig.vcproj"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\samples\c\stub.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/libconfigcpp.c++ b/libconfigcpp.c++
new file mode 100644
index 0000000..82ad56e
--- /dev/null
+++ b/libconfigcpp.c++
@@ -0,0 +1,1112 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ Copyright (C) 2005-2009 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
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#include "libconfig.h++"
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4996)
+#endif
+
+#include "wincompat.h"
+
+using namespace libconfig;
+
+#include <cstring>
+#include <cstdlib>
+#include <sstream>
+
+// ---------------------------------------------------------------------------
+
+ParseException::ParseException(int line, const char *error)
+ : _line(line), _error(error)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+ParseException::~ParseException() throw()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+const char *ParseException::what() const throw()
+{
+ return("ParseException");
+}
+
+// ---------------------------------------------------------------------------
+
+static int __toTypeCode(Setting::Type type)
+{
+ int typecode;
+
+ switch(type)
+ {
+ case Setting::TypeGroup:
+ typecode = CONFIG_TYPE_GROUP;
+ break;
+
+ case Setting::TypeInt:
+ typecode = CONFIG_TYPE_INT;
+ break;
+
+ case Setting::TypeInt64:
+ typecode = CONFIG_TYPE_INT64;
+ break;
+
+ case Setting::TypeFloat:
+ typecode = CONFIG_TYPE_FLOAT;
+ break;
+
+ case Setting::TypeString:
+ typecode = CONFIG_TYPE_STRING;
+ break;
+
+ case Setting::TypeBoolean:
+ typecode = CONFIG_TYPE_BOOL;
+ break;
+
+ case Setting::TypeArray:
+ typecode = CONFIG_TYPE_ARRAY;
+ break;
+
+ case Setting::TypeList:
+ typecode = CONFIG_TYPE_LIST;
+ break;
+
+ default:
+ typecode = CONFIG_TYPE_NONE;
+ }
+
+ return(typecode);
+}
+
+// ---------------------------------------------------------------------------
+
+static void __constructPath(const Setting &setting,
+ std::stringstream &path)
+{
+ // head recursion to print path from root to target
+
+ if(! setting.isRoot())
+ {
+ __constructPath(setting.getParent(), path);
+ if(path.tellp() > 0)
+ path << '.';
+
+ const char *name = setting.getName();
+ if(name)
+ path << name;
+ else
+ path << '[' << setting.getIndex() << ']';
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException::SettingException(const Setting &setting)
+{
+ std::stringstream sstr;
+ __constructPath(setting, sstr);
+
+ _path = ::strdup(sstr.str().c_str());
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException::SettingException(const Setting &setting, int idx)
+{
+ std::stringstream sstr;
+ __constructPath(setting, sstr);
+ sstr << ".[" << idx << "]";
+
+ _path = ::strdup(sstr.str().c_str());
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException::SettingException(const Setting &setting, const char *name)
+{
+ std::stringstream sstr;
+ __constructPath(setting, sstr);
+ sstr << '.' << name;
+
+ _path = ::strdup(sstr.str().c_str());
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException::SettingException(const char *path)
+{
+ _path = ::strdup(path);
+}
+
+// ---------------------------------------------------------------------------
+
+const char *SettingException::getPath() const
+{
+ return(_path);
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException::SettingException(const SettingException &other)
+{
+ _path = ::strdup(other._path);
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException &SettingException::operator=(const SettingException &other)
+{
+ ::free(_path);
+ _path = ::strdup(other._path);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+const char *SettingException::what() const throw()
+{
+ return("SettingException");
+}
+
+// ---------------------------------------------------------------------------
+
+SettingException::~SettingException() throw()
+{
+ ::free(_path);
+}
+
+// ---------------------------------------------------------------------------
+
+SettingTypeException::SettingTypeException(const Setting &setting)
+ : SettingException(setting)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SettingTypeException::SettingTypeException(const Setting &setting, int idx)
+ : SettingException(setting, idx)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SettingTypeException::SettingTypeException(const Setting &setting,
+ const char *name)
+ : SettingException(setting, name)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+const char *SettingTypeException::what() const throw()
+{
+ return("SettingTypeException");
+}
+
+// ---------------------------------------------------------------------------
+
+SettingNotFoundException::SettingNotFoundException(const Setting &setting,
+ int idx)
+ : SettingException(setting, idx)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SettingNotFoundException::SettingNotFoundException(const Setting &setting,
+ const char *name)
+ : SettingException(setting, name)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SettingNotFoundException::SettingNotFoundException(const char *path)
+ : SettingException(path)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+const char *SettingNotFoundException::what() const throw()
+{
+ return("SettingNotFoundException");
+}
+
+// ---------------------------------------------------------------------------
+
+SettingNameException::SettingNameException(const Setting &setting,
+ const char *name)
+ : SettingException(setting, name)
+{
+}
+
+// ---------------------------------------------------------------------------
+
+const char *SettingNameException::what() const throw()
+{
+ return("SettingNameException");
+}
+
+// ---------------------------------------------------------------------------
+
+const char *FileIOException::what() const throw()
+{
+ return("FileIOException");
+}
+
+// ---------------------------------------------------------------------------
+
+void Config::ConfigDestructor(void *arg)
+{
+ delete reinterpret_cast<Setting *>(arg);
+}
+
+// ---------------------------------------------------------------------------
+
+Config::Config()
+{
+ config_init(& _config);
+ config_set_destructor(& _config, ConfigDestructor);
+}
+
+// ---------------------------------------------------------------------------
+
+Config::~Config()
+{
+ config_destroy(& _config);
+}
+
+// ---------------------------------------------------------------------------
+
+void Config::setAutoConvert(bool flag)
+{
+ config_set_auto_convert(& _config, (flag ? CONFIG_TRUE : CONFIG_FALSE));
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::getAutoConvert() const
+{
+ return(config_get_auto_convert(& _config) != CONFIG_FALSE);
+}
+
+// ---------------------------------------------------------------------------
+
+void Config::read(FILE *stream) throw(ParseException)
+{
+ if(! config_read(& _config, stream))
+ throw ParseException(config_error_line(& _config),
+ config_error_text(& _config));
+}
+
+// ---------------------------------------------------------------------------
+
+void Config::write(FILE *stream) const
+{
+ config_write(& _config, stream);
+}
+
+// ---------------------------------------------------------------------------
+
+void Config::readFile(const char *filename) throw(FileIOException,
+ ParseException)
+{
+ FILE *f = fopen(filename, "rt");
+ if(f == NULL)
+ throw FileIOException();
+ try
+ {
+ read(f);
+ fclose(f);
+ }
+ catch(ParseException& p)
+ {
+ fclose(f);
+ throw p;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+void Config::writeFile(const char *filename) throw(FileIOException)
+{
+ if(! config_write_file(& _config, filename))
+ throw FileIOException();
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Config::lookup(const char *path) const
+ throw(SettingNotFoundException)
+{
+ config_setting_t *s = config_lookup(& _config, path);
+ if(! s)
+ throw SettingNotFoundException(path);
+
+ return(Setting::wrapSetting(s));
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::exists(const char *path) const throw()
+{
+ config_setting_t *s = config_lookup(& _config, path);
+
+ return(s != NULL);
+}
+
+// ---------------------------------------------------------------------------
+
+#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V) \
+ try \
+ { \
+ Setting &s = lookup(P); \
+ V = (T)s; \
+ return(true); \
+ } \
+ catch(ConfigException) \
+ { \
+ return(false); \
+ }
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, bool &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, long &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, unsigned long &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, int &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, unsigned int &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, long long &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, unsigned long long &value)
+ const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, double &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, float &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, const char *&value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Config::lookupValue(const char *path, std::string &value) const throw()
+{
+ CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Config::getRoot() const
+{
+ return(Setting::wrapSetting(config_root_setting(& _config)));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::Setting(config_setting_t *setting)
+ : _setting(setting)
+{
+ switch(config_setting_type(setting))
+ {
+ case CONFIG_TYPE_GROUP:
+ _type = TypeGroup;
+ break;
+
+ case CONFIG_TYPE_INT:
+ _type = TypeInt;
+ break;
+
+ case CONFIG_TYPE_INT64:
+ _type = TypeInt64;
+ break;
+
+ case CONFIG_TYPE_FLOAT:
+ _type = TypeFloat;
+ break;
+
+ case CONFIG_TYPE_STRING:
+ _type = TypeString;
+ break;
+
+ case CONFIG_TYPE_BOOL:
+ _type = TypeBoolean;
+ break;
+
+ case CONFIG_TYPE_ARRAY:
+ _type = TypeArray;
+ break;
+
+ case CONFIG_TYPE_LIST:
+ _type = TypeList;
+ break;
+
+ case CONFIG_TYPE_NONE:
+ default:
+ _type = TypeNone;
+ break;
+ }
+
+ switch(config_setting_get_format(setting))
+ {
+ case CONFIG_FORMAT_HEX:
+ _format = FormatHex;
+ break;
+
+ case CONFIG_FORMAT_DEFAULT:
+ default:
+ _format = FormatDefault;
+ break;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::~Setting() throw()
+{
+ _setting = NULL;
+}
+
+// ---------------------------------------------------------------------------
+
+void Setting::setFormat(Format format) throw()
+{
+ if((_type == TypeInt) || (_type == TypeInt64))
+ {
+ if(format == FormatHex)
+ _format = FormatHex;
+ else
+ _format = FormatDefault;
+ }
+ else
+ _format = FormatDefault;
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator bool() const throw(SettingTypeException)
+{
+ assertType(TypeBoolean);
+
+ return(config_setting_get_bool(_setting) ? true : false);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator long() const throw(SettingTypeException)
+{
+ assertType(TypeInt);
+
+ return(config_setting_get_int(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator unsigned long() const throw(SettingTypeException)
+{
+ assertType(TypeInt);
+
+ long v = config_setting_get_int(_setting);
+
+ if(v < 0)
+ v = 0;
+
+ return(static_cast<unsigned long>(v));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator int() const throw(SettingTypeException)
+{
+ assertType(TypeInt);
+
+ // may cause loss of precision:
+ return(static_cast<int>(config_setting_get_int(_setting)));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator unsigned int() const throw(SettingTypeException)
+{
+ assertType(TypeInt);
+
+ long v = config_setting_get_int(_setting);
+
+ if(v < 0)
+ v = 0;
+
+ return(static_cast<unsigned int>(v));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator long long() const throw(SettingTypeException)
+{
+ assertType(TypeInt64);
+
+ return(config_setting_get_int64(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator unsigned long long() const throw(SettingTypeException)
+{
+ assertType(TypeInt64);
+
+ long long v = config_setting_get_int64(_setting);
+
+ if(v < INT64_CONST(0))
+ v = INT64_CONST(0);
+
+ return(static_cast<unsigned long long>(v));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator double() const throw(SettingTypeException)
+{
+ assertType(TypeFloat);
+
+ return(config_setting_get_float(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator float() const throw(SettingTypeException)
+{
+ assertType(TypeFloat);
+
+ // may cause loss of precision:
+ return(static_cast<float>(config_setting_get_float(_setting)));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator const char *() const throw(SettingTypeException)
+{
+ assertType(TypeString);
+
+ return(config_setting_get_string(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting::operator std::string() const throw(SettingTypeException)
+{
+ assertType(TypeString);
+
+ const char *s = config_setting_get_string(_setting);
+
+ std::string str;
+ if(s)
+ str = s;
+
+ return(str);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(bool value) throw(SettingTypeException)
+{
+ assertType(TypeBoolean);
+
+ config_setting_set_bool(_setting, value);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(long value) throw(SettingTypeException)
+{
+ assertType(TypeInt);
+
+ config_setting_set_int(_setting, value);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(int value) throw(SettingTypeException)
+{
+ assertType(TypeInt);
+
+ long cvalue = static_cast<long>(value);
+
+ config_setting_set_int(_setting, cvalue);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(const long long &value)
+ throw(SettingTypeException)
+{
+ assertType(TypeInt64);
+
+ config_setting_set_int64(_setting, value);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(const double &value) throw(SettingTypeException)
+{
+ assertType(TypeFloat);
+
+ config_setting_set_float(_setting, value);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(float value) throw(SettingTypeException)
+{
+ assertType(TypeFloat);
+
+ double cvalue = static_cast<double>(value);
+
+ config_setting_set_float(_setting, cvalue);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(const char *value) throw(SettingTypeException)
+{
+ assertType(TypeString);
+
+ config_setting_set_string(_setting, value);
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator=(const std::string &value)
+ throw(SettingTypeException)
+{
+ assertType(TypeString);
+
+ config_setting_set_string(_setting, value.c_str());
+
+ return(*this);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator[](int i) const
+ throw(SettingTypeException, SettingNotFoundException)
+{
+ if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
+ throw SettingTypeException(*this, i);
+
+ config_setting_t *setting = config_setting_get_elem(_setting, i);
+
+ if(! setting)
+ throw SettingNotFoundException(*this, i);
+
+ return(wrapSetting(setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::operator[](const char *key) const
+ throw(SettingTypeException, SettingNotFoundException)
+{
+ assertType(TypeGroup);
+
+ config_setting_t *setting = config_setting_get_member(_setting, key);
+
+ if(! setting)
+ throw SettingNotFoundException(*this, key);
+
+ return(wrapSetting(setting));
+}
+
+// ---------------------------------------------------------------------------
+
+#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V) \
+ try \
+ { \
+ Setting &s = operator[](K); \
+ V = (T)s; \
+ return(true); \
+ } \
+ catch(ConfigException) \
+ { \
+ return(false); \
+ }
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, bool &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, long &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, unsigned long &value)
+ const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, int &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, unsigned int &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, long long &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, unsigned long long &value)
+ const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, double &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, float &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, const char *&value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::lookupValue(const char *name, std::string &value) const throw()
+{
+ SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::exists(const char *name) const throw()
+{
+ if(_type != TypeGroup)
+ return(false);
+
+ config_setting_t *setting = config_setting_get_member(_setting, name);
+
+ return(setting != NULL);
+}
+
+// ---------------------------------------------------------------------------
+
+int Setting::getLength() const throw()
+{
+ return(config_setting_length(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+const char * Setting::getName() const throw()
+{
+ return(config_setting_name(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+std::string Setting::getPath() const
+{
+ std::stringstream path;
+
+ __constructPath(*this, path);
+
+ return(path.str());
+}
+
+// ---------------------------------------------------------------------------
+
+const Setting & Setting::getParent() const throw(SettingNotFoundException)
+{
+ config_setting_t *setting = config_setting_parent(_setting);
+
+ if(! setting)
+ throw SettingNotFoundException(NULL);
+
+ return(wrapSetting(setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::getParent() throw(SettingNotFoundException)
+{
+ config_setting_t *setting = config_setting_parent(_setting);
+
+ if(! setting)
+ throw SettingNotFoundException(NULL);
+
+ return(wrapSetting(setting));
+}
+
+// ---------------------------------------------------------------------------
+
+bool Setting::isRoot() const throw()
+{
+ return(config_setting_is_root(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+int Setting::getIndex() const throw()
+{
+ return(config_setting_index(_setting));
+}
+
+// ---------------------------------------------------------------------------
+
+void Setting::remove(const char *name)
+ throw(SettingTypeException, SettingNotFoundException)
+{
+ assertType(TypeGroup);
+
+ if(! config_setting_remove(_setting, name))
+ throw SettingNotFoundException(*this, name);
+}
+
+// ---------------------------------------------------------------------------
+
+void Setting::remove(unsigned int idx)
+ throw(SettingTypeException, SettingNotFoundException)
+{
+ if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
+ throw SettingTypeException(*this, idx);
+
+ if(! config_setting_remove_elem(_setting, idx))
+ throw SettingNotFoundException(*this, idx);
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::add(const char *name, Setting::Type type)
+ throw(SettingNameException, SettingTypeException)
+{
+ assertType(TypeGroup);
+
+ int typecode = __toTypeCode(type);
+
+ if(typecode == CONFIG_TYPE_NONE)
+ throw SettingTypeException(*this, name);
+
+ config_setting_t *setting = config_setting_add(_setting, name, typecode);
+
+ if(! setting)
+ throw SettingNameException(*this, name);
+
+ return(wrapSetting(setting));
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::add(Setting::Type type) throw(SettingTypeException)
+{
+ if((_type != TypeArray) && (_type != TypeList))
+ throw SettingTypeException(*this);
+
+ if(_type == TypeArray)
+ {
+ int idx = getLength();
+
+ if(idx > 0)
+ {
+ Setting::Type atype = operator[](0).getType();
+ if(type != atype)
+ throw SettingTypeException(*this, idx);
+ }
+ else
+ {
+ if((type != TypeInt) && (type != TypeFloat) && (type != TypeString)
+ && (type != TypeBoolean))
+ throw SettingTypeException(*this, idx);
+ }
+ }
+
+ int typecode = __toTypeCode(type);
+ config_setting_t *s = config_setting_add(_setting, NULL, typecode);
+
+ Setting &ns = wrapSetting(s);
+
+ switch(type)
+ {
+ case TypeInt:
+ ns = 0;
+ break;
+
+ case TypeInt64:
+ ns = INT64_CONST(0);
+ break;
+
+ case TypeFloat:
+ ns = 0.0;
+ break;
+
+ case TypeString:
+ ns = (char *)NULL;
+ break;
+
+ case TypeBoolean:
+ ns = false;
+ break;
+
+ default:
+ // won't happen
+ break;
+ }
+
+ return(ns);
+}
+
+// ---------------------------------------------------------------------------
+
+void Setting::assertType(Setting::Type type) const throw(SettingTypeException)
+{
+ if(type != _type)
+ {
+ if(!(isNumber() && config_get_auto_convert(_setting->config)
+ && ((type == TypeInt) || (type == TypeFloat))))
+ throw SettingTypeException(*this);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+Setting & Setting::wrapSetting(config_setting_t *s)
+{
+ Setting *setting = NULL;
+
+ void *hook = config_setting_get_hook(s);
+ if(! hook)
+ {
+ setting = new Setting(s);
+ config_setting_set_hook(s, reinterpret_cast<void *>(setting));
+ }
+ else
+ setting = reinterpret_cast<Setting *>(hook);
+
+ return(*setting);
+}
+
+// ---------------------------------------------------------------------------
+// eof
diff --git a/libconfigcpp.cc b/libconfigcpp.cc
new file mode 100644
index 0000000..3917ee7
--- /dev/null
+++ b/libconfigcpp.cc
@@ -0,0 +1,23 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A structured configuration file parsing library
+ Copyright (C) 2005-2008 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 Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ----------------------------------------------------------------------------
+*/
+
+#include "libconfigcpp.c++"