summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjk7744.park <jk7744.park@samsung.com>2015-10-24 16:03:25 +0900
committerjk7744.park <jk7744.park@samsung.com>2015-10-24 16:03:25 +0900
commit29fbfaf7e402c00837b491dcd6ac76ba2c7f31e3 (patch)
treea79b4c9e8246be9a28f6be9a90844bde20bc30fc
parent3a29fc23e7ceace9a3f29a5fe0f841c584ffc772 (diff)
downloadiniparser-accepted/tizen/2.4/mobile/20151029.040220.tar.gz
iniparser-accepted/tizen/2.4/mobile/20151029.040220.tar.bz2
iniparser-accepted/tizen/2.4/mobile/20151029.040220.zip
-rw-r--r--AUTHORS9
-rw-r--r--INSTALL13
-rw-r--r--LICENSE2
-rw-r--r--Makefile39
-rw-r--r--README5
-rw-r--r--doc/Makefile16
-rw-r--r--doc/iniparser.dox81
-rw-r--r--doc/iniparser.main207
-rw-r--r--html/doxygen.css745
-rw-r--r--html/globals_func.html84
-rw-r--r--html/index.html205
-rw-r--r--html/iniparser_8h.html468
-rw-r--r--html/iniparser_8main.html26
-rw-r--r--html/tabs.css15
-rwxr-xr-xpackaging/iniparser.spec6
-rw-r--r--packaging/iniparser_getstr_add.patch117
-rw-r--r--src/dictionary.c556
-rw-r--r--src/dictionary.h133
-rw-r--r--src/iniparser.c625
-rw-r--r--src/iniparser.h75
-rw-r--r--src/strlib.c211
-rw-r--r--src/strlib.h108
-rw-r--r--test/Makefile10
-rw-r--r--test/iniexample.c169
-rw-r--r--test/iniexample_thread.c170
-rw-r--r--test/parse.c24
-rwxr-xr-xtest/test.sh12
-rw-r--r--test/twisted-errors.ini9
-rw-r--r--test/twisted-genhuge.py12
-rw-r--r--test/twisted-ofkey.ini66
-rw-r--r--test/twisted-ofval.ini56
-rw-r--r--test/twisted.ini131
32 files changed, 2648 insertions, 1757 deletions
diff --git a/AUTHORS b/AUTHORS
index f3dc876..d5a3f6b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,6 @@
-Author for this package:
-Nicolas Devillard <ndevilla@free.fr>
+Author: Nicolas Devillard <ndevilla@free.fr>
+
+This tiny library has received countless contributions and I have
+not kept track of all the people who contributed. Let them be thanked
+for their ideas, code, suggestions, corrections, enhancements!
-Many thanks to the many people who contributed ideas, code, suggestions,
-corrections, enhancements.
diff --git a/INSTALL b/INSTALL
index 0d319b2..a5b05d0 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,11 +2,14 @@
iniParser installation instructions
-----------------------------------
-1. Modify the Makefile to suit your environment.
-2. Type 'make' to make the library.
-3. Type 'make check' to make the test program.
-4. Type 'test/iniexample' to launch the test program.
+- Modify the Makefile to suit your environment.
+- Type 'make' to make the library.
+- Type 'make check' to make the test program.
+- Type 'test/iniexample' to launch the test program.
+- Type 'test/parse' to launch torture tests.
+
+
Enjoy!
N. Devillard
-Tue Jan 14 11:52:03 CET 2003
+Wed Mar 2 21:14:17 CET 2011
diff --git a/LICENSE b/LICENSE
index 2eae408..5a3a80b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2000 by Nicolas Devillard.
+Copyright (c) 2000-2011 by Nicolas Devillard.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/Makefile b/Makefile
index bc5d612..f571d8a 100644
--- a/Makefile
+++ b/Makefile
@@ -3,37 +3,44 @@
#
# Compiler settings
-CC = gcc
-CFLAGS = -O3 -fPIC
+CC ?= gcc
+CFLAGS ?= -O2
+CFLAGS += -fPIC -Wall -ansi -pedantic
# Ar settings to build the library
-AR = ar
+AR ?= ar
ARFLAGS = rcv
SHLD = ${CC} ${CFLAGS}
-LDSHFLAGS = -shared -Wl,-Bsymbolic -Wl,-rpath -Wl,/usr/lib -Wl,-rpath,/usr/lib
-LDFLAGS = -Wl,-rpath -Wl,/usr/lib -Wl,-rpath,/usr/lib
+LDSHFLAGS = -shared -Wl,-Bsymbolic
+LDFLAGS += -Wl,-rpath -Wl,/usr/lib -Wl,-rpath,/usr/lib
# Set RANLIB to ranlib on systems that require it (Sun OS < 4, Mac OSX)
# RANLIB = ranlib
RANLIB = true
-RM = rm -f
+RM ?= rm -f
# Implicit rules
SUFFIXES = .o .c .h .a .so .sl
-COMPILE.c=$(CC) $(CFLAGS) -c
+COMPILE.c ?= $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+
+ifndef V
+QUIET_AR = @echo "AR $@";
+QUIET_CC = @echo "CC $@";
+QUIET_LINK = @echo "LINK $@";
+QUIET_RANLIB = @echo "RANLIB $@";
+endif
+
.c.o:
- @(echo "compiling $< ...")
- @($(COMPILE.c) -o $@ $<)
+ $(QUIET_CC)$(COMPILE.c) $(OUTPUT_OPTION) $<
SRCS = src/iniparser.c \
- src/dictionary.c \
- src/strlib.c
+ src/dictionary.c
OBJS = $(SRCS:.c=.o)
@@ -41,11 +48,11 @@ OBJS = $(SRCS:.c=.o)
default: libiniparser.a libiniparser.so
libiniparser.a: $(OBJS)
- @($(AR) $(ARFLAGS) libiniparser.a $(OBJS))
- @($(RANLIB) libiniparser.a)
+ $(QUIET_AR)$(AR) $(ARFLAGS) $@ $^
+ $(QUIET_RANLIB)$(RANLIB) $@
libiniparser.so: $(OBJS)
- @$(SHLD) $(LDSHFLAGS) -o $@.0 $(OBJS) $(LDFLAGS) \
+ $(QUIET_LINK)$(SHLD) $(LDSHFLAGS) $(LDFLAGS) -o $@.0 $(OBJS) \
-Wl,-soname=`basename $@`.0
clean:
@@ -59,5 +66,7 @@ veryclean:
docs:
@(cd doc ; $(MAKE))
-check:
+check: default
@(cd test ; $(MAKE))
+
+.PHONY: default clean veryclean docs check
diff --git a/README b/README
index 466d079..bc69787 100644
--- a/README
+++ b/README
@@ -1,5 +1,6 @@
-Welcome to iniParser!
+Welcome to iniParser -- version 3.1
+released 08 Apr 2012
This modules offers parsing of ini files from the C level.
See a complete documentation in HTML format, from this directory
@@ -8,4 +9,4 @@ open the file html/index.html with any HTML-capable browser.
Enjoy!
N.Devillard
-Thu Nov 17 12:31:42 CET 2005
+Sun Apr 8 16:38:09 CEST 2012
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..db925ec
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,16 @@
+#
+# iniparser doc Makefile
+#
+
+all: html
+
+html:
+ doxygen iniparser.dox
+ rm -f ../html/annotated.html
+ rm -f ../html/classes.html
+ rm -f ../html/doxygen.gif
+ rm -f ../html/files.html
+ rm -f ../html/functions.html
+ rm -f ../html/globals.html
+ rm -f ../html/iniparser_main.html
+
diff --git a/doc/iniparser.dox b/doc/iniparser.dox
new file mode 100644
index 0000000..ee59555
--- /dev/null
+++ b/doc/iniparser.dox
@@ -0,0 +1,81 @@
+PROJECT_NAME = iniparser
+PROJECT_NUMBER = 3.1
+OUTPUT_DIRECTORY = ..
+OUTPUT_LANGUAGE = English
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+HIDE_UNDOC_MEMBERS = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+INTERNAL_DOCS = NO
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+VERBATIM_HEADERS = NO
+SHOW_INCLUDE_FILES = NO
+JAVADOC_AUTOBRIEF = NO
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 4
+ENABLED_SECTIONS =
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+ALIASES =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = YES
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+INPUT = iniparser.main ../src
+FILE_PATTERNS = iniparser.h
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+
+GENERATE_LATEX = NO
+GENERATE_RTF = NO
+GENERATE_MAN = NO
+
+ENABLE_PREPROCESSING = NO
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = NO
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+PERL_PATH = /usr/bin/perl
+HAVE_DOT = NO
+SEARCHENGINE = NO
diff --git a/doc/iniparser.main b/doc/iniparser.main
new file mode 100644
index 0000000..47747c1
--- /dev/null
+++ b/doc/iniparser.main
@@ -0,0 +1,207 @@
+
+/**
+
+ @mainpage iniparser documentation
+
+
+ @section welcome Introduction
+
+ iniParser is a simple C library offering ini file parsing services.
+ The library is pretty small (less than 1500 lines of C) and robust, and
+ does not depend on any other external library to compile. It is written
+ in ANSI C and should compile on most platforms without difficulty.
+
+
+ @section inidef What is an ini file?
+
+ An ini file is an ASCII file describing simple parameters
+ (character strings, integers, floating-point values or booleans)
+ in an explicit format, easy to use and modify for users.
+
+ An ini file is segmented into Sections, declared by the following
+ syntax:
+
+ @verbatim
+ [Section Name]
+ @endverbatim
+
+ i.e. the section name enclosed in square brackets, alone on a
+ line. Sections names are allowed to contain any character but
+ square brackets or linefeeds.
+
+ In any section are zero or more variables, declared with the
+ following syntax:
+
+ @verbatim
+ Key = value ; comment
+ @endverbatim
+
+ The key is any string (possibly containing blanks). The value is
+ any character on the right side of the equal sign. Values can be
+ given enclosed with quotes. If no quotes are present, the value is
+ understood as containing all characters between the first and the
+ last non-blank characters before the comment. The following
+ declarations are identical:
+
+ @verbatim
+ Hello = "this is a long string value" ; comment
+ Hello = this is a long string value ; comment
+ @endverbatim
+
+ The semicolon and comment at the end of the line are optional. If
+ there is a comment, it starts from the first character after the
+ semicolon up to the end of the line.
+
+ Multi-line values can be provided by ending the line with a
+ backslash (\).
+
+ @verbatim
+ Multiple = Line 1 \
+ Line 2 \
+ Line 3 \
+ Line 4 ; comment
+ @endverbatim
+
+ This would yield: "multiple" <- "Line1 Line2 Line3 Line4"
+
+ Comments in an ini file are:
+
+ - Lines starting with a hash sign
+ - Blank lines (only blanks or tabs)
+ - Comments given on value lines after the semicolon (if present)
+
+
+ @section install Compiling/installing the library
+
+ Edit the Makefile to indicate the C compiler you want to use, the
+ options to provide to compile ANSI C, and possibly the options to pass
+ to the ar program on your machine to build a library (.a) from a set
+ of object (.o) files.
+
+ Defaults are set for the gcc compiler and the standard ar library
+ builder.
+
+ Type 'make', that should do it.
+
+ To use the library in your programs, add the following line on top
+ of your module:
+
+ @code
+ #include "iniparser.h"
+ @endcode
+
+ And link your program with the iniparser library by adding
+ @c -liniparser.a to the compile line.
+
+ See the file test/initest.c for an example.
+
+ iniparser is an ANSI C library. If you want to compile it
+ with a C++ compiler you will likely run into compatibility
+ issues. Headers probably have to include the extern "C"
+ hack and function prototypes will want to add some const
+ here and there to keep the compiler happy. This job is left
+ to the reader as there are too many C++ compilers around, each
+ with its own requirements as to what represents acceptable
+ C code in a C++ environment. You have been warned.
+
+
+ @section reference Library reference
+
+ The library is completely documented in its header file. On-line
+ documentation has been generated and can be consulted here:
+
+ - iniparser.h
+
+
+ @section usage Using the parser
+
+ Comments are discarded by the parser. Then sections are
+ identified, and in each section a new entry is created for every
+ keyword found. The keywords are stored with the following syntax:
+
+ @verbatim
+ [Section]
+ Keyword = value ; comment
+ @endverbatim
+
+ is converted to the following key pair:
+
+ @verbatim
+ ("section:keyword", "value")
+ @endverbatim
+
+ This means that if you want to retrieve the value that was stored
+ in the section called @c Pizza, in the keyword @c Cheese,
+ you would make a request to the dictionary for
+ @c "pizza:cheese". All section and keyword names are converted
+ to lowercase before storage in the structure. The value side is
+ conserved as it has been parsed, though.
+
+ Section names are also stored in the structure. They are stored
+ using as key the section name, and a NULL associated value. They
+ can be queried through iniparser_find_entry().
+
+ To launch the parser, use the function called iniparser_load(), which
+ takes an input file name and returns a newly allocated @e dictionary
+ structure. This latter object should remain opaque to the user and only
+ accessed through the following accessor functions:
+
+ - iniparser_getstring()
+ - iniparser_getint()
+ - iniparser_getdouble()
+ - iniparser_getboolean()
+
+ Finally, discard this structure using iniparser_freedict().
+
+ All values parsed from the ini file are stored as strings. The
+ accessors are just converting these strings to the requested type on
+ the fly, but you could basically perform this conversion by yourself
+ after having called the string accessor.
+
+ Notice that iniparser_getboolean() will return an integer (0 or 1),
+ trying to make sense of what was found in the file. Strings starting
+ with "y", "Y", "t", "T" or "1" are considered true values (return 1),
+ strings starting with "n", "N", "f", "F", "0" are considered false
+ (return 0). This allows some flexibility in handling of boolean
+ answers.
+
+ If you want to add extra information into the structure that was not
+ present in the ini file, you can use iniparser_set() to insert a
+ string.
+
+ If you want to add a section to the structure, add a key
+ with a NULL value. Example:
+ @verbatim
+ iniparser_set(ini, "section", NULL);
+ iniparser_set(ini, "section:key1", NULL);
+ iniparser_set(ini, "section:key2", NULL);
+ @endverbatim
+
+
+ @section implementation A word about the implementation
+
+ The dictionary structure is a pretty simple dictionary
+ implementation which might find some uses in other applications.
+ If you are curious, look into the source.
+
+
+ @section defects Known defects
+
+ The dictionary structure is extremely unefficient for searching
+ as keys are sorted in the same order as they are read from the
+ ini file, which is convenient when dumping back to a file. The
+ simplistic first-approach linear search implemented there can
+ become a bottleneck if you have a very large number of keys.
+
+ People who need to load large amounts of data from an ini file
+ should definitely turn to more appropriate solutions: sqlite3 or
+ similar. There are otherwise many other dictionary implementations
+ available on the net to replace this one.
+
+
+ @section authors Authors
+
+ Nicolas Devillard (ndevilla AT free DOT fr).
+
+
+*/
diff --git a/html/doxygen.css b/html/doxygen.css
index c7db1a8..d6aaf28 100644
--- a/html/doxygen.css
+++ b/html/doxygen.css
@@ -1,358 +1,545 @@
-BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
- font-family: Geneva, Arial, Helvetica, sans-serif;
-}
-BODY,TD {
- font-size: 90%;
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+ font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+ font-size: 12px;
}
-H1 {
+
+/* @group Heading Levels */
+
+h1 {
text-align: center;
- font-size: 160%;
+ font-size: 150%;
}
-H2 {
- font-size: 120%;
+
+h2 {
+ font-size: 120%;
}
-H3 {
- font-size: 100%;
+
+h3 {
+ font-size: 100%;
}
-CAPTION { font-weight: bold }
-DIV.qindex {
- width: 100%;
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+ margin-top: 2px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
background-color: #e8eef2;
border: 1px solid #84b0c7;
text-align: center;
margin: 2px;
padding: 2px;
- line-height: 140%;
}
-DIV.nav {
+
+div.qindex, div.navpath {
width: 100%;
- background-color: #e8eef2;
- border: 1px solid #84b0c7;
- text-align: center;
- margin: 2px;
- padding: 2px;
line-height: 140%;
}
-DIV.navtab {
- background-color: #e8eef2;
- border: 1px solid #84b0c7;
- text-align: center;
- margin: 2px;
- margin-right: 15px;
- padding: 2px;
+
+div.navtab {
+ margin-right: 15px;
}
-TD.navtab {
- font-size: 70%;
+
+/* @group Link Styling */
+
+a {
+ color: #153788;
+ font-weight: normal;
+ text-decoration: none;
}
-A.qindex {
- text-decoration: none;
- font-weight: bold;
- color: #1A419D;
+
+.contents a:visited {
+ color: #1b77c5;
}
-A.qindex:visited {
- text-decoration: none;
- font-weight: bold;
- color: #1A419D
+
+a:hover {
+ text-decoration: underline;
}
-A.qindex:hover {
- text-decoration: none;
- background-color: #ddddff;
+
+a.qindex {
+ font-weight: bold;
}
-A.qindexHL {
- text-decoration: none;
+
+a.qindexHL {
font-weight: bold;
background-color: #6666cc;
color: #ffffff;
border: 1px double #9295C2;
}
-A.qindexHL:hover {
- text-decoration: none;
- background-color: #6666cc;
- color: #ffffff;
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+ color: #3030f0;
}
-A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
-A.el { text-decoration: none; font-weight: bold }
-A.elRef { font-weight: bold }
-A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
-A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
-A.codeRef:link { font-weight: normal; color: #0000FF}
-A.codeRef:visited { font-weight: normal; color: #0000FF}
-A:hover { text-decoration: none; background-color: #f2f2ff }
-DL.el { margin-left: -1cm }
+
+a.codeRef {
+ color: #3030f0;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
.fragment {
- font-family: monospace, fixed;
- font-size: 95%;
+ font-family: monospace, fixed;
+ font-size: 105%;
}
-PRE.fragment {
+
+pre.fragment {
border: 1px solid #CCCCCC;
background-color: #f5f5f5;
- margin-top: 4px;
- margin-bottom: 4px;
- margin-left: 2px;
- margin-right: 8px;
- padding-left: 6px;
- padding-right: 6px;
- padding-top: 4px;
- padding-bottom: 4px;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ margin-bottom: 6px;
+ font-weight: bold;
}
-DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
-DIV.groupHeader {
- margin-left: 16px;
- margin-top: 12px;
- margin-bottom: 6px;
- font-weight: bold;
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
}
-DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
-BODY {
+
+body {
background: white;
color: black;
margin-right: 20px;
margin-left: 20px;
}
-TD.indexkey {
+
+td.indexkey {
background-color: #e8eef2;
font-weight: bold;
- padding-right : 10px;
- padding-top : 2px;
- padding-left : 10px;
- padding-bottom : 2px;
- margin-left : 0px;
- margin-right : 0px;
- margin-top : 2px;
- margin-bottom : 2px;
border: 1px solid #CCCCCC;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
}
-TD.indexvalue {
+
+td.indexvalue {
background-color: #e8eef2;
- font-style: italic;
- padding-right : 10px;
- padding-top : 2px;
- padding-left : 10px;
- padding-bottom : 2px;
- margin-left : 0px;
- margin-right : 0px;
- margin-top : 2px;
- margin-bottom : 2px;
border: 1px solid #CCCCCC;
+ padding: 2px 10px;
+ margin: 2px 0px;
}
-TR.memlist {
- background-color: #f0f0f0;
-}
-P.formulaDsp { text-align: center; }
-IMG.formulaDsp { }
-IMG.formulaInl { vertical-align: middle; }
-SPAN.keyword { color: #008000 }
-SPAN.keywordtype { color: #604020 }
-SPAN.keywordflow { color: #e08000 }
-SPAN.comment { color: #800000 }
-SPAN.preprocessor { color: #806020 }
-SPAN.stringliteral { color: #002080 }
-SPAN.charliteral { color: #008080 }
-.mdescLeft {
- padding: 0px 8px 4px 8px;
- font-size: 80%;
- font-style: italic;
- background-color: #FAFAFA;
- border-top: 1px none #E0E0E0;
- border-right: 1px none #E0E0E0;
- border-bottom: 1px none #E0E0E0;
- border-left: 1px none #E0E0E0;
- margin: 0px;
+
+tr.memlist {
+ background-color: #f0f0f0;
}
-.mdescRight {
- padding: 0px 8px 4px 8px;
- font-size: 80%;
- font-style: italic;
- background-color: #FAFAFA;
- border-top: 1px none #E0E0E0;
- border-right: 1px none #E0E0E0;
- border-bottom: 1px none #E0E0E0;
- border-left: 1px none #E0E0E0;
- margin: 0px;
+
+p.formulaDsp {
+ text-align: center;
}
-.memItemLeft {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
+
+img.formulaDsp {
+
}
-.memItemRight {
- padding: 1px 8px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
+
+img.formulaInl {
+ vertical-align: middle;
}
-.memTemplItemLeft {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: none;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
}
-.memTemplItemRight {
- padding: 1px 8px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: none;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- background-color: #FAFAFA;
- font-size: 80%;
+
+div.center img {
+ border: 0px;
}
-.memTemplParams {
- padding: 1px 0px 0px 8px;
- margin: 4px;
- border-top-width: 1px;
- border-right-width: 1px;
- border-bottom-width: 1px;
- border-left-width: 1px;
- border-top-color: #E0E0E0;
- border-right-color: #E0E0E0;
- border-bottom-color: #E0E0E0;
- border-left-color: #E0E0E0;
- border-top-style: solid;
- border-right-style: none;
- border-bottom-style: none;
- border-left-style: none;
- color: #606060;
- background-color: #FAFAFA;
- font-size: 80%;
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
}
-.search { color: #003399;
- font-weight: bold;
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
}
-FORM.search {
- margin-bottom: 0px;
- margin-top: 0px;
+
+span.keywordtype {
+ color: #604020
}
-INPUT.search { font-size: 75%;
- color: #000080;
- font-weight: normal;
- background-color: #e8eef2;
+
+span.keywordflow {
+ color: #e08000
}
-TD.tiny { font-size: 75%;
+
+span.comment {
+ color: #800000
}
-a {
- color: #1A41A8;
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+/* @end */
+
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #84b0c7;
+}
+
+th.dirtab {
+ background: #e8eef2;
+ font-weight: bold;
}
-a:visited {
- color: #2A3798;
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #666;
}
-.dirtab { padding: 4px;
- border-collapse: collapse;
- border: 1px solid #84b0c7;
+
+hr.footer {
+ height: 1px;
}
-TH.dirtab { background: #e8eef2;
- font-weight: bold;
+
+/* @group Member Descriptions */
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #FAFAFA;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
}
-HR { height: 1px;
- border: none;
- border-top: 1px solid black;
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
}
-/* Style for detailed member documentation */
+.memItemLeft, .memItemRight, .memTemplParams {
+ border-top: 1px solid #ccc;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memTemplParams {
+ color: #606060;
+ white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
.memtemplate {
- font-size: 80%;
- color: #606060;
- font-weight: normal;
-}
-.memnav {
- background-color: #e8eef2;
- border: 1px solid #84b0c7;
- text-align: center;
- margin: 2px;
- margin-right: 15px;
- padding: 2px;
+ font-size: 80%;
+ color: #606060;
+ font-weight: normal;
+ margin-left: 3px;
}
+
+.memnav {
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
.memitem {
- padding: 4px;
- background-color: #eef3f5;
- border-width: 1px;
- border-style: solid;
- border-color: #dedeee;
- -moz-border-radius: 8px 8px 8px 8px;
+ padding: 0;
+ margin-bottom: 10px;
}
+
.memname {
- white-space: nowrap;
- font-weight: bold;
-}
-.memdoc{
- padding-left: 10px;
+ white-space: nowrap;
+ font-weight: bold;
+ margin-left: 6px;
}
+
.memproto {
- background-color: #d5e1e8;
- width: 100%;
- border-width: 1px;
- border-style: solid;
- border-color: #84b0c7;
- font-weight: bold;
- -moz-border-radius: 8px 8px 8px 8px;
+ border-top: 1px solid #84b0c7;
+ border-left: 1px solid #84b0c7;
+ border-right: 1px solid #84b0c7;
+ padding: 0;
+ background-color: #d5e1e8;
+ font-weight: bold;
+ /* firefox specific markup */
+ background-image: -moz-linear-gradient(rgba(228, 233, 245, 1.0) 0%, rgba(193, 205, 232, 1.0) 100%);
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-topleft: 8px;
+ /* webkit specific markup */
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(228, 233, 245, 1.0)), to(rgba(193, 205, 232, 1.0)));
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-top-left-radius: 8px;
+
}
+
+.memdoc {
+ border-bottom: 1px solid #84b0c7;
+ border-left: 1px solid #84b0c7;
+ border-right: 1px solid #84b0c7;
+ padding: 2px 5px;
+ background-color: #eef3f5;
+ border-top-width: 0;
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
.paramkey {
- text-align: right;
+ text-align: right;
}
+
.paramtype {
- white-space: nowrap;
+ white-space: nowrap;
}
+
.paramname {
- color: #602020;
- font-style: italic;
- white-space: nowrap;
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
}
-/* End Styling for detailed member documentation */
+
+/* @end */
+
+/* @group Directory (tree) */
/* for the tree view */
+
.ftvtree {
font-family: sans-serif;
- margin:0.5em;
-}
-.directory { font-size: 9pt; font-weight: bold; }
-.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }
-.directory > h3 { margin-top: 0; }
-.directory p { margin: 0px; white-space: nowrap; }
-.directory div { display: none; margin: 0px; }
-.directory img { vertical-align: -30%; }
+ margin: 0.5em;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+}
+
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice. Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+ height: 61px;
+ background-repeat: no-repeat;
+ background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+ display: none;
+}
+*/
+
+.directory > h3 {
+ margin-top: 0;
+}
+
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory div {
+ display: none;
+ margin: 0px;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+.directory-alt > h3 {
+ margin-top: 0;
+}
+
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+
+.directory-alt img {
+ vertical-align: -30%;
+}
+
+/* @end */
+
+address {
+ font-style: normal;
+ color: #333;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #153788;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #254798;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+}
+
diff --git a/html/globals_func.html b/html/globals_func.html
index dc5c712..429cf31 100644
--- a/html/globals_func.html
+++ b/html/globals_func.html
@@ -1,54 +1,64 @@
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta name="author" content="ndevilla@free.fr">
- <meta name="keywords" content="ini file, config file, parser, C library">
- <link href="doxygen.css" rel="stylesheet" type="text/css">
-<title>iniparser 2.x</title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>iniparser: Data Fields</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
-
-<body text="#000000" bgcolor="#ffffff">
-
-
-
-<!-- Generated by Doxygen 1.5.1 -->
-<div class="tabs">
- <ul>
- <li><a href="globals.html"><span>All</span></a></li>
- <li id="current"><a href="globals_func.html"><span>Functions</span></a></li>
- </ul>
-</div>
-&nbsp;
-<p>
-<ul>
+<body>
+<!-- Generated by Doxygen 1.6.3 -->
+ <div class="tabs">
+ <ul>
+ <li><a href="globals.html"><span>All</span></a></li>
+ <li class="current"><a href="globals_func.html"><span>Functions</span></a></li>
+ </ul>
+ </div>
+<div class="contents">
+&nbsp;<ul>
<li>iniparser_dump()
-: <a class="el" href="iniparser_8h.html#046436b3489cd8854ba8e29109250324">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a046436b3489cd8854ba8e29109250324">iniparser.h</a>
+</li>
<li>iniparser_dump_ini()
-: <a class="el" href="iniparser_8h.html#ece0e32de371c9e9592d8333f816dfac">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#aece0e32de371c9e9592d8333f816dfac">iniparser.h</a>
+</li>
<li>iniparser_find_entry()
-: <a class="el" href="iniparser_8h.html#3d67c98bbc0cb5239f024ad54bdc63f1">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a3d67c98bbc0cb5239f024ad54bdc63f1">iniparser.h</a>
+</li>
<li>iniparser_freedict()
-: <a class="el" href="iniparser_8h.html#90549ee518523921886b74454ff872eb">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a90549ee518523921886b74454ff872eb">iniparser.h</a>
+</li>
<li>iniparser_getboolean()
-: <a class="el" href="iniparser_8h.html#eb93c13fcbb75efaa396f53bfd73ff4d">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#aa2ea2b34f6f4b3cf93c9d4f8f992811f">iniparser.h</a>
+</li>
<li>iniparser_getdouble()
-: <a class="el" href="iniparser_8h.html#480d35322f1252344cf2246ac21ee559">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a480d35322f1252344cf2246ac21ee559">iniparser.h</a>
+</li>
<li>iniparser_getint()
-: <a class="el" href="iniparser_8h.html#694eb1110f4200db8648820a0bb405fa">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#ab813340fa9c9a7fcfe6775d6e5e458c2">iniparser.h</a>
+</li>
<li>iniparser_getnsec()
-: <a class="el" href="iniparser_8h.html#0b5d6cdc7587e2d27a30f5cdc4a91931">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a0b5d6cdc7587e2d27a30f5cdc4a91931">iniparser.h</a>
+</li>
<li>iniparser_getsecname()
-: <a class="el" href="iniparser_8h.html#393212be805f395bbfdeb1bafa8bb72a">iniparser.h</a>
-<li>iniparser_getstr()
-: <a class="el" href="iniparser_8h.html#587eafb48937fdee8ae414ad7a666db8">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a393212be805f395bbfdeb1bafa8bb72a">iniparser.h</a>
+</li>
<li>iniparser_getstring()
-: <a class="el" href="iniparser_8h.html#7894f8480e1f254d4a1b4a31bdc51b46">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#aec2e5539bc2be063d1323cdf65f162a3">iniparser.h</a>
+</li>
<li>iniparser_load()
-: <a class="el" href="iniparser_8h.html#b0be559bfb769224b3f1b75e26242a67">iniparser.h</a>
-<li>iniparser_setstr()
-: <a class="el" href="iniparser_8h.html#605a88057bac4c3249513fc588421c32">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a45d87791d4d2593781bfdfe2991c3a2d">iniparser.h</a>
+</li>
+<li>iniparser_set()
+: <a class="el" href="iniparser_8h.html#aa5d5787f96d6982a937edb2fd499ba60">iniparser.h</a>
+</li>
<li>iniparser_unset()
-: <a class="el" href="iniparser_8h.html#7b1a7f2492a35043867fa801b8f21e52">iniparser.h</a>
+: <a class="el" href="iniparser_8h.html#a7b1a7f2492a35043867fa801b8f21e52">iniparser.h</a>
+</li>
</ul>
-
+</div>
+<hr class="footer"/><address style="text-align: right;"><small>Generated on Wed Mar 2 22:04:59 2011 for iniparser by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.3 </small></address>
</body>
</html>
diff --git a/html/index.html b/html/index.html
index a095755..a4e5b69 100644
--- a/html/index.html
+++ b/html/index.html
@@ -1,156 +1,101 @@
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta name="author" content="ndevilla@free.fr">
- <meta name="keywords" content="ini file, config file, parser, C library">
- <link href="doxygen.css" rel="stylesheet" type="text/css">
-<title>iniparser 2.x</title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>iniparser: iniparser documentation</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
-
-<body text="#000000" bgcolor="#ffffff">
-
-
-
-<!-- Generated by Doxygen 1.5.1 -->
-<h1>iniparser documentation</h1>
-<p>
-<h3 align="center">2.x </h3><hr>
-<h2><a class="anchor" name="welcome">
+<body>
+<!-- Generated by Doxygen 1.6.3 -->
+<div class="contents">
+<h1>iniparser documentation </h1><h3 class="version">3.0 </h3><h2><a class="anchor" id="welcome">
Introduction</a></h2>
-iniParser is a simple C library offering ini file parsing services. The library is pretty small (less than 1500 lines of C) and robust, and does not depend on any other external library to compile. It is written in ANSI C and should compile anywhere without difficulty.<p>
-<hr>
-<h2><a class="anchor" name="inidef">
+<p>iniParser is a simple C library offering ini file parsing services. The library is pretty small (less than 1500 lines of C) and robust, and does not depend on any other external library to compile. It is written in ANSI C and should compile on most platforms without difficulty.</p>
+<h2><a class="anchor" id="inidef">
What is an ini file?</a></h2>
-An ini file is an ASCII file describing simple parameters (character strings, integers, floating-point values or booleans) in an explicit format, easy to use and modify for users.<p>
-An ini file is segmented into Sections, declared by the following syntax:<p>
+<p>An ini file is an ASCII file describing simple parameters (character strings, integers, floating-point values or booleans) in an explicit format, easy to use and modify for users.</p>
+<p>An ini file is segmented into Sections, declared by the following syntax:</p>
<div class="fragment"><pre class="fragment">
[Section Name]
- </pre></div><p>
-i.e. the section name enclosed in square brackets, alone on a line. Sections names are allowed to contain any character but square brackets or linefeeds. Slashes (/) are also reserved for hierarchical sections (see below).<p>
-In any section are zero or more variables, declared with the following syntax:<p>
+ </pre></div><p>i.e. the section name enclosed in square brackets, alone on a line. Sections names are allowed to contain any character but square brackets or linefeeds.</p>
+<p>In any section are zero or more variables, declared with the following syntax:</p>
<div class="fragment"><pre class="fragment">
Key = value ; comment
- </pre></div><p>
-The key is any string (possibly containing blanks). The value is any character on the right side of the equal sign. Values can be given enclosed with quotes. If no quotes are present, the value is understood as containing all characters between the first and the last non-blank characters. The following declarations are identical:<p>
+ </pre></div><p>The key is any string (possibly containing blanks). The value is any character on the right side of the equal sign. Values can be given enclosed with quotes. If no quotes are present, the value is understood as containing all characters between the first and the last non-blank characters before the comment. The following declarations are identical:</p>
<div class="fragment"><pre class="fragment">
Hello = "this is a long string value" ; comment
Hello = this is a long string value ; comment
- </pre></div><p>
-The semicolon and comment at the end of the line are optional. If there is a comment, it starts from the first character after the semicolon up to the end of the line.<p>
-Comments in an ini file are:<p>
+ </pre></div><p>The semicolon and comment at the end of the line are optional. If there is a comment, it starts from the first character after the semicolon up to the end of the line.</p>
+<p>Multi-line values can be provided by ending the line with a backslash (\).</p>
+<div class="fragment"><pre class="fragment">
+ Multiple = Line 1 \
+ Line 2 \
+ Line 3 \
+ Line 4 ; comment
+ </pre></div><p>This would yield: "multiple" &lt;- "Line1 Line2 Line3 Line4"</p>
+<p>Comments in an ini file are:</p>
<ul>
-<li>Lines starting with a hash sign</li><li>Blank lines (only blanks or tabs)</li><li>Comments given on value lines after the semicolon (if present)</li></ul>
-<p>
-<hr>
-<h2><a class="anchor" name="install">
+<li>Lines starting with a hash sign</li>
+<li>Blank lines (only blanks or tabs)</li>
+<li>Comments given on value lines after the semicolon (if present)</li>
+</ul>
+<h2><a class="anchor" id="install">
Compiling/installing the library</a></h2>
-Edit the Makefile to indicate the C compiler you want to use, the options to provide to compile ANSI C, and possibly the options to pass to the <code>ar</code> program on your machine to build a library (.a) from a set of object (.o) files.<p>
-Defaults are set for the gcc compiler and the standard ar library builder.<p>
-Type 'make', that should do it.<p>
-To use the library in your programs, add the following line on top of your module:<p>
-<div class="fragment"><pre class="fragment"><span class="preprocessor"> #include "<a class="code" href="iniparser_8h.html">iniparser.h</a>"</span>
-</pre></div><p>
-And link your program with the iniparser library by adding <code>-liniparser.a</code> to the compile line.<p>
-See the file test/initest.c for an example.<p>
-<hr>
-<h2><a class="anchor" name="reference">
+<p>Edit the Makefile to indicate the C compiler you want to use, the options to provide to compile ANSI C, and possibly the options to pass to the ar program on your machine to build a library (.a) from a set of object (.o) files.</p>
+<p>Defaults are set for the gcc compiler and the standard ar library builder.</p>
+<p>Type 'make', that should do it.</p>
+<p>To use the library in your programs, add the following line on top of your module:</p>
+<div class="fragment"><pre class="fragment"><span class="preprocessor"> #include &quot;<a class="code" href="iniparser_8h.html" title="Parser for ini files.">iniparser.h</a>&quot;</span>
+</pre></div><p>And link your program with the iniparser library by adding <code>-liniparser.a</code> to the compile line.</p>
+<p>See the file test/initest.c for an example.</p>
+<p>iniparser is an ANSI C library. If you want to compile it with a C++ compiler you will likely run into compatibility issues. Headers probably have to include the extern "C" hack and function prototypes will want to add some const here and there to keep the compiler happy. This job is left to the reader as there are too many C++ compilers around, each with its own requirements as to what represents acceptable C code in a C++ environment. You have been warned.</p>
+<h2><a class="anchor" id="reference">
Library reference</a></h2>
-The library is completely documented in its header file. On-line documentation has been generated and can be consulted here:<p>
+<p>The library is completely documented in its header file. On-line documentation has been generated and can be consulted here:</p>
<ul>
-<li><a class="el" href="iniparser_8h.html">iniparser.h</a></li></ul>
-<p>
-<hr>
-<h2><a class="anchor" name="usage">
+<li><a class="el" href="iniparser_8h.html" title="Parser for ini files.">iniparser.h</a></li>
+</ul>
+<h2><a class="anchor" id="usage">
Using the parser</a></h2>
-Comments are discarded by the parser. Then sections are identified, and in each section a new entry is created for every keyword found. The keywords are stored with the following syntax:<p>
+<p>Comments are discarded by the parser. Then sections are identified, and in each section a new entry is created for every keyword found. The keywords are stored with the following syntax:</p>
<div class="fragment"><pre class="fragment">
[Section]
Keyword = value ; comment
- </pre></div><p>
-is converted to the following key pair:<p>
+ </pre></div><p>is converted to the following key pair:</p>
<div class="fragment"><pre class="fragment">
("section:keyword", "value")
- </pre></div><p>
-This means that if you want to retrieve the value that was stored in the section called <code>Pizza</code>, in the keyword <code>Cheese</code>, you would make a request to the dictionary for <code>"pizza:cheese"</code>. All section and keyword names are converted to lowercase before storage in the structure. The value side is conserved as it has been parsed, though.<p>
-Section names are also stored in the structure. They are stored using as key the section name, and a NULL associated value. They can be queried through <a class="el" href="iniparser_8h.html#3d67c98bbc0cb5239f024ad54bdc63f1">iniparser_find_entry()</a>.<p>
-To launch the parser, simply use the function called <a class="el" href="iniparser_8h.html#b0be559bfb769224b3f1b75e26242a67">iniparser_load()</a>, which takes an input file name and returns a newly allocated <em>dictionary</em> structure. This latter object should remain opaque to the user and only accessed through the following accessor functions:<p>
+ </pre></div><p>This means that if you want to retrieve the value that was stored in the section called <code>Pizza</code>, in the keyword <code>Cheese</code>, you would make a request to the dictionary for <code>"pizza:cheese"</code>. All section and keyword names are converted to lowercase before storage in the structure. The value side is conserved as it has been parsed, though.</p>
+<p>Section names are also stored in the structure. They are stored using as key the section name, and a NULL associated value. They can be queried through <a class="el" href="iniparser_8h.html#a3d67c98bbc0cb5239f024ad54bdc63f1" title="Finds out if a given entry exists in a dictionary.">iniparser_find_entry()</a>.</p>
+<p>To launch the parser, use the function called <a class="el" href="iniparser_8h.html#a45d87791d4d2593781bfdfe2991c3a2d" title="Parse an ini file and return an allocated dictionary object.">iniparser_load()</a>, which takes an input file name and returns a newly allocated <em>dictionary</em> structure. This latter object should remain opaque to the user and only accessed through the following accessor functions:</p>
<ul>
-<li><a class="el" href="iniparser_8h.html#587eafb48937fdee8ae414ad7a666db8">iniparser_getstr()</a></li><li><a class="el" href="iniparser_8h.html#694eb1110f4200db8648820a0bb405fa">iniparser_getint()</a></li><li><a class="el" href="iniparser_8h.html#480d35322f1252344cf2246ac21ee559">iniparser_getdouble()</a></li><li><a class="el" href="iniparser_8h.html#eb93c13fcbb75efaa396f53bfd73ff4d">iniparser_getboolean()</a></li></ul>
-<p>
-Finally, discard this structure using <a class="el" href="iniparser_8h.html#90549ee518523921886b74454ff872eb">iniparser_freedict()</a>.<p>
-All values parsed from the ini file are stored as strings. The getint, getdouble and getboolean accessors are just converting these strings to the requested type on the fly, but you could basically perform this conversion by yourself after having called the getstr accessor.<p>
-Notice that the <a class="el" href="iniparser_8h.html#eb93c13fcbb75efaa396f53bfd73ff4d">iniparser_getboolean()</a> function will return an integer (0 or 1), trying to make sense of what was found in the file. Strings starting with "y", "Y", "t", "T" or "1" are considered true values (return 1), strings starting with "n", "N", "f", "F", "0" are considered false (return 0). This allows flexible handling of boolean answers.<p>
-If you want to add extra information into the structure that was not present in the ini file, you can use <a class="el" href="iniparser_8h.html#605a88057bac4c3249513fc588421c32">iniparser_setstr()</a> to insert a string.<p>
-<hr>
-<h2><a class="anchor" name="implementation">
-A word about the implementation</a></h2>
-The dictionary structure is a pretty simple dictionary implementation which might find some uses in other applications. If you are curious, look into the source.<p>
-<hr>
-<h2><a class="anchor" name="hierarchical">
-Hierarchical ini files</a></h2>
-ini files are nice to present informations to the user in a readable format, but lack a very useful feature: the possibility of organizing data in a hierarchical (tree-like) fashion. The following convention can be used to make ini files obtain this second dimension:<p>
-A section depends on another section if it contains its name as a prefix, separated by slashes (/). For example: we have 2 main sections in the ini file. The first one is called <code>Pizza</code> and has two child subsections called <code>Cheese</code> and <code>Ham</code>. The second main section in the ini file is called <code>Wine</code> and has two child subsections called <code>Year</code> and <code>Grape</code>. As a tree, this could appear as:<p>
-<div class="fragment"><pre class="fragment">
- |
- +-- Pizza
- | +-- Cheese
- | +-- Ham
- +-- Wine
- +--- Year
- +--- Grape
- </pre></div><p>
-In an ini file, that would be converted to:<p>
+<li><a class="el" href="iniparser_8h.html#aec2e5539bc2be063d1323cdf65f162a3" title="Get the string associated to a key.">iniparser_getstring()</a></li>
+<li><a class="el" href="iniparser_8h.html#ab813340fa9c9a7fcfe6775d6e5e458c2" title="Get the string associated to a key, convert to an int.">iniparser_getint()</a></li>
+<li><a class="el" href="iniparser_8h.html#a480d35322f1252344cf2246ac21ee559" title="Get the string associated to a key, convert to a double.">iniparser_getdouble()</a></li>
+<li><a class="el" href="iniparser_8h.html#aa2ea2b34f6f4b3cf93c9d4f8f992811f" title="Get the string associated to a key, convert to a boolean.">iniparser_getboolean()</a></li>
+</ul>
+<p>Finally, discard this structure using <a class="el" href="iniparser_8h.html#a90549ee518523921886b74454ff872eb" title="Free all memory associated to an ini dictionary.">iniparser_freedict()</a>.</p>
+<p>All values parsed from the ini file are stored as strings. The accessors are just converting these strings to the requested type on the fly, but you could basically perform this conversion by yourself after having called the string accessor.</p>
+<p>Notice that <a class="el" href="iniparser_8h.html#aa2ea2b34f6f4b3cf93c9d4f8f992811f" title="Get the string associated to a key, convert to a boolean.">iniparser_getboolean()</a> will return an integer (0 or 1), trying to make sense of what was found in the file. Strings starting with "y", "Y", "t", "T" or "1" are considered true values (return 1), strings starting with "n", "N", "f", "F", "0" are considered false (return 0). This allows some flexibility in handling of boolean answers.</p>
+<p>If you want to add extra information into the structure that was not present in the ini file, you can use <a class="el" href="iniparser_8h.html#aa5d5787f96d6982a937edb2fd499ba60" title="Set an entry in a dictionary.">iniparser_set()</a> to insert a string.</p>
+<p>If you want to add a section to the structure, add a key with a NULL value. Example: </p>
<div class="fragment"><pre class="fragment">
- [Pizza]
-
- [Pizza/Cheese]
- Name = Gorgonzola ;
- Origin = Italy ;
-
- [Pizza/Ham]
- Name = Parma ;
- Origin = Italy ;
-
- [Wine]
-
- [Wine/Year]
- Value = 1998 ;
-
- [Wine/Grape]
- Name = Cabernet Sauvignon ;
- Origin = Chile ;
- </pre></div><p>
-This proposal is actually more related to the way people write ini files, more than the parser presented here. But it is certainly a useful way of making tree-like data declarations without going through painful formats like XML.<p>
-Accessing the above tree would give something like (error checking removed for clarity sake):<p>
-<div class="fragment"><pre class="fragment"> dictionary * d ;
-
- d = <a class="code" href="iniparser_8h.html#b0be559bfb769224b3f1b75e26242a67">iniparser_load</a>(<span class="stringliteral">"example.ini"</span>);
-
- printf(<span class="stringliteral">"cheese name is %s\n"</span>, <a class="code" href="iniparser_8h.html#587eafb48937fdee8ae414ad7a666db8">iniparser_getstr</a>(d, <span class="stringliteral">"pizza/cheese:name"</span>));
- printf(<span class="stringliteral">"grape name is %s\n"</span>, <a class="code" href="iniparser_8h.html#587eafb48937fdee8ae414ad7a666db8">iniparser_getstr</a>(d, <span class="stringliteral">"wine/grape:name"</span>));
-
- <a class="code" href="iniparser_8h.html#90549ee518523921886b74454ff872eb">iniparser_freedict</a>(d);
-</pre></div><p>
-The whole ini file above is represented in the dictionary as the following list of pairs:<p>
-<div class="fragment"><pre class="fragment">
- key value
-
- "pizza" NULL
- "pizza/cheese" NULL
- "pizza/cheese:name" "Gorgonzola"
- "pizza/cheese:origin" "Italy"
- "pizza/ham" NULL
- "pizza/ham:name" "Parma"
- "pizza/ham:origin" "Italy"
- "wine" NULL
- "wine/year" NULL
- "wine/year:value" "1998"
- "wine/grape" NULL
- "wine/grape:name" "Cabernet Sauvignon"
- "wine/grape:origin" "Chile"
- </pre></div><p>
-<hr>
-<h2><a class="anchor" name="authors">
+ iniparser_set(ini, "section", NULL);
+ iniparser_set(ini, "section:key1", NULL);
+ iniparser_set(ini, "section:key2", NULL);
+ </pre></div><h2><a class="anchor" id="implementation">
+A word about the implementation</a></h2>
+<p>The dictionary structure is a pretty simple dictionary implementation which might find some uses in other applications. If you are curious, look into the source.</p>
+<h2><a class="anchor" id="defects">
+Known defects</a></h2>
+<p>The dictionary structure is extremely unefficient for searching as keys are sorted in the same order as they are read from the ini file, which is convenient when dumping back to a file. The simplistic first-approach linear search implemented there can become a bottleneck if you have a very large number of keys.</p>
+<p>People who need to load large amounts of data from an ini file should definitely turn to more appropriate solutions: sqlite3 or similar. There are otherwise many other dictionary implementations available on the net to replace this one.</p>
+<h2><a class="anchor" id="authors">
Authors</a></h2>
-Nicolas Devillard (ndevilla AT free DOT fr).
+<p>Nicolas Devillard (ndevilla AT free DOT fr). </p>
+</div>
+<hr class="footer"/><address style="text-align: right;"><small>Generated on Wed Mar 2 22:04:58 2011 for iniparser by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.3 </small></address>
</body>
</html>
diff --git a/html/iniparser_8h.html b/html/iniparser_8h.html
index 9a7d5ec..09e8949 100644
--- a/html/iniparser_8h.html
+++ b/html/iniparser_8h.html
@@ -1,78 +1,58 @@
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta name="author" content="ndevilla@free.fr">
- <meta name="keywords" content="ini file, config file, parser, C library">
- <link href="doxygen.css" rel="stylesheet" type="text/css">
-<title>iniparser 2.x</title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>iniparser: iniparser.h File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
-
-<body text="#000000" bgcolor="#ffffff">
-
-
-
-<!-- Generated by Doxygen 1.5.1 -->
-<h1>iniparser.h File Reference</h1>Parser for ini files. <a href="#_details">More...</a>
-<p>
+<body>
+<!-- Generated by Doxygen 1.6.3 -->
+<div class="contents">
+<h1>iniparser.h File Reference</h1>
+<p>Parser for ini files.
+<a href="#_details">More...</a></p>
<table border="0" cellpadding="0" cellspacing="0">
-<tr><td></td></tr>
-<tr><td colspan="2"><br><h2>Functions</h2></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#0b5d6cdc7587e2d27a30f5cdc4a91931">iniparser_getnsec</a> (dictionary *d)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get number of sections in a dictionary. <a href="#0b5d6cdc7587e2d27a30f5cdc4a91931"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#393212be805f395bbfdeb1bafa8bb72a">iniparser_getsecname</a> (dictionary *d, int n)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get name for section n in a dictionary. <a href="#393212be805f395bbfdeb1bafa8bb72a"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#ece0e32de371c9e9592d8333f816dfac">iniparser_dump_ini</a> (dictionary *d, FILE *f)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Save a dictionary to a loadable ini file. <a href="#ece0e32de371c9e9592d8333f816dfac"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#046436b3489cd8854ba8e29109250324">iniparser_dump</a> (dictionary *d, FILE *f)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Dump a dictionary to an opened file pointer. <a href="#046436b3489cd8854ba8e29109250324"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#587eafb48937fdee8ae414ad7a666db8">iniparser_getstr</a> (dictionary *d, const char *key)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, return NULL if not found. <a href="#587eafb48937fdee8ae414ad7a666db8"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#7894f8480e1f254d4a1b4a31bdc51b46">iniparser_getstring</a> (dictionary *d, const char *key, char *def)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key. <a href="#7894f8480e1f254d4a1b4a31bdc51b46"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#694eb1110f4200db8648820a0bb405fa">iniparser_getint</a> (dictionary *d, const char *key, int notfound)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, convert to an int. <a href="#694eb1110f4200db8648820a0bb405fa"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">double&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#480d35322f1252344cf2246ac21ee559">iniparser_getdouble</a> (dictionary *d, char *key, double notfound)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, convert to a double. <a href="#480d35322f1252344cf2246ac21ee559"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#eb93c13fcbb75efaa396f53bfd73ff4d">iniparser_getboolean</a> (dictionary *d, const char *key, int notfound)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, convert to a boolean. <a href="#eb93c13fcbb75efaa396f53bfd73ff4d"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#605a88057bac4c3249513fc588421c32">iniparser_setstr</a> (dictionary *ini, char *entry, char *val)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set an entry in a dictionary. <a href="#605a88057bac4c3249513fc588421c32"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#7b1a7f2492a35043867fa801b8f21e52">iniparser_unset</a> (dictionary *ini, char *entry)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Delete an entry in a dictionary. <a href="#7b1a7f2492a35043867fa801b8f21e52"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#3d67c98bbc0cb5239f024ad54bdc63f1">iniparser_find_entry</a> (dictionary *ini, char *entry)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Finds out if a given entry exists in a dictionary. <a href="#3d67c98bbc0cb5239f024ad54bdc63f1"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">dictionary *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#b0be559bfb769224b3f1b75e26242a67">iniparser_load</a> (const char *ininame)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Parse an ini file and return an allocated dictionary object. <a href="#b0be559bfb769224b3f1b75e26242a67"></a><br></td></tr>
-<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#90549ee518523921886b74454ff872eb">iniparser_freedict</a> (dictionary *d)</td></tr>
-
-<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Free all memory associated to an ini dictionary. <a href="#90549ee518523921886b74454ff872eb"></a><br></td></tr>
+<tr><td colspan="2"><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a0b5d6cdc7587e2d27a30f5cdc4a91931">iniparser_getnsec</a> (dictionary *d)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get number of sections in a dictionary. <a href="#a0b5d6cdc7587e2d27a30f5cdc4a91931"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a393212be805f395bbfdeb1bafa8bb72a">iniparser_getsecname</a> (dictionary *d, int n)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get name for section n in a dictionary. <a href="#a393212be805f395bbfdeb1bafa8bb72a"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#aece0e32de371c9e9592d8333f816dfac">iniparser_dump_ini</a> (dictionary *d, FILE *f)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Save a dictionary to a loadable ini file. <a href="#aece0e32de371c9e9592d8333f816dfac"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a046436b3489cd8854ba8e29109250324">iniparser_dump</a> (dictionary *d, FILE *f)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Dump a dictionary to an opened file pointer. <a href="#a046436b3489cd8854ba8e29109250324"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">char *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#aec2e5539bc2be063d1323cdf65f162a3">iniparser_getstring</a> (dictionary *d, char *key, char *def)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key. <a href="#aec2e5539bc2be063d1323cdf65f162a3"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#ab813340fa9c9a7fcfe6775d6e5e458c2">iniparser_getint</a> (dictionary *d, char *key, int notfound)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, convert to an int. <a href="#ab813340fa9c9a7fcfe6775d6e5e458c2"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">double&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a480d35322f1252344cf2246ac21ee559">iniparser_getdouble</a> (dictionary *d, char *key, double notfound)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, convert to a double. <a href="#a480d35322f1252344cf2246ac21ee559"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#aa2ea2b34f6f4b3cf93c9d4f8f992811f">iniparser_getboolean</a> (dictionary *d, char *key, int notfound)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Get the string associated to a key, convert to a boolean. <a href="#aa2ea2b34f6f4b3cf93c9d4f8f992811f"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#aa5d5787f96d6982a937edb2fd499ba60">iniparser_set</a> (dictionary *ini, char *entry, char *val)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Set an entry in a dictionary. <a href="#aa5d5787f96d6982a937edb2fd499ba60"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a7b1a7f2492a35043867fa801b8f21e52">iniparser_unset</a> (dictionary *ini, char *entry)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Delete an entry in a dictionary. <a href="#a7b1a7f2492a35043867fa801b8f21e52"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a3d67c98bbc0cb5239f024ad54bdc63f1">iniparser_find_entry</a> (dictionary *ini, char *entry)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Finds out if a given entry exists in a dictionary. <a href="#a3d67c98bbc0cb5239f024ad54bdc63f1"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">dictionary *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a45d87791d4d2593781bfdfe2991c3a2d">iniparser_load</a> (char *ininame)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Parse an ini file and return an allocated dictionary object. <a href="#a45d87791d4d2593781bfdfe2991c3a2d"></a><br/></td></tr>
+<tr><td class="memItemLeft" align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="iniparser_8h.html#a90549ee518523921886b74454ff872eb">iniparser_freedict</a> (dictionary *d)</td></tr>
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Free all memory associated to an ini dictionary. <a href="#a90549ee518523921886b74454ff872eb"></a><br/></td></tr>
</table>
-<hr><a name="_details"></a><h2>Detailed Description</h2>
-Parser for ini files.
-<p>
-<dl class="author" compact><dt><b>Author:</b></dt><dd>N. Devillard </dd></dl>
-<dl class="date" compact><dt><b>Date:</b></dt><dd>Mar 2000 </dd></dl>
-<dl class="version" compact><dt><b>Version:</b></dt><dd><dl class="rcs" compact><dt><b>Revision</b></dt><dd>1.23 </dd></dl>
-</dd></dl>
-<hr><h2>Function Documentation</h2>
-<a class="anchor" name="046436b3489cd8854ba8e29109250324"></a><!-- doxytag: member="iniparser.h::iniparser_dump" ref="046436b3489cd8854ba8e29109250324" args="(dictionary *d, FILE *f)" -->
+<hr/><a name="_details"></a><h2>Detailed Description</h2>
+<p>Parser for ini files. </p>
+<dl class="author"><dt><b>Author:</b></dt><dd>N. Devillard </dd></dl>
+<dl class="date"><dt><b>Date:</b></dt><dd>Sep 2007 </dd></dl>
+<dl class="version"><dt><b>Version:</b></dt><dd>3.0 </dd></dl>
+<hr/><h2>Function Documentation</h2>
+<a class="anchor" id="a046436b3489cd8854ba8e29109250324"></a><!-- doxytag: member="iniparser.h::iniparser_dump" ref="a046436b3489cd8854ba8e29109250324" args="(dictionary *d, FILE *f)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">void iniparser_dump </td>
+ <td class="memname">void iniparser_dump </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -86,31 +66,31 @@ Parser for ini files.
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Dump a dictionary to an opened file pointer.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Dump a dictionary to an opened file pointer. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to dump. </td></tr>
<tr><td valign="top"></td><td valign="top"><em>f</em>&nbsp;</td><td>Opened file pointer to dump to. </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>void</dd></dl>
-This function prints out the contents of a dictionary, one element by line, onto the provided file pointer. It is OK to specify <code>stderr</code> or <code>stdout</code> as output files. This function is meant for debugging purposes mostly.
+<dl class="return"><dt><b>Returns:</b></dt><dd>void</dd></dl>
+<p>This function prints out the contents of a dictionary, one element by line, onto the provided file pointer. It is OK to specify <code>stderr</code> or <code>stdout</code> as output files. This function is meant for debugging purposes mostly. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="ece0e32de371c9e9592d8333f816dfac"></a><!-- doxytag: member="iniparser.h::iniparser_dump_ini" ref="ece0e32de371c9e9592d8333f816dfac" args="(dictionary *d, FILE *f)" -->
+<a class="anchor" id="aece0e32de371c9e9592d8333f816dfac"></a><!-- doxytag: member="iniparser.h::iniparser_dump_ini" ref="aece0e32de371c9e9592d8333f816dfac" args="(dictionary *d, FILE *f)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">void iniparser_dump_ini </td>
+ <td class="memname">void iniparser_dump_ini </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -124,31 +104,31 @@ This function prints out the contents of a dictionary, one element by line, onto
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Save a dictionary to a loadable ini file.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Save a dictionary to a loadable ini file. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to dump </td></tr>
<tr><td valign="top"></td><td valign="top"><em>f</em>&nbsp;</td><td>Opened file pointer to dump to </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>void</dd></dl>
-This function dumps a given dictionary into a loadable ini file. It is Ok to specify <code>stderr</code> or <code>stdout</code> as output files.
+<dl class="return"><dt><b>Returns:</b></dt><dd>void</dd></dl>
+<p>This function dumps a given dictionary into a loadable ini file. It is Ok to specify <code>stderr</code> or <code>stdout</code> as output files. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="3d67c98bbc0cb5239f024ad54bdc63f1"></a><!-- doxytag: member="iniparser.h::iniparser_find_entry" ref="3d67c98bbc0cb5239f024ad54bdc63f1" args="(dictionary *ini, char *entry)" -->
+<a class="anchor" id="a3d67c98bbc0cb5239f024ad54bdc63f1"></a><!-- doxytag: member="iniparser.h::iniparser_find_entry" ref="a3d67c98bbc0cb5239f024ad54bdc63f1" args="(dictionary *ini, char *entry)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">int iniparser_find_entry </td>
+ <td class="memname">int iniparser_find_entry </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>ini</em>, </td>
@@ -162,59 +142,59 @@ This function dumps a given dictionary into a loadable ini file. It is Ok to spe
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Finds out if a given entry exists in a dictionary.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Finds out if a given entry exists in a dictionary. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>ini</em>&nbsp;</td><td>Dictionary to search </td></tr>
<tr><td valign="top"></td><td valign="top"><em>entry</em>&nbsp;</td><td>Name of the entry to look for </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>integer 1 if entry exists, 0 otherwise</dd></dl>
-Finds out if a given entry exists in the dictionary. Since sections are stored as keys with NULL associated values, this is the only way of querying for the presence of sections in a dictionary.
+<dl class="return"><dt><b>Returns:</b></dt><dd>integer 1 if entry exists, 0 otherwise</dd></dl>
+<p>Finds out if a given entry exists in the dictionary. Since sections are stored as keys with NULL associated values, this is the only way of querying for the presence of sections in a dictionary. </p>
+
</div>
-</div><p>
-<a class="anchor" name="90549ee518523921886b74454ff872eb"></a><!-- doxytag: member="iniparser.h::iniparser_freedict" ref="90549ee518523921886b74454ff872eb" args="(dictionary *d)" -->
+</div>
+<a class="anchor" id="a90549ee518523921886b74454ff872eb"></a><!-- doxytag: member="iniparser.h::iniparser_freedict" ref="a90549ee518523921886b74454ff872eb" args="(dictionary *d)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">void iniparser_freedict </td>
+ <td class="memname">void iniparser_freedict </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
- <td class="paramname"> <em>d</em> </td>
+ <td class="paramname"> <em>d</em></td>
<td>&nbsp;)&nbsp;</td>
- <td width="100%"></td>
+ <td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Free all memory associated to an ini dictionary.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Free all memory associated to an ini dictionary. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to free </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>void</dd></dl>
-Free all memory associated to an ini dictionary. It is mandatory to call this function before the dictionary object gets out of the current context.
+<dl class="return"><dt><b>Returns:</b></dt><dd>void</dd></dl>
+<p>Free all memory associated to an ini dictionary. It is mandatory to call this function before the dictionary object gets out of the current context. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="eb93c13fcbb75efaa396f53bfd73ff4d"></a><!-- doxytag: member="iniparser.h::iniparser_getboolean" ref="eb93c13fcbb75efaa396f53bfd73ff4d" args="(dictionary *d, const char *key, int notfound)" -->
+<a class="anchor" id="aa2ea2b34f6f4b3cf93c9d4f8f992811f"></a><!-- doxytag: member="iniparser.h::iniparser_getboolean" ref="aa2ea2b34f6f4b3cf93c9d4f8f992811f" args="(dictionary *d, char *key, int notfound)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">int iniparser_getboolean </td>
+ <td class="memname">int iniparser_getboolean </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -222,7 +202,7 @@ Free all memory associated to an ini dictionary. It is mandatory to call this fu
<tr>
<td class="paramkey"></td>
<td></td>
- <td class="paramtype">const char *&nbsp;</td>
+ <td class="paramtype">char *&nbsp;</td>
<td class="paramname"> <em>key</em>, </td>
</tr>
<tr>
@@ -234,41 +214,49 @@ Free all memory associated to an ini dictionary. It is mandatory to call this fu
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Get the string associated to a key, convert to a boolean.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Get the string associated to a key, convert to a boolean. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to search </td></tr>
<tr><td valign="top"></td><td valign="top"><em>key</em>&nbsp;</td><td>Key string to look for </td></tr>
<tr><td valign="top"></td><td valign="top"><em>notfound</em>&nbsp;</td><td>Value to return in case of error </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>integer</dd></dl>
-This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.<p>
-A true boolean is found if one of the following is matched:<p>
+<dl class="return"><dt><b>Returns:</b></dt><dd>integer</dd></dl>
+<p>This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.</p>
+<p>A true boolean is found if one of the following is matched:</p>
<ul>
-<li>A string starting with 'y'</li><li>A string starting with 'Y'</li><li>A string starting with 't'</li><li>A string starting with 'T'</li><li>A string starting with '1'</li></ul>
-<p>
-A false boolean is found if one of the following is matched:<p>
+<li>A string starting with 'y'</li>
+<li>A string starting with 'Y'</li>
+<li>A string starting with 't'</li>
+<li>A string starting with 'T'</li>
+<li>A string starting with '1'</li>
+</ul>
+<p>A false boolean is found if one of the following is matched:</p>
<ul>
-<li>A string starting with 'n'</li><li>A string starting with 'N'</li><li>A string starting with 'f'</li><li>A string starting with 'F'</li><li>A string starting with '0'</li></ul>
-<p>
-The notfound value returned if no boolean is identified, does not necessarily have to be 0 or 1.
+<li>A string starting with 'n'</li>
+<li>A string starting with 'N'</li>
+<li>A string starting with 'f'</li>
+<li>A string starting with 'F'</li>
+<li>A string starting with '0'</li>
+</ul>
+<p>The notfound value returned if no boolean is identified, does not necessarily have to be 0 or 1. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="480d35322f1252344cf2246ac21ee559"></a><!-- doxytag: member="iniparser.h::iniparser_getdouble" ref="480d35322f1252344cf2246ac21ee559" args="(dictionary *d, char *key, double notfound)" -->
+<a class="anchor" id="a480d35322f1252344cf2246ac21ee559"></a><!-- doxytag: member="iniparser.h::iniparser_getdouble" ref="a480d35322f1252344cf2246ac21ee559" args="(dictionary *d, char *key, double notfound)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">double iniparser_getdouble </td>
+ <td class="memname">double iniparser_getdouble </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -288,32 +276,32 @@ The notfound value returned if no boolean is identified, does not necessarily ha
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Get the string associated to a key, convert to a double.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Get the string associated to a key, convert to a double. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to search </td></tr>
<tr><td valign="top"></td><td valign="top"><em>key</em>&nbsp;</td><td>Key string to look for </td></tr>
<tr><td valign="top"></td><td valign="top"><em>notfound</em>&nbsp;</td><td>Value to return in case of error </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>double</dd></dl>
-This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.
+<dl class="return"><dt><b>Returns:</b></dt><dd>double</dd></dl>
+<p>This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="694eb1110f4200db8648820a0bb405fa"></a><!-- doxytag: member="iniparser.h::iniparser_getint" ref="694eb1110f4200db8648820a0bb405fa" args="(dictionary *d, const char *key, int notfound)" -->
+<a class="anchor" id="ab813340fa9c9a7fcfe6775d6e5e458c2"></a><!-- doxytag: member="iniparser.h::iniparser_getint" ref="ab813340fa9c9a7fcfe6775d6e5e458c2" args="(dictionary *d, char *key, int notfound)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">int iniparser_getint </td>
+ <td class="memname">int iniparser_getint </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -321,7 +309,7 @@ This function queries a dictionary for a key. A key as read from an ini file is
<tr>
<td class="paramkey"></td>
<td></td>
- <td class="paramtype">const char *&nbsp;</td>
+ <td class="paramtype">char *&nbsp;</td>
<td class="paramname"> <em>key</em>, </td>
</tr>
<tr>
@@ -333,68 +321,70 @@ This function queries a dictionary for a key. A key as read from an ini file is
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Get the string associated to a key, convert to an int.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Get the string associated to a key, convert to an int. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to search </td></tr>
<tr><td valign="top"></td><td valign="top"><em>key</em>&nbsp;</td><td>Key string to look for </td></tr>
<tr><td valign="top"></td><td valign="top"><em>notfound</em>&nbsp;</td><td>Value to return in case of error </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>integer</dd></dl>
-This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.<p>
-Supported values for integers include the usual C notation so decimal, octal (starting with 0) and hexadecimal (starting with 0x) are supported. Examples:<p>
+<dl class="return"><dt><b>Returns:</b></dt><dd>integer</dd></dl>
+<p>This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.</p>
+<p>Supported values for integers include the usual C notation so decimal, octal (starting with 0) and hexadecimal (starting with 0x) are supported. Examples:</p>
<ul>
-<li>"42" -&gt; 42</li><li>"042" -&gt; 34 (octal -&gt; decimal)</li><li>"0x42" -&gt; 66 (hexa -&gt; decimal)</li></ul>
-<p>
-Warning: the conversion may overflow in various ways. Conversion is totally outsourced to strtol(), see the associated man page for overflow handling.<p>
-Credits: Thanks to A. Becker for suggesting strtol()
+<li>"42" -&gt; 42</li>
+<li>"042" -&gt; 34 (octal -&gt; decimal)</li>
+<li>"0x42" -&gt; 66 (hexa -&gt; decimal)</li>
+</ul>
+<p>Warning: the conversion may overflow in various ways. Conversion is totally outsourced to strtol(), see the associated man page for overflow handling.</p>
+<p>Credits: Thanks to A. Becker for suggesting strtol() </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="0b5d6cdc7587e2d27a30f5cdc4a91931"></a><!-- doxytag: member="iniparser.h::iniparser_getnsec" ref="0b5d6cdc7587e2d27a30f5cdc4a91931" args="(dictionary *d)" -->
+<a class="anchor" id="a0b5d6cdc7587e2d27a30f5cdc4a91931"></a><!-- doxytag: member="iniparser.h::iniparser_getnsec" ref="a0b5d6cdc7587e2d27a30f5cdc4a91931" args="(dictionary *d)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">int iniparser_getnsec </td>
+ <td class="memname">int iniparser_getnsec </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
- <td class="paramname"> <em>d</em> </td>
+ <td class="paramname"> <em>d</em></td>
<td>&nbsp;)&nbsp;</td>
- <td width="100%"></td>
+ <td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Get number of sections in a dictionary.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Get number of sections in a dictionary. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to examine </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>int Number of sections found in dictionary</dd></dl>
-This function returns the number of sections found in a dictionary. The test to recognize sections is done on the string stored in the dictionary: a section name is given as "section" whereas a key is stored as "section:key", thus the test looks for entries that do not contain a colon.<p>
-This clearly fails in the case a section name contains a colon, but this should simply be avoided.<p>
-This function returns -1 in case of error.
+<dl class="return"><dt><b>Returns:</b></dt><dd>int Number of sections found in dictionary</dd></dl>
+<p>This function returns the number of sections found in a dictionary. The test to recognize sections is done on the string stored in the dictionary: a section name is given as "section" whereas a key is stored as "section:key", thus the test looks for entries that do not contain a colon.</p>
+<p>This clearly fails in the case a section name contains a colon, but this should simply be avoided.</p>
+<p>This function returns -1 in case of error. </p>
+
</div>
-</div><p>
-<a class="anchor" name="393212be805f395bbfdeb1bafa8bb72a"></a><!-- doxytag: member="iniparser.h::iniparser_getsecname" ref="393212be805f395bbfdeb1bafa8bb72a" args="(dictionary *d, int n)" -->
+</div>
+<a class="anchor" id="a393212be805f395bbfdeb1bafa8bb72a"></a><!-- doxytag: member="iniparser.h::iniparser_getsecname" ref="a393212be805f395bbfdeb1bafa8bb72a" args="(dictionary *d, int n)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">char* iniparser_getsecname </td>
+ <td class="memname">char* iniparser_getsecname </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -408,71 +398,32 @@ This function returns -1 in case of error.
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Get name for section n in a dictionary.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Get name for section n in a dictionary. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to examine </td></tr>
<tr><td valign="top"></td><td valign="top"><em>n</em>&nbsp;</td><td>Section number (from 0 to nsec-1). </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>Pointer to char string</dd></dl>
-This function locates the n-th section in a dictionary and returns its name as a pointer to a string statically allocated inside the dictionary. Do not free or modify the returned string!<p>
-This function returns NULL in case of error.
-</div>
-</div><p>
-<a class="anchor" name="587eafb48937fdee8ae414ad7a666db8"></a><!-- doxytag: member="iniparser.h::iniparser_getstr" ref="587eafb48937fdee8ae414ad7a666db8" args="(dictionary *d, const char *key)" -->
-<div class="memitem">
-<div class="memproto">
- <table class="memname">
- <tr>
- <td class="memname">char* iniparser_getstr </td>
- <td>(</td>
- <td class="paramtype">dictionary *&nbsp;</td>
- <td class="paramname"> <em>d</em>, </td>
- </tr>
- <tr>
- <td class="paramkey"></td>
- <td></td>
- <td class="paramtype">const char *&nbsp;</td>
- <td class="paramname"> <em>key</em></td><td>&nbsp;</td>
- </tr>
- <tr>
- <td></td>
- <td>)</td>
- <td></td><td></td><td width="100%"></td>
- </tr>
- </table>
-</div>
-<div class="memdoc">
+<dl class="return"><dt><b>Returns:</b></dt><dd>Pointer to char string</dd></dl>
+<p>This function locates the n-th section in a dictionary and returns its name as a pointer to a string statically allocated inside the dictionary. Do not free or modify the returned string!</p>
+<p>This function returns NULL in case of error. </p>
-<p>
-Get the string associated to a key, return NULL if not found.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
- <table border="0" cellspacing="2" cellpadding="0">
- <tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to search </td></tr>
- <tr><td valign="top"></td><td valign="top"><em>key</em>&nbsp;</td><td>Key string to look for </td></tr>
- </table>
-</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>pointer to statically allocated character string, or NULL.</dd></dl>
-This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, NULL is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it.<p>
-This function is only provided for backwards compatibility with previous versions of iniparser. It is recommended to use <a class="el" href="iniparser_8h.html#7894f8480e1f254d4a1b4a31bdc51b46">iniparser_getstring()</a> instead.
</div>
-</div><p>
-<a class="anchor" name="7894f8480e1f254d4a1b4a31bdc51b46"></a><!-- doxytag: member="iniparser.h::iniparser_getstring" ref="7894f8480e1f254d4a1b4a31bdc51b46" args="(dictionary *d, const char *key, char *def)" -->
+</div>
+<a class="anchor" id="aec2e5539bc2be063d1323cdf65f162a3"></a><!-- doxytag: member="iniparser.h::iniparser_getstring" ref="aec2e5539bc2be063d1323cdf65f162a3" args="(dictionary *d, char *key, char *def)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">char* iniparser_getstring </td>
+ <td class="memname">char* iniparser_getstring </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>d</em>, </td>
@@ -480,7 +431,7 @@ This function is only provided for backwards compatibility with previous version
<tr>
<td class="paramkey"></td>
<td></td>
- <td class="paramtype">const char *&nbsp;</td>
+ <td class="paramtype">char *&nbsp;</td>
<td class="paramname"> <em>key</em>, </td>
</tr>
<tr>
@@ -492,61 +443,61 @@ This function is only provided for backwards compatibility with previous version
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Get the string associated to a key.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Get the string associated to a key. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>d</em>&nbsp;</td><td>Dictionary to search </td></tr>
<tr><td valign="top"></td><td valign="top"><em>key</em>&nbsp;</td><td>Key string to look for </td></tr>
<tr><td valign="top"></td><td valign="top"><em>def</em>&nbsp;</td><td>Default value to return if key not found. </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>pointer to statically allocated character string</dd></dl>
-This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the pointer passed as 'def' is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it.
+<dl class="return"><dt><b>Returns:</b></dt><dd>pointer to statically allocated character string</dd></dl>
+<p>This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the pointer passed as 'def' is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it. </p>
+
</div>
-</div><p>
-<a class="anchor" name="b0be559bfb769224b3f1b75e26242a67"></a><!-- doxytag: member="iniparser.h::iniparser_load" ref="b0be559bfb769224b3f1b75e26242a67" args="(const char *ininame)" -->
+</div>
+<a class="anchor" id="a45d87791d4d2593781bfdfe2991c3a2d"></a><!-- doxytag: member="iniparser.h::iniparser_load" ref="a45d87791d4d2593781bfdfe2991c3a2d" args="(char *ininame)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">dictionary* iniparser_load </td>
+ <td class="memname">dictionary* iniparser_load </td>
<td>(</td>
- <td class="paramtype">const char *&nbsp;</td>
- <td class="paramname"> <em>ininame</em> </td>
+ <td class="paramtype">char *&nbsp;</td>
+ <td class="paramname"> <em>ininame</em></td>
<td>&nbsp;)&nbsp;</td>
- <td width="100%"></td>
+ <td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Parse an ini file and return an allocated dictionary object.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Parse an ini file and return an allocated dictionary object. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>ininame</em>&nbsp;</td><td>Name of the ini file to read. </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>Pointer to newly allocated dictionary</dd></dl>
-This is the parser for ini files. This function is called, providing the name of the file to be read. It returns a dictionary object that should not be accessed directly, but through accessor functions instead.<p>
-The returned dictionary must be freed using <a class="el" href="iniparser_8h.html#90549ee518523921886b74454ff872eb">iniparser_freedict()</a>.
+<dl class="return"><dt><b>Returns:</b></dt><dd>Pointer to newly allocated dictionary</dd></dl>
+<p>This is the parser for ini files. This function is called, providing the name of the file to be read. It returns a dictionary object that should not be accessed directly, but through accessor functions instead.</p>
+<p>The returned dictionary must be freed using <a class="el" href="iniparser_8h.html#a90549ee518523921886b74454ff872eb" title="Free all memory associated to an ini dictionary.">iniparser_freedict()</a>. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="605a88057bac4c3249513fc588421c32"></a><!-- doxytag: member="iniparser.h::iniparser_setstr" ref="605a88057bac4c3249513fc588421c32" args="(dictionary *ini, char *entry, char *val)" -->
+<a class="anchor" id="aa5d5787f96d6982a937edb2fd499ba60"></a><!-- doxytag: member="iniparser.h::iniparser_set" ref="aa5d5787f96d6982a937edb2fd499ba60" args="(dictionary *ini, char *entry, char *val)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">int iniparser_setstr </td>
+ <td class="memname">int iniparser_set </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>ini</em>, </td>
@@ -566,32 +517,32 @@ The returned dictionary must be freed using <a class="el" href="iniparser_8h.htm
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Set an entry in a dictionary.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Set an entry in a dictionary. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>ini</em>&nbsp;</td><td>Dictionary to modify. </td></tr>
<tr><td valign="top"></td><td valign="top"><em>entry</em>&nbsp;</td><td>Entry to modify (entry name) </td></tr>
<tr><td valign="top"></td><td valign="top"><em>val</em>&nbsp;</td><td>New value to associate to the entry. </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>int 0 if Ok, -1 otherwise.</dd></dl>
-If the given entry can be found in the dictionary, it is modified to contain the provided value. If it cannot be found, -1 is returned. It is Ok to set val to NULL.
+<dl class="return"><dt><b>Returns:</b></dt><dd>int 0 if Ok, -1 otherwise.</dd></dl>
+<p>If the given entry can be found in the dictionary, it is modified to contain the provided value. If it cannot be found, -1 is returned. It is Ok to set val to NULL. </p>
+
+</div>
</div>
-</div><p>
-<a class="anchor" name="7b1a7f2492a35043867fa801b8f21e52"></a><!-- doxytag: member="iniparser.h::iniparser_unset" ref="7b1a7f2492a35043867fa801b8f21e52" args="(dictionary *ini, char *entry)" -->
+<a class="anchor" id="a7b1a7f2492a35043867fa801b8f21e52"></a><!-- doxytag: member="iniparser.h::iniparser_unset" ref="a7b1a7f2492a35043867fa801b8f21e52" args="(dictionary *ini, char *entry)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
- <td class="memname">void iniparser_unset </td>
+ <td class="memname">void iniparser_unset </td>
<td>(</td>
<td class="paramtype">dictionary *&nbsp;</td>
<td class="paramname"> <em>ini</em>, </td>
@@ -605,25 +556,28 @@ If the given entry can be found in the dictionary, it is modified to contain the
<tr>
<td></td>
<td>)</td>
- <td></td><td></td><td width="100%"></td>
+ <td></td><td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
-<p>
-Delete an entry in a dictionary.
-<p>
-<dl compact><dt><b>Parameters:</b></dt><dd>
+<p>Delete an entry in a dictionary. </p>
+<dl><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>ini</em>&nbsp;</td><td>Dictionary to modify </td></tr>
<tr><td valign="top"></td><td valign="top"><em>entry</em>&nbsp;</td><td>Entry to delete (entry name) </td></tr>
</table>
+ </dd>
</dl>
-<dl class="return" compact><dt><b>Returns:</b></dt><dd>void</dd></dl>
-If the given entry can be found, it is deleted from the dictionary.
-</div>
-</div><p>
+<dl class="return"><dt><b>Returns:</b></dt><dd>void</dd></dl>
+<p>If the given entry can be found, it is deleted from the dictionary. </p>
+</div>
+</div>
+</div>
+<hr class="footer"/><address style="text-align: right;"><small>Generated on Wed Mar 2 22:04:59 2011 for iniparser by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.3 </small></address>
</body>
</html>
diff --git a/html/iniparser_8main.html b/html/iniparser_8main.html
index a00eed2..3761667 100644
--- a/html/iniparser_8main.html
+++ b/html/iniparser_8main.html
@@ -1,19 +1,19 @@
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta name="author" content="ndevilla@free.fr">
- <meta name="keywords" content="ini file, config file, parser, C library">
- <link href="doxygen.css" rel="stylesheet" type="text/css">
-<title>iniparser 2.x</title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<title>iniparser: iniparser.main File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
-
-<body text="#000000" bgcolor="#ffffff">
-
-
-
-<!-- Generated by Doxygen 1.5.1 -->
+<body>
+<!-- Generated by Doxygen 1.6.3 -->
+<div class="contents">
<h1>iniparser.main File Reference</h1><table border="0" cellpadding="0" cellspacing="0">
-<tr><td></td></tr>
</table>
-
+</div>
+<hr class="footer"/><address style="text-align: right;"><small>Generated on Wed Mar 2 22:04:59 2011 for iniparser by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.3 </small></address>
</body>
</html>
diff --git a/html/tabs.css b/html/tabs.css
index a61552a..a444163 100644
--- a/html/tabs.css
+++ b/html/tabs.css
@@ -32,7 +32,7 @@ DIV.tabs A
float : left;
background : url("tab_r.gif") no-repeat right top;
border-bottom : 1px solid #84B0C7;
- font-size : x-small;
+ font-size : 80%;
font-weight : bold;
text-decoration : none;
}
@@ -57,7 +57,7 @@ DIV.tabs SPAN
white-space : nowrap;
}
-DIV.tabs INPUT
+DIV.tabs #MSearchBox
{
float : right;
display : inline;
@@ -66,7 +66,7 @@ DIV.tabs INPUT
DIV.tabs TD
{
- font-size : x-small;
+ font-size : 80%;
font-weight : bold;
text-decoration : none;
}
@@ -82,21 +82,24 @@ DIV.tabs A:hover SPAN
background-position: 0% -150px;
}
-DIV.tabs LI#current A
+DIV.tabs LI.current A
{
background-position: 100% -150px;
border-width : 0px;
}
-DIV.tabs LI#current SPAN
+DIV.tabs LI.current SPAN
{
background-position: 0% -150px;
padding-bottom : 6px;
}
-DIV.nav
+DIV.navpath
{
background : none;
border : none;
border-bottom : 1px solid #84B0C7;
+ text-align : center;
+ margin : 2px;
+ padding : 2px;
}
diff --git a/packaging/iniparser.spec b/packaging/iniparser.spec
index 4a5479f..6e72c40 100755
--- a/packaging/iniparser.spec
+++ b/packaging/iniparser.spec
@@ -1,8 +1,8 @@
#sbs-git:slp/unmodified/iniparser iniparser 2.17 2a9012b9ef8ccf91d380cd8293767ab6f101830b
Name: iniparser
Summary: Stand-alone ini file parsing library
-Version: 2.17
-Release: 3
+Version: 3.1
+Release: 2
Group: Applications/Databases
License: MIT
URL: http://ndevilla.free.fr/iniparser/
@@ -10,6 +10,7 @@ Source: http://ndevilla.free.fr/iniparser/iniparser-%{version}.tar.gz
Source1001: %{name}.manifest
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
+Patch1: iniparser_getstr_add.patch
%description
iniparser is a free stand-alone ini file parsing library.
@@ -29,6 +30,7 @@ to install %{name}-devel.
%prep
%setup -q
+%patch1 -p1
%build
cp %{SOURCE1001} .
LDFLAGS="-Wl,--rpath=%{_prefix}/lib -Wl,--hash-style=both -Wl,--as-needed $LDFLAGS" \
diff --git a/packaging/iniparser_getstr_add.patch b/packaging/iniparser_getstr_add.patch
new file mode 100644
index 0000000..22b76b9
--- /dev/null
+++ b/packaging/iniparser_getstr_add.patch
@@ -0,0 +1,117 @@
+Binary files iniparser/.git/index and iniparser_3.1/.git/index differ
+Only in iniparser_3.1/.git/objects/37: 10990f7726991967df604a6c635eb26f0337c6
+Only in iniparser_3.1/.git/objects: 5f
+Only in iniparser_3.1/.git/objects/e2: 893750416bbb6c6bd35bd6148e2c89b93580f4
+Only in iniparser_3.1/.git/objects: e8
+Only in iniparser_3.1: iniparser_getstr_add.patch
+diff -ru iniparser/src/iniparser.c iniparser_3.1/src/iniparser.c
+--- iniparser/src/iniparser.c 2015-02-25 14:37:27.509366130 +0900
++++ iniparser_3.1/src/iniparser.c 2015-02-25 16:34:03.297365295 +0900
+@@ -344,6 +344,29 @@
+
+ /*-------------------------------------------------------------------------*/
+ /**
++ @brief Get the string associated to a key, return NULL if not found
++ @param d Dictionary to search
++ @param key Key string to look for
++ @return pointer to statically allocated character string, or NULL.
++
++ This function queries a dictionary for a key. A key as read from an
++ ini file is given as "section:key". If the key cannot be found,
++ NULL is returned.
++ The returned char pointer is pointing to a string allocated in
++ the dictionary, do not free or modify it.
++
++ This function is only provided for backwards compatibility with
++ previous versions of iniparser. It is recommended to use
++ iniparser_getstring() instead.
++ */
++/*--------------------------------------------------------------------------*/
++char * iniparser_getstr(dictionary * d, const char * key)
++{
++ return iniparser_getstring(d, key, NULL);
++}
++
++/*-------------------------------------------------------------------------*/
++/**
+ @brief Get the string associated to a key
+ @param d Dictionary to search
+ @param key Key string to look for
+@@ -505,6 +528,25 @@
+
+ /*-------------------------------------------------------------------------*/
+ /**
++ @brief Set an entry in a dictionary.
++ @param ini Dictionary to modify.
++ @param entry Entry to modify (entry name)
++ @param val New value to associate to the entry.
++ @return int 0 if Ok, -1 otherwise.
++
++ If the given entry can be found in the dictionary, it is modified to
++ contain the provided value. If it cannot be found, -1 is returned.
++ It is Ok to set val to NULL.
++ */
++/*--------------------------------------------------------------------------*/
++int iniparser_setstr(dictionary * ini, char * entry, char * val)
++{
++ return iniparser_set(ini, entry, val);
++}
++
++
++/*-------------------------------------------------------------------------*/
++/**
+ @brief Set an entry in a dictionary.
+ @param ini Dictionary to modify.
+ @param entry Entry to modify (entry name)
+diff -ru iniparser/src/iniparser.h iniparser_3.1/src/iniparser.h
+--- iniparser/src/iniparser.h 2015-02-25 14:37:27.509366130 +0900
++++ iniparser_3.1/src/iniparser.h 2015-02-25 16:32:06.201365309 +0900
+@@ -143,6 +143,26 @@
+
+ /*-------------------------------------------------------------------------*/
+ /**
++ @brief Get the string associated to a key, return NULL if not found
++ @param d Dictionary to search
++ @param key Key string to look for
++ @return pointer to statically allocated character string, or NULL.
++
++ This function queries a dictionary for a key. A key as read from an
++ ini file is given as "section:key". If the key cannot be found,
++ NULL is returned.
++ The returned char pointer is pointing to a string allocated in
++ the dictionary, do not free or modify it.
++
++ This function is only provided for backwards compatibility with
++ previous versions of iniparser. It is recommended to use
++ iniparser_getstring() instead.
++ */
++/*--------------------------------------------------------------------------*/
++char * iniparser_getstr(dictionary * d, const char * key);
++
++/*-------------------------------------------------------------------------*/
++/**
+ @brief Get the string associated to a key
+ @param d Dictionary to search
+ @param key Key string to look for
+@@ -239,6 +259,21 @@
+
+ /*-------------------------------------------------------------------------*/
+ /**
++ @brief Set an entry in a dictionary.
++ @param ini Dictionary to modify.
++ @param entry Entry to modify (entry name)
++ @param val New value to associate to the entry.
++ @return int 0 if Ok, -1 otherwise.
++
++ If the given entry can be found in the dictionary, it is modified to
++ contain the provided value. If it cannot be found, -1 is returned.
++ It is Ok to set val to NULL.
++ */
++/*--------------------------------------------------------------------------*/
++int iniparser_setstr(dictionary * ini, char * entry, char * val);
++
++/*-------------------------------------------------------------------------*/
++/**
+ @brief Set an entry in a dictionary.
+ @param ini Dictionary to modify.
+ @param entry Entry to modify (entry name)
diff --git a/src/dictionary.c b/src/dictionary.c
index b9d426d..d3d3e27 100644
--- a/src/dictionary.c
+++ b/src/dictionary.c
@@ -1,11 +1,8 @@
-
/*-------------------------------------------------------------------------*/
/**
- @file dictionary.c
- @author N. Devillard
- @date Aug 2000
- @version $Revision: 1.25 $
- @brief Implements a dictionary for string variables.
+ @file dictionary.c
+ @author N. Devillard
+ @brief Implements a dictionary for string variables.
This module implements a simple dictionary object, i.e. a list
of string/string associations. This object is useful to store e.g.
@@ -13,17 +10,9 @@
*/
/*--------------------------------------------------------------------------*/
-/*
- $Id: dictionary.c,v 1.25 2007-05-27 13:03:43 ndevilla Exp $
- $Author: ndevilla $
- $Date: 2007-05-27 13:03:43 $
- $Revision: 1.25 $
-*/
-
/*---------------------------------------------------------------------------
- Includes
+ Includes
---------------------------------------------------------------------------*/
-
#include "dictionary.h"
#include <stdio.h>
@@ -31,43 +20,67 @@
#include <string.h>
#include <unistd.h>
-
/** Maximum value size for integers and doubles. */
-#define MAXVALSZ 1024
+#define MAXVALSZ 1024
/** Minimal allocated number of entries in a dictionary */
-#define DICTMINSZ 128
+#define DICTMINSZ 128
/** Invalid key token */
#define DICT_INVALID_KEY ((char*)-1)
-
/*---------------------------------------------------------------------------
- Private functions
+ Private functions
---------------------------------------------------------------------------*/
/* Doubles the allocated size associated to a pointer */
/* 'size' is the current allocated size. */
-static void * mem_double(void * ptr, int size)
+static void * mem_double(void * ptr, size_t size)
{
- void * newptr ;
-
+ void * newptr ;
+
newptr = calloc(2*size, 1);
+ if (newptr==NULL) {
+ return NULL ;
+ }
memcpy(newptr, ptr, size);
free(ptr);
return newptr ;
}
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Duplicate a string
+ @param s String to duplicate
+ @return Pointer to a newly allocated string, to be freed with free()
+
+ This is a replacement for strdup(). This implementation is provided
+ for systems that do not have it.
+ */
+/*--------------------------------------------------------------------------*/
+char * xstrdup(const char * s)
+{
+ char * t ;
+ size_t len ;
+ if (!s)
+ return NULL ;
+
+ len = strlen(s) + 1 ;
+ t = malloc(len) ;
+ if (t) {
+ memcpy(t, s, len) ;
+ }
+ return t ;
+}
/*---------------------------------------------------------------------------
- Function codes
+ Function codes
---------------------------------------------------------------------------*/
-
/*-------------------------------------------------------------------------*/
/**
- @brief Compute the hash key for a string.
- @param key Character string to use for key.
- @return 1 unsigned int on at least 32 bits.
+ @brief Compute the hash key for a string.
+ @param key Character string to use for key.
+ @return 1 unsigned int on at least 32 bits.
This hash function has been taken from an Article in Dr Dobbs Journal.
This is normally a collision-free function, distributing keys evenly.
@@ -75,93 +88,87 @@ static void * mem_double(void * ptr, int size)
by comparing the key itself in last resort.
*/
/*--------------------------------------------------------------------------*/
-
-unsigned dictionary_hash(char * key)
+unsigned dictionary_hash(const char * key)
{
- int len ;
- unsigned hash ;
- int i ;
-
- len = strlen(key);
- for (hash=0, i=0 ; i<len ; i++) {
- hash += (unsigned)key[i] ;
- hash += (hash<<10);
- hash ^= (hash>>6) ;
- }
- hash += (hash <<3);
- hash ^= (hash >>11);
- hash += (hash <<15);
- return hash ;
+ size_t len ;
+ unsigned hash ;
+ size_t i ;
+
+ len = strlen(key);
+ for (hash=0, i=0 ; i<len ; i++) {
+ hash += (unsigned)key[i] ;
+ hash += (hash<<10);
+ hash ^= (hash>>6) ;
+ }
+ hash += (hash <<3);
+ hash ^= (hash >>11);
+ hash += (hash <<15);
+ return hash ;
}
-
/*-------------------------------------------------------------------------*/
/**
- @brief Create a new dictionary object.
- @param size Optional initial size of the dictionary.
- @return 1 newly allocated dictionary objet.
+ @brief Create a new dictionary object.
+ @param size Optional initial size of the dictionary.
+ @return 1 newly allocated dictionary objet.
This function allocates a new dictionary object of given size and returns
it. If you do not know in advance (roughly) the number of entries in the
dictionary, give size=0.
*/
/*--------------------------------------------------------------------------*/
-
-dictionary * dictionary_new(int size)
+dictionary * dictionary_new(size_t size)
{
- dictionary * d ;
-
- /* If no size was specified, allocate space for DICTMINSZ */
- if (size<DICTMINSZ) size=DICTMINSZ ;
-
- if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
- return NULL;
- }
- d->size = size ;
- d->val = (char **)calloc(size, sizeof(char*));
- d->key = (char **)calloc(size, sizeof(char*));
- d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
- return d ;
-}
+ dictionary * d ;
+ /* If no size was specified, allocate space for DICTMINSZ */
+ if (size<DICTMINSZ) size=DICTMINSZ ;
+
+ d = calloc(1, sizeof *d) ;
+
+ if (d) {
+ d->size = size ;
+ d->val = calloc(size, sizeof *d->val);
+ d->key = calloc(size, sizeof *d->key);
+ d->hash = calloc(size, sizeof *d->hash);
+ }
+ return d ;
+}
/*-------------------------------------------------------------------------*/
/**
- @brief Delete a dictionary object
- @param d dictionary object to deallocate.
- @return void
+ @brief Delete a dictionary object
+ @param d dictionary object to deallocate.
+ @return void
Deallocate a dictionary object and all memory associated to it.
*/
/*--------------------------------------------------------------------------*/
-
void dictionary_del(dictionary * d)
{
- int i ;
-
- if (d==NULL) return ;
- for (i=0 ; i<d->size ; i++) {
- if (d->key[i]!=NULL)
- free(d->key[i]);
- if (d->val[i]!=NULL)
- free(d->val[i]);
- }
- free(d->val);
- free(d->key);
- free(d->hash);
- free(d);
- return ;
-}
-
+ size_t i ;
+ if (d==NULL) return ;
+ for (i=0 ; i<d->size ; i++) {
+ if (d->key[i]!=NULL)
+ free(d->key[i]);
+ if (d->val[i]!=NULL)
+ free(d->val[i]);
+ }
+ free(d->val);
+ free(d->key);
+ free(d->hash);
+ free(d);
+ return ;
+}
/*-------------------------------------------------------------------------*/
/**
- @brief Get a value from a dictionary.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
+ @brief Get a value from a dictionary.
+ @param d dictionary object to search.
+ @param key Key to look for in the dictionary.
@param def Default value to return if key not found.
- @return 1 pointer to internally allocated character string.
+ @return 1 pointer to internally allocated character string.
This function locates a key in a dictionary and returns a pointer to its
value, or the passed 'def' pointer if no such key can be found in
@@ -169,106 +176,33 @@ void dictionary_del(dictionary * d)
dictionary object, you should not try to free it or modify it.
*/
/*--------------------------------------------------------------------------*/
-char * dictionary_get(dictionary * d, char * key, char * def)
+char * dictionary_get(dictionary * d, const char * key, char * def)
{
- unsigned hash ;
- int i ;
+ unsigned hash ;
+ size_t i ;
- hash = dictionary_hash(key);
- for (i=0 ; i<d->size ; i++) {
- if (d->key==NULL)
+ hash = dictionary_hash(key);
+ for (i=0 ; i<d->size ; i++) {
+ if (d->key[i]==NULL)
continue ;
/* Compare hash */
- if (hash==d->hash[i]) {
+ if (hash==d->hash[i]) {
/* Compare string, to avoid hash collisions */
if (!strcmp(key, d->key[i])) {
- return d->val[i] ;
- }
- }
- }
- return def ;
-}
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Get a value from a dictionary, as a char.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
- @param def Default value for the key if not found.
- @return char
-
- This function locates a key in a dictionary using dictionary_get,
- and returns the first char of the found string.
- */
-/*--------------------------------------------------------------------------*/
-char dictionary_getchar(dictionary * d, char * key, char def)
-{
- char * v ;
-
- if ((v=dictionary_get(d,key,DICT_INVALID_KEY))==DICT_INVALID_KEY) {
- return def ;
- } else {
- return v[0] ;
- }
-}
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Get a value from a dictionary, as an int.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
- @param def Default value for the key if not found.
- @return int
-
- This function locates a key in a dictionary using dictionary_get,
- and applies atoi on it to return an int. If the value cannot be found
- in the dictionary, the default is returned.
- */
-/*--------------------------------------------------------------------------*/
-int dictionary_getint(dictionary * d, char * key, int def)
-{
- char * v ;
-
- if ((v=dictionary_get(d,key,DICT_INVALID_KEY))==DICT_INVALID_KEY) {
- return def ;
- } else {
- return atoi(v);
- }
-}
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Get a value from a dictionary, as a double.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
- @param def Default value for the key if not found.
- @return double
-
- This function locates a key in a dictionary using dictionary_get,
- and applies atof on it to return a double. If the value cannot be found
- in the dictionary, the default is returned.
- */
-/*--------------------------------------------------------------------------*/
-double dictionary_getdouble(dictionary * d, char * key, double def)
-{
- char * v ;
-
- if ((v=dictionary_get(d,key,DICT_INVALID_KEY))==DICT_INVALID_KEY) {
- return def ;
- } else {
- return atof(v);
- }
+ return d->val[i] ;
+ }
+ }
+ }
+ return def ;
}
-
/*-------------------------------------------------------------------------*/
/**
- @brief Set a value in a dictionary.
- @param d dictionary object to modify.
- @param key Key to modify or add.
- @param val Value to add.
- @return void
+ @brief Set a value in a dictionary.
+ @param d dictionary object to modify.
+ @param key Key to modify or add.
+ @param val Value to add.
+ @return int 0 if Ok, anything else otherwise
If the given key is found in the dictionary, the associated value is
replaced by the provided one. If the key cannot be found in the
@@ -284,96 +218,99 @@ double dictionary_getdouble(dictionary * d, char * key, double def)
content to NULL is equivalent to deleting the variable from the
dictionary. It is not possible (in this implementation) to have a key in
the dictionary without value.
+
+ This function returns non-zero in case of failure.
*/
/*--------------------------------------------------------------------------*/
-
-void dictionary_set(dictionary * d, char * key, char * val)
+int dictionary_set(dictionary * d, const char * key, const char * val)
{
- int i ;
- unsigned hash ;
-
- if (d==NULL || key==NULL) return ;
-
- /* Compute hash for this key */
- hash = dictionary_hash(key) ;
- /* Find if value is already in blackboard */
- if (d->n>0) {
- for (i=0 ; i<d->size ; i++) {
+ size_t i ;
+ unsigned hash ;
+
+ if (d==NULL || key==NULL) return -1 ;
+
+ /* Compute hash for this key */
+ hash = dictionary_hash(key) ;
+ /* Find if value is already in dictionary */
+ if (d->n>0) {
+ for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
- if (hash==d->hash[i]) { /* Same hash value */
- if (!strcmp(key, d->key[i])) { /* Same key */
- /* Found a value: modify and return */
- if (d->val[i]!=NULL)
- free(d->val[i]);
- d->val[i] = val ? strdup(val) : NULL ;
+ if (hash==d->hash[i]) { /* Same hash value */
+ if (!strcmp(key, d->key[i])) { /* Same key */
+ /* Found a value: modify and return */
+ if (d->val[i]!=NULL)
+ free(d->val[i]);
+ d->val[i] = val ? xstrdup(val) : NULL ;
/* Value has been modified: return */
- return ;
- }
- }
- }
- }
- /* Add a new value */
- /* See if dictionary needs to grow */
- if (d->n==d->size) {
-
- /* Reached maximum size: reallocate blackboard */
- d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ;
- d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ;
- d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
-
- /* Double size */
- d->size *= 2 ;
- }
-
- /* Insert key in the first empty slot */
- for (i=0 ; i<d->size ; i++) {
- if (d->key[i]==NULL) {
- /* Add key here */
- break ;
+ return 0 ;
+ }
+ }
+ }
+ }
+ /* Add a new value */
+ /* See if dictionary needs to grow */
+ if (d->n==d->size) {
+
+ /* Reached maximum size: reallocate dictionary */
+ d->val = mem_double(d->val, d->size * sizeof *d->val) ;
+ d->key = mem_double(d->key, d->size * sizeof *d->key) ;
+ d->hash = mem_double(d->hash, d->size * sizeof *d->hash) ;
+ if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) {
+ /* Cannot grow dictionary */
+ return -1 ;
}
+ /* Double size */
+ d->size *= 2 ;
}
- /* Copy key */
- d->key[i] = strdup(key);
- d->val[i] = val ? strdup(val) : NULL ;
- d->hash[i] = hash;
- d->n ++ ;
- return ;
+
+ /* Insert key in the first empty slot. Start at d->n and wrap at
+ d->size. Because d->n < d->size this will necessarily
+ terminate. */
+ for (i=d->n ; d->key[i] ; ) {
+ if(++i == d->size) i = 0;
+ }
+ /* Copy key */
+ d->key[i] = xstrdup(key);
+ d->val[i] = val ? xstrdup(val) : NULL ;
+ d->hash[i] = hash;
+ d->n ++ ;
+ return 0 ;
}
/*-------------------------------------------------------------------------*/
/**
- @brief Delete a key in a dictionary
- @param d dictionary object to modify.
- @param key Key to remove.
+ @brief Delete a key in a dictionary
+ @param d dictionary object to modify.
+ @param key Key to remove.
@return void
This function deletes a key in a dictionary. Nothing is done if the
key cannot be found.
*/
/*--------------------------------------------------------------------------*/
-void dictionary_unset(dictionary * d, char * key)
+void dictionary_unset(dictionary * d, const char * key)
{
- unsigned hash ;
- int i ;
+ unsigned hash ;
+ size_t i ;
- if (key == NULL) {
- return;
- }
+ if (key == NULL) {
+ return;
+ }
- hash = dictionary_hash(key);
- for (i=0 ; i<d->size ; i++) {
+ hash = dictionary_hash(key);
+ for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
/* Compare hash */
- if (hash==d->hash[i]) {
+ if (hash==d->hash[i]) {
/* Compare string, to avoid hash collisions */
if (!strcmp(key, d->key[i])) {
/* Found key */
break ;
- }
- }
- }
+ }
+ }
+ }
if (i>=d->size)
/* Key not found */
return ;
@@ -389,126 +326,77 @@ void dictionary_unset(dictionary * d, char * key)
return ;
}
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Set a key in a dictionary, providing an int.
- @param d Dictionary to update.
- @param key Key to modify or add
- @param val Integer value to store (will be stored as a string).
- @return void
-
- This helper function calls dictionary_set() with the provided integer
- converted to a string using %d.
- */
-/*--------------------------------------------------------------------------*/
-
-
-void dictionary_setint(dictionary * d, char * key, int val)
-{
- char sval[MAXVALSZ];
- sprintf(sval, "%d", val);
- dictionary_set(d, key, sval);
-}
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Set a key in a dictionary, providing a double.
- @param d Dictionary to update.
- @param key Key to modify or add
- @param val Double value to store (will be stored as a string).
- @return void
-
- This helper function calls dictionary_set() with the provided double
- converted to a string using %g.
- */
-/*--------------------------------------------------------------------------*/
-
-
-void dictionary_setdouble(dictionary * d, char * key, double val)
-{
- char sval[MAXVALSZ];
- sprintf(sval, "%g", val);
- dictionary_set(d, key, sval);
-}
-
-
-
/*-------------------------------------------------------------------------*/
/**
- @brief Dump a dictionary to an opened file pointer.
- @param d Dictionary to dump
- @param f Opened file pointer.
- @return void
+ @brief Dump a dictionary to an opened file pointer.
+ @param d Dictionary to dump
+ @param f Opened file pointer.
+ @return void
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
output file pointers.
*/
/*--------------------------------------------------------------------------*/
-
void dictionary_dump(dictionary * d, FILE * out)
{
- int i ;
-
- if (d==NULL || out==NULL) return ;
- if (d->n<1) {
- fprintf(out, "empty dictionary\n");
- return ;
- }
- for (i=0 ; i<d->size ; i++) {
+ size_t i ;
+
+ if (d==NULL || out==NULL) return ;
+ if (d->n<1) {
+ fprintf(out, "empty dictionary\n");
+ return ;
+ }
+ for (i=0 ; i<d->size ; i++) {
if (d->key[i]) {
fprintf(out, "%20s\t[%s]\n",
d->key[i],
d->val[i] ? d->val[i] : "UNDEF");
}
- }
- return ;
+ }
+ return ;
}
-
-/* Example code */
+/* Test code */
#ifdef TESTDIC
#define NVALS 20000
int main(int argc, char *argv[])
{
- dictionary * d ;
- char * val ;
- int i ;
- char cval[90] ;
-
- /* allocate blackboard */
- printf("allocating...\n");
- d = dictionary_new(0);
-
- /* Set values in blackboard */
- printf("setting %d values...\n", NVALS);
- for (i=0 ; i<NVALS ; i++) {
- sprintf(cval, "%04d", i);
- dictionary_set(d, cval, "salut");
- }
- printf("getting %d values...\n", NVALS);
- for (i=0 ; i<NVALS ; i++) {
- sprintf(cval, "%04d", i);
- val = dictionary_get(d, cval, DICT_INVALID_KEY);
- if (val==DICT_INVALID_KEY) {
- printf("cannot get value for key [%s]\n", cval);
- }
- }
+ dictionary * d ;
+ char * val ;
+ int i ;
+ char cval[90] ;
+
+ /* Allocate dictionary */
+ printf("allocating...\n");
+ d = dictionary_new(0);
+
+ /* Set values in dictionary */
+ printf("setting %d values...\n", NVALS);
+ for (i=0 ; i<NVALS ; i++) {
+ sprintf(cval, "%04d", i);
+ dictionary_set(d, cval, "salut");
+ }
+ printf("getting %d values...\n", NVALS);
+ for (i=0 ; i<NVALS ; i++) {
+ sprintf(cval, "%04d", i);
+ val = dictionary_get(d, cval, DICT_INVALID_KEY);
+ if (val==DICT_INVALID_KEY) {
+ printf("cannot get value for key [%s]\n", cval);
+ }
+ }
printf("unsetting %d values...\n", NVALS);
- for (i=0 ; i<NVALS ; i++) {
- sprintf(cval, "%04d", i);
- dictionary_unset(d, cval);
- }
+ for (i=0 ; i<NVALS ; i++) {
+ sprintf(cval, "%04d", i);
+ dictionary_unset(d, cval);
+ }
if (d->n != 0) {
printf("error deleting values\n");
}
-
- printf("deallocating...\n");
- dictionary_del(d);
- return 0 ;
+ printf("deallocating...\n");
+ dictionary_del(d);
+ return 0 ;
}
#endif
/* vim: set ts=4 et sw=4 tw=75 */
diff --git a/src/dictionary.h b/src/dictionary.h
index b332680..965dfd6 100644
--- a/src/dictionary.h
+++ b/src/dictionary.h
@@ -3,8 +3,6 @@
/**
@file dictionary.h
@author N. Devillard
- @date Aug 2000
- @version $Revision: 1.11 $
@brief Implements a dictionary for string variables.
This module implements a simple dictionary object, i.e. a list
@@ -13,18 +11,11 @@
*/
/*--------------------------------------------------------------------------*/
-/*
- $Id: dictionary.h,v 1.11 2002-06-17 09:30:46 ndevilla Exp $
- $Author: ndevilla $
- $Date: 2002-06-17 09:30:46 $
- $Revision: 1.11 $
-*/
-
#ifndef _DICTIONARY_H_
#define _DICTIONARY_H_
/*---------------------------------------------------------------------------
- Includes
+ Includes
---------------------------------------------------------------------------*/
#include <stdio.h>
@@ -32,14 +23,18 @@
#include <string.h>
#include <unistd.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*---------------------------------------------------------------------------
- New types
+ New types
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
- @brief Dictionary object
+ @brief Dictionary object
This object contains a list of string/string associations. Each
association is identified by a unique string key. Looking up values
@@ -48,16 +43,16 @@
*/
/*-------------------------------------------------------------------------*/
typedef struct _dictionary_ {
- int n ; /** Number of entries in dictionary */
- int size ; /** Storage size */
- char ** val ; /** List of string values */
- char ** key ; /** List of string keys */
- unsigned * hash ; /** List of hash values for keys */
+ int n ; /** Number of entries in dictionary */
+ int size ; /** Storage size */
+ char ** val ; /** List of string values */
+ char ** key ; /** List of string keys */
+ unsigned * hash ; /** List of hash values for keys */
} dictionary ;
/*---------------------------------------------------------------------------
- Function prototypes
+ Function prototypes
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
@@ -72,7 +67,7 @@ typedef struct _dictionary_ {
by comparing the key itself in last resort.
*/
/*--------------------------------------------------------------------------*/
-unsigned dictionary_hash(char * key);
+unsigned dictionary_hash(const char * key);
/*-------------------------------------------------------------------------*/
/**
@@ -85,7 +80,7 @@ unsigned dictionary_hash(char * key);
dictionary, give size=0.
*/
/*--------------------------------------------------------------------------*/
-dictionary * dictionary_new(int size);
+dictionary * dictionary_new(size_t size);
/*-------------------------------------------------------------------------*/
/**
@@ -112,52 +107,8 @@ void dictionary_del(dictionary * vd);
dictionary object, you should not try to free it or modify it.
*/
/*--------------------------------------------------------------------------*/
-char * dictionary_get(dictionary * d, char * key, char * def);
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Get a value from a dictionary, as a char.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
- @param def Default value for the key if not found.
- @return char
-
- This function locates a key in a dictionary using dictionary_get,
- and returns the first char of the found string.
- */
-/*--------------------------------------------------------------------------*/
-char dictionary_getchar(dictionary * d, char * key, char def) ;
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Get a value from a dictionary, as an int.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
- @param def Default value for the key if not found.
- @return int
-
- This function locates a key in a dictionary using dictionary_get,
- and applies atoi on it to return an int. If the value cannot be found
- in the dictionary, the default is returned.
- */
-/*--------------------------------------------------------------------------*/
-int dictionary_getint(dictionary * d, char * key, int def);
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Get a value from a dictionary, as a double.
- @param d dictionary object to search.
- @param key Key to look for in the dictionary.
- @param def Default value for the key if not found.
- @return double
+char * dictionary_get(dictionary * d, const char * key, char * def);
- This function locates a key in a dictionary using dictionary_get,
- and applies atof on it to return a double. If the value cannot be found
- in the dictionary, the default is returned.
- */
-/*--------------------------------------------------------------------------*/
-double dictionary_getdouble(dictionary * d, char * key, double def);
/*-------------------------------------------------------------------------*/
/**
@@ -165,7 +116,7 @@ double dictionary_getdouble(dictionary * d, char * key, double def);
@param d dictionary object to modify.
@param key Key to modify or add.
@param val Value to add.
- @return void
+ @return int 0 if Ok, anything else otherwise
If the given key is found in the dictionary, the associated value is
replaced by the provided one. If the key cannot be found in the
@@ -181,9 +132,11 @@ double dictionary_getdouble(dictionary * d, char * key, double def);
content to NULL is equivalent to deleting the variable from the
dictionary. It is not possible (in this implementation) to have a key in
the dictionary without value.
+
+ This function returns non-zero in case of failure.
*/
/*--------------------------------------------------------------------------*/
-void dictionary_set(dictionary * vd, char * key, char * val);
+int dictionary_set(dictionary * vd, const char * key, const char * val);
/*-------------------------------------------------------------------------*/
/**
@@ -196,36 +149,8 @@ void dictionary_set(dictionary * vd, char * key, char * val);
key cannot be found.
*/
/*--------------------------------------------------------------------------*/
-void dictionary_unset(dictionary * d, char * key);
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Set a key in a dictionary, providing an int.
- @param d Dictionary to update.
- @param key Key to modify or add
- @param val Integer value to store (will be stored as a string).
- @return void
-
- This helper function calls dictionary_set() with the provided integer
- converted to a string using %d.
- */
-/*--------------------------------------------------------------------------*/
-void dictionary_setint(dictionary * d, char * key, int val);
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Set a key in a dictionary, providing a double.
- @param d Dictionary to update.
- @param key Key to modify or add
- @param val Double value to store (will be stored as a string).
- @return void
+void dictionary_unset(dictionary * d, const char * key);
- This helper function calls dictionary_set() with the provided double
- converted to a string using %g.
- */
-/*--------------------------------------------------------------------------*/
-void dictionary_setdouble(dictionary * d, char * key, double val);
/*-------------------------------------------------------------------------*/
/**
@@ -241,4 +166,20 @@ void dictionary_setdouble(dictionary * d, char * key, double val);
/*--------------------------------------------------------------------------*/
void dictionary_dump(dictionary * d, FILE * out);
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Duplicate a string
+ @param s String to duplicate
+ @return Pointer to a newly allocated string, to be freed with free()
+
+ This is a replacement for strdup(). This implementation is provided
+ for systems that do not have it.
+ */
+/*--------------------------------------------------------------------------*/
+char * xstrdup(const char * s);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/src/iniparser.c b/src/iniparser.c
index 0934087..9f3e973 100644
--- a/src/iniparser.c
+++ b/src/iniparser.c
@@ -3,54 +3,81 @@
/**
@file iniparser.c
@author N. Devillard
- @date Mar 2000
- @version $Revision: 2.17 $
@brief Parser for ini files.
*/
/*--------------------------------------------------------------------------*/
-
-/*
- $Id: iniparser.c,v 2.17 2007-05-27 13:03:43 ndevilla Exp $
- $Author: ndevilla $
- $Date: 2007-05-27 13:03:43 $
- $Revision: 2.17 $
-*/
-
-/*---------------------------------------------------------------------------
- Includes
- ---------------------------------------------------------------------------*/
-
+/*---------------------------- Includes ------------------------------------*/
+#include <ctype.h>
#include "iniparser.h"
-#include "strlib.h"
-#define ASCIILINESZ 1024
+/*---------------------------- Defines -------------------------------------*/
+#define ASCIILINESZ (1024)
#define INI_INVALID_KEY ((char*)-1)
/*---------------------------------------------------------------------------
Private to this module
---------------------------------------------------------------------------*/
+/**
+ * This enum stores the status for each parsed line (internal use only).
+ */
+typedef enum _line_status_ {
+ LINE_UNPROCESSED,
+ LINE_ERROR,
+ LINE_EMPTY,
+ LINE_COMMENT,
+ LINE_SECTION,
+ LINE_VALUE
+} line_status ;
+
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Convert a string to lowercase.
+ @param s String to convert.
-/* Private: add an entry to the dictionary */
-static void iniparser_add_entry(
- dictionary * d,
- char * sec,
- char * key,
- char * val)
+ This function modifies the string passed, the modified string
+ contains a lowercased version of the input string.
+ */
+/*--------------------------------------------------------------------------*/
+
+static void strlwc(char * s)
{
- char longkey[2*ASCIILINESZ+1];
+ int i ;
- /* Make a key as section:keyword */
- if (key!=NULL) {
- sprintf(longkey, "%s:%s", sec, key);
- } else {
- strcpy(longkey, sec);
+ if (s==NULL) return;
+ i=0 ;
+ while (s[i]) {
+ s[i] = (char)tolower((int)s[i]);
+ i++ ;
}
-
- /* Add (key,val) to dictionary */
- dictionary_set(d, longkey, val);
- return ;
}
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Remove blanks at the beginning and the end of a string.
+ @param s String to parse.
+
+ This function modifies the input string and returns a modified string
+ which is identical to the input string, except that all blank
+ characters at the end and the beg. of the string have been removed.
+ */
+/*--------------------------------------------------------------------------*/
+void strstrip(char * s)
+{
+ char *last = s + strlen(s);
+ char *dest = s;
+
+ if (s==NULL) return ;
+
+ while (isspace((int)*s) && *s) s++;
+ while (last > s) {
+ if (!isspace((int)*(last-1)))
+ break ;
+ last -- ;
+ }
+ *last = (char)0;
+
+ memmove(dest,s,last - s + 1);
+}
/*-------------------------------------------------------------------------*/
/**
@@ -70,7 +97,6 @@ static void iniparser_add_entry(
This function returns -1 in case of error.
*/
/*--------------------------------------------------------------------------*/
-
int iniparser_getnsec(dictionary * d)
{
int i ;
@@ -88,7 +114,6 @@ int iniparser_getnsec(dictionary * d)
return nsec ;
}
-
/*-------------------------------------------------------------------------*/
/**
@brief Get name for section n in a dictionary.
@@ -103,7 +128,6 @@ int iniparser_getnsec(dictionary * d)
This function returns NULL in case of error.
*/
/*--------------------------------------------------------------------------*/
-
char * iniparser_getsecname(dictionary * d, int n)
{
int i ;
@@ -126,7 +150,6 @@ char * iniparser_getsecname(dictionary * d, int n)
return d->key[i] ;
}
-
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
@@ -168,14 +191,11 @@ void iniparser_dump(dictionary * d, FILE * f)
It is Ok to specify @c stderr or @c stdout as output files.
*/
/*--------------------------------------------------------------------------*/
-
void iniparser_dump_ini(dictionary * d, FILE * f)
{
- int i, j ;
- char keym[ASCIILINESZ+1];
+ int i ;
int nsec ;
char * secname ;
- int seclen ;
if (d==NULL || f==NULL) return ;
@@ -191,50 +211,136 @@ void iniparser_dump_ini(dictionary * d, FILE * f)
}
for (i=0 ; i<nsec ; i++) {
secname = iniparser_getsecname(d, i) ;
- seclen = (int)strlen(secname);
- fprintf(f, "\n[%s]\n", secname);
- sprintf(keym, "%s:", secname);
- for (j=0 ; j<d->size ; j++) {
- if (d->key[j]==NULL)
- continue ;
- if (!strncmp(d->key[j], keym, seclen+1)) {
- fprintf(f,
- "%-30s = %s\n",
- d->key[j]+seclen+1,
- d->val[j] ? d->val[j] : "");
- }
+ iniparser_dumpsection_ini(d, secname, f) ;
+ }
+ fprintf(f, "\n");
+ return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Save a dictionary section to a loadable ini file
+ @param d Dictionary to dump
+ @param s Section name of dictionary to dump
+ @param f Opened file pointer to dump to
+ @return void
+
+ This function dumps a given section of a given dictionary into a loadable ini
+ file. It is Ok to specify @c stderr or @c stdout as output files.
+ */
+/*--------------------------------------------------------------------------*/
+void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f)
+{
+ int j ;
+ char *keym;
+ int secsize ;
+
+ if (d==NULL || f==NULL) return ;
+ if (! iniparser_find_entry(d, s)) return ;
+
+ fprintf(f, "\n[%s]\n", s);
+ secsize = (int)strlen(s) + 2;
+ keym = malloc(secsize);
+ snprintf(keym, secsize, "%s:", s);
+ for (j=0 ; j<d->size ; j++) {
+ if (d->key[j]==NULL)
+ continue ;
+ if (!strncmp(d->key[j], keym, secsize-1)) {
+ fprintf(f,
+ "%-30s = %s\n",
+ d->key[j]+secsize-1,
+ d->val[j] ? d->val[j] : "");
}
}
fprintf(f, "\n");
+ free(keym);
return ;
}
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Get the number of keys in a section of a dictionary.
+ @param d Dictionary to examine
+ @param s Section name of dictionary to examine
+ @return Number of keys in section
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getsecnkeys(dictionary * d, char * s)
+{
+ int secsize, nkeys ;
+ char *keym;
+ int j ;
+
+ nkeys = 0;
+ if (d==NULL) return nkeys;
+ if (! iniparser_find_entry(d, s)) return nkeys;
+ secsize = (int)strlen(s)+2;
+ keym = malloc(secsize);
+ snprintf(keym, secsize, "%s:", s);
+
+ for (j=0 ; j<d->size ; j++) {
+ if (d->key[j]==NULL)
+ continue ;
+ if (!strncmp(d->key[j], keym, secsize-1))
+ nkeys++;
+ }
+ free(keym);
+ return nkeys;
+
+}
/*-------------------------------------------------------------------------*/
/**
- @brief Get the string associated to a key, return NULL if not found
- @param d Dictionary to search
- @param key Key string to look for
- @return pointer to statically allocated character string, or NULL.
+ @brief Get the number of keys in a section of a dictionary.
+ @param d Dictionary to examine
+ @param s Section name of dictionary to examine
+ @return pointer to statically allocated character strings
- This function queries a dictionary for a key. A key as read from an
- ini file is given as "section:key". If the key cannot be found,
- NULL is returned.
- The returned char pointer is pointing to a string allocated in
- the dictionary, do not free or modify it.
+ This function queries a dictionary and finds all keys in a given section.
+ Each pointer in the returned char pointer-to-pointer is pointing to
+ a string allocated in the dictionary; do not free or modify them.
- This function is only provided for backwards compatibility with
- previous versions of iniparser. It is recommended to use
- iniparser_getstring() instead.
+ This function returns NULL in case of error.
*/
/*--------------------------------------------------------------------------*/
-char * iniparser_getstr(dictionary * d, const char * key)
+char ** iniparser_getseckeys(dictionary * d, char * s)
{
- return iniparser_getstring(d, key, NULL);
-}
+ char **keys;
+
+ int i, j ;
+ char *keym;
+ int secsize, nkeys ;
+
+ keys = NULL;
+
+ if (d==NULL) return keys;
+ if (! iniparser_find_entry(d, s)) return keys;
+
+ nkeys = iniparser_getsecnkeys(d, s);
+
+ keys = (char**) malloc(nkeys*sizeof(char*));
+
+ secsize = (int)strlen(s) + 2;
+ keym = malloc(secsize);
+ snprintf(keym, secsize, "%s:", s);
+
+ i = 0;
+
+ for (j=0 ; j<d->size ; j++) {
+ if (d->key[j]==NULL)
+ continue ;
+ if (!strncmp(d->key[j], keym, secsize-1)) {
+ keys[i] = d->key[j];
+ i++;
+ }
+ }
+
+ return keys;
+
+}
/*-------------------------------------------------------------------------*/
/**
@@ -259,16 +365,13 @@ char * iniparser_getstring(dictionary * d, const char * key, char * def)
if (d==NULL || key==NULL)
return def ;
- if (!(lc_key = strdup(strlwc(key)))) {
- return NULL;
- }
+ lc_key = xstrdup(key);
+ strlwc(lc_key);
sval = dictionary_get(d, lc_key, def);
free(lc_key);
return sval ;
}
-
-
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to an int
@@ -305,7 +408,6 @@ int iniparser_getint(dictionary * d, const char * key, int notfound)
return (int)strtol(str, NULL, 0);
}
-
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to a double
@@ -319,7 +421,7 @@ int iniparser_getint(dictionary * d, const char * key, int notfound)
the notfound value is returned.
*/
/*--------------------------------------------------------------------------*/
-double iniparser_getdouble(dictionary * d, char * key, double notfound)
+double iniparser_getdouble(dictionary * d, const char * key, double notfound)
{
char * str ;
@@ -328,8 +430,6 @@ double iniparser_getdouble(dictionary * d, char * key, double notfound)
return atof(str);
}
-
-
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to a boolean
@@ -379,7 +479,6 @@ int iniparser_getboolean(dictionary * d, const char * key, int notfound)
return ret;
}
-
/*-------------------------------------------------------------------------*/
/**
@brief Finds out if a given entry exists in a dictionary
@@ -392,10 +491,9 @@ int iniparser_getboolean(dictionary * d, const char * key, int notfound)
of querying for the presence of sections in a dictionary.
*/
/*--------------------------------------------------------------------------*/
-
int iniparser_find_entry(
dictionary * ini,
- char * entry
+ const char * entry
)
{
int found=0 ;
@@ -405,8 +503,6 @@ int iniparser_find_entry(
return found ;
}
-
-
/*-------------------------------------------------------------------------*/
/**
@brief Set an entry in a dictionary.
@@ -420,11 +516,14 @@ int iniparser_find_entry(
It is Ok to set val to NULL.
*/
/*--------------------------------------------------------------------------*/
-
-int iniparser_setstr(dictionary * ini, char * entry, char * val)
+int iniparser_set(dictionary * ini, const char * entry, const char * val)
{
- dictionary_set(ini, strlwc(entry), val);
- return 0 ;
+ int result = 0;
+ char *lc_entry = xstrdup(entry);
+ strlwc(lc_entry);
+ result = dictionary_set(ini, lc_entry, val) ;
+ free(lc_entry);
+ return result;
}
/*-------------------------------------------------------------------------*/
@@ -437,11 +536,139 @@ int iniparser_setstr(dictionary * ini, char * entry, char * val)
If the given entry can be found, it is deleted from the dictionary.
*/
/*--------------------------------------------------------------------------*/
-void iniparser_unset(dictionary * ini, char * entry)
+void iniparser_unset(dictionary * ini, const char * entry)
{
- dictionary_unset(ini, strlwc(entry));
+ char* lc_entry = xstrdup(entry);
+ strlwc(lc_entry);
+ dictionary_unset(ini, lc_entry);
+ free(lc_entry);
}
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Load a single line from an INI file
+ @param input_line Input line, may be concatenated multi-line input
+ @param section Output space to store section
+ @param key Output space to store key
+ @param value Output space to store value
+ @return line_status value
+ */
+/*--------------------------------------------------------------------------*/
+static line_status iniparser_line(
+ int line_size,
+ const char * input_line,
+ char ** section_out,
+ char ** key_out,
+ char ** value_out)
+{
+ line_status sta ;
+ int len = line_size-1;
+ char * line = malloc(line_size);
+ char * key = NULL;
+ char * value = NULL;
+ char * equals = NULL;
+
+ if (!line) {
+ fprintf(stderr, "iniparser: memory alloc error\n");
+ return LINE_ERROR;
+ }
+
+ *line = 0;
+
+
+ strcpy(line, input_line);
+ strstrip(line);
+ len = (int)strlen(line);
+
+ /* only allocate necessary space for key & val */
+ equals = strchr(line,'=');
+ if (equals) {
+ value = malloc((len + line) - equals + 1);
+ key = malloc(equals - line + 1);
+ *value = 0;
+ } else {
+ key = malloc(line_size + 1);
+ }
+
+ if (!key || (equals && !value)) {
+ fprintf(stderr, "iniparser: memory alloc error\n");
+ return LINE_ERROR;
+ }
+
+ *key = 0;
+
+ sta = LINE_UNPROCESSED ;
+ if (len<1) {
+ /* Empty line */
+ sta = LINE_EMPTY ;
+ } else if (line[0]=='#' || line[0]==';') {
+ /* Comment line */
+ sta = LINE_COMMENT ;
+ } else if (line[0]=='[' && line[len-1]==']') {
+ /* Section name */
+ sscanf(line, "[%[^]]", key);
+ strstrip(key);
+ strlwc(key);
+ sta = LINE_SECTION ;
+ *section_out=key;
+ /* don't free key's memory */
+ key = NULL;
+ } else if (equals && (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
+ || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2
+ || sscanf (line, "%[^=] = %[^;#]", key, value) == 2)) {
+ /* Usual key=value, with or without comments */
+ strstrip(key);
+ strlwc(key);
+ strstrip(value);
+ /*
+ * sscanf cannot handle '' or "" as empty values
+ * this is done here
+ */
+ if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
+ value[0]=0 ;
+ }
+ *key_out = key;
+ *value_out = value;
+ key = NULL;
+ value = NULL;
+ sta = LINE_VALUE ;
+ } else if (equals && (sscanf(line, "%[^=] = %[;#]", key, value)==2
+ || sscanf(line, "%[^=] %[=]", key, value) == 2)) {
+ /*
+ * Special cases:
+ * key=
+ * key=;
+ * key=#
+ */
+ strstrip(key);
+ strlwc(key);
+ value[0]=0 ;
+ *key_out = key;
+ *value_out = value;
+
+ /* don't free out params key or val's memory */
+ key = NULL;
+ value = NULL;
+ sta = LINE_VALUE ;
+ } else {
+ /* Generate syntax error */
+ sta = LINE_ERROR ;
+ }
+
+ if (line) {
+ free(line);
+ line = NULL;
+ }
+ if (key) {
+ free(key);
+ key = NULL;
+ }
+ if (value) {
+ free(value);
+ value= NULL;
+ }
+ return sta ;
+}
/*-------------------------------------------------------------------------*/
/**
@@ -457,65 +684,196 @@ void iniparser_unset(dictionary * ini, char * entry)
The returned dictionary must be freed using iniparser_freedict().
*/
/*--------------------------------------------------------------------------*/
-
dictionary * iniparser_load(const char * ininame)
{
- dictionary * d ;
- char lin[ASCIILINESZ+1];
- char sec[ASCIILINESZ+1];
- char key[ASCIILINESZ+1];
- char val[ASCIILINESZ+1];
- char * where ;
- FILE * ini ;
- int lineno ;
-
- if ((ini=fopen(ininame, "r"))==NULL) {
+ FILE * in ;
+
+ char line [ASCIILINESZ+1] ;
+ char *section = xstrdup("");
+ char *current_section = NULL;
+ char *key = NULL;
+ char *val = NULL;
+ char* full_line = NULL;
+ char* prev_line = NULL;
+
+ int len ;
+ int lineno=0 ;
+ int errs=0;
+ int seckey_size=0;
+
+ dictionary * dict ;
+
+ if ((in=fopen(ininame, "r"))==NULL) {
+ fprintf(stderr, "iniparser: cannot open %s\n", ininame);
return NULL ;
}
- sec[0]=0;
-
- /*
- * Initialize a new dictionary entry
- */
- if (!(d = dictionary_new(0))) {
- fclose(ini);
- return NULL;
+ dict = dictionary_new(0) ;
+ if (!dict) {
+ fclose(in);
+ return NULL ;
}
- lineno = 0 ;
- while (fgets(lin, ASCIILINESZ, ini)!=NULL) {
+
+ memset(line, 0, ASCIILINESZ);
+
+ while (fgets(line, ASCIILINESZ, in)!=NULL) {
+ int prev_line_len = 0;
+ int multi_line = 0;
+ int total_size = 0;
+
+ if (key) {
+ free(key);
+ key = NULL;
+ }
+ if (val) {
+ free(val);
+ val = NULL;
+ }
+
+
lineno++ ;
- where = strskp(lin); /* Skip leading spaces */
- if (*where==';' || *where=='#' || *where==0)
- continue ; /* Comment lines */
- else {
- if (sscanf(where, "[%[^]]", sec)==1) {
- /* Valid section name */
- strcpy(sec, strlwc(sec));
- iniparser_add_entry(d, sec, NULL, NULL);
- } else if (sscanf (where, "%[^=] = \"%[^\"]\"", key, val) == 2
- || sscanf (where, "%[^=] = '%[^\']'", key, val) == 2
- || sscanf (where, "%[^=] = %[^;#]", key, val) == 2) {
- strcpy(key, strlwc(strcrop(key)));
- /*
- * sscanf cannot handle "" or '' as empty value,
- * this is done here
- */
- if (!strcmp(val, "\"\"") || !strcmp(val, "''")) {
- val[0] = (char)0;
- } else {
- strcpy(val, strcrop(val));
+ len = (int)strlen(line)-1;
+ if (len==0)
+ continue;
+ /* Safety check against buffer overflows */
+ if (line[len]!='\n' && !feof(in)) {
+ fprintf(stderr,
+ "iniparser: input line too long in %s (%d)\n",
+ ininame,
+ lineno);
+ errs++;
+ goto out;
+ }
+ /* Get rid of \n and spaces at end of line */
+ while ((len>=0) &&
+ ((line[len]=='\n') || (isspace(line[len])))) {
+ line[len]=0 ;
+ len-- ;
+ }
+
+ /* Detect multi-line */
+ if (line[len]=='\\') {
+ multi_line = 1;
+ }
+ if (multi_line) {
+ /* Multi-line value */
+ /* length without trailing '\' */
+ /* remove multi-line indicator before appending*/
+ line[len] = 0;
+ len--;
+ }
+
+ /*
+ * If processing a multi-line then append it the previous portion,
+ * at this point 'full_line' has the previously read portion of a
+ * multi-line line (or NULL)
+ */
+ prev_line = full_line;
+ prev_line_len=0;
+ if (prev_line) {
+ prev_line_len = strlen(prev_line);
+ }
+
+ /* len is not strlen(line) but strlen(line) -1 */
+ total_size = (len+1) + prev_line_len + 1;
+
+ full_line = malloc(total_size);
+ if (!full_line) {
+ fprintf(stderr,
+ "iniparser: out of mem\n");
+ errs++;
+ goto out;
+ }
+
+ memset(full_line,0,total_size);
+
+ if (prev_line) {
+ strcpy(full_line,prev_line);
+ }
+
+ strcpy(full_line+prev_line_len,line);
+ free(prev_line);
+ prev_line = NULL;
+
+ if (multi_line) {
+ continue ;
+ }
+
+ switch (iniparser_line(total_size, full_line, &current_section, &key, &val)) {
+ case LINE_EMPTY:
+ case LINE_COMMENT:
+ break ;
+
+ case LINE_SECTION:
+ if (section) {
+ free(section);
+ section=NULL;
+ }
+ errs = dictionary_set(dict, current_section, NULL);
+ section = current_section;
+ break ;
+
+ case LINE_VALUE:
+ {
+ char *seckey;
+ /* section + ':' + key + eos */
+ seckey_size = strlen(section) + strlen(key) +2;
+ seckey = malloc(seckey_size);
+ if (!seckey) {
+ errs++;
+ fprintf(stderr,
+ "iniparser: out of mem\n");
+ goto out;
}
- iniparser_add_entry(d, sec, key, val);
+ snprintf(seckey, seckey_size, "%s:%s", section, key);
+ errs = dictionary_set(dict, seckey, val) ;
+ free(seckey);
+ seckey = NULL;
}
+ break ;
+
+ case LINE_ERROR:
+ fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
+ ininame,
+ lineno);
+ fprintf(stderr, "-> %s\n", full_line);
+ errs++ ;
+ break;
+
+ default:
+ break ;
+ }
+ memset(line, 0, ASCIILINESZ);
+ if (full_line) {
+ free(full_line);
+ full_line = NULL;
+ }
+ if (errs<0) {
+ fprintf(stderr, "iniparser: memory allocation failure\n");
+ break ;
}
}
- fclose(ini);
- return d ;
+out:
+ if (errs) {
+ dictionary_del(dict);
+ dict = NULL ;
+ }
+ if (val) {
+ free(val);
+ val = NULL;
+ }
+ if (key) {
+ free(key);
+ key = NULL;
+ }
+ if (section) {
+ free(section);
+ section = NULL;
+ }
+ fclose(in);
+ return dict ;
}
-
-
/*-------------------------------------------------------------------------*/
/**
@brief Free all memory associated to an ini dictionary
@@ -527,7 +885,6 @@ dictionary * iniparser_load(const char * ininame)
gets out of the current context.
*/
/*--------------------------------------------------------------------------*/
-
void iniparser_freedict(dictionary * d)
{
dictionary_del(d);
diff --git a/src/iniparser.h b/src/iniparser.h
index 5bbd904..153ad07 100644
--- a/src/iniparser.h
+++ b/src/iniparser.h
@@ -3,24 +3,15 @@
/**
@file iniparser.h
@author N. Devillard
- @date Mar 2000
- @version $Revision: 1.23 $
@brief Parser for ini files.
*/
/*--------------------------------------------------------------------------*/
-/*
- $Id: iniparser.h,v 1.23 2006-09-27 11:03:35 ndevilla Exp $
- $Author: ndevilla $
- $Date: 2006-09-27 11:03:35 $
- $Revision: 1.23 $
-*/
-
#ifndef _INIPARSER_H_
#define _INIPARSER_H_
/*---------------------------------------------------------------------------
- Includes
+ Includes
---------------------------------------------------------------------------*/
#include <stdio.h>
@@ -36,6 +27,10 @@
#include "dictionary.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*-------------------------------------------------------------------------*/
/**
@brief Get number of sections in a dictionary
@@ -92,6 +87,21 @@ void iniparser_dump_ini(dictionary * d, FILE * f);
/*-------------------------------------------------------------------------*/
/**
+ @brief Save a dictionary section to a loadable ini file
+ @param d Dictionary to dump
+ @param s Section name of dictionary to dump
+ @param f Opened file pointer to dump to
+ @return void
+
+ This function dumps a given section of a given dictionary into a loadable ini
+ file. It is Ok to specify @c stderr or @c stdout as output files.
+ */
+/*--------------------------------------------------------------------------*/
+
+void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);
+
+/*-------------------------------------------------------------------------*/
+/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump.
@param f Opened file pointer to dump to.
@@ -107,24 +117,29 @@ void iniparser_dump(dictionary * d, FILE * f);
/*-------------------------------------------------------------------------*/
/**
- @brief Get the string associated to a key, return NULL if not found
- @param d Dictionary to search
- @param key Key string to look for
- @return pointer to statically allocated character string, or NULL.
+ @brief Get the number of keys in a section of a dictionary.
+ @param d Dictionary to examine
+ @param s Section name of dictionary to examine
+ @return Number of keys in section
+ */
+/*--------------------------------------------------------------------------*/
+int iniparser_getsecnkeys(dictionary * d, char * s);
- This function queries a dictionary for a key. A key as read from an
- ini file is given as "section:key". If the key cannot be found,
- NULL is returned.
- The returned char pointer is pointing to a string allocated in
- the dictionary, do not free or modify it.
+/*-------------------------------------------------------------------------*/
+/**
+ @brief Get the number of keys in a section of a dictionary.
+ @param d Dictionary to examine
+ @param s Section name of dictionary to examine
+ @return pointer to statically allocated character strings
- This function is only provided for backwards compatibility with
- previous versions of iniparser. It is recommended to use
- iniparser_getstring() instead.
+ This function queries a dictionary and finds all keys in a given section.
+ Each pointer in the returned char pointer-to-pointer is pointing to
+ a string allocated in the dictionary; do not free or modify them.
+
+ This function returns NULL in case of error.
*/
/*--------------------------------------------------------------------------*/
-char * iniparser_getstr(dictionary * d, const char * key);
-
+char ** iniparser_getseckeys(dictionary * d, char * s);
/*-------------------------------------------------------------------------*/
/**
@@ -185,7 +200,7 @@ int iniparser_getint(dictionary * d, const char * key, int notfound);
the notfound value is returned.
*/
/*--------------------------------------------------------------------------*/
-double iniparser_getdouble(dictionary * d, char * key, double notfound);
+double iniparser_getdouble(dictionary * d, const char * key, double notfound);
/*-------------------------------------------------------------------------*/
/**
@@ -235,8 +250,8 @@ int iniparser_getboolean(dictionary * d, const char * key, int notfound);
It is Ok to set val to NULL.
*/
/*--------------------------------------------------------------------------*/
+int iniparser_set(dictionary * ini, const char * entry, const char * val);
-int iniparser_setstr(dictionary * ini, char * entry, char * val);
/*-------------------------------------------------------------------------*/
/**
@@ -248,7 +263,7 @@ int iniparser_setstr(dictionary * ini, char * entry, char * val);
If the given entry can be found, it is deleted from the dictionary.
*/
/*--------------------------------------------------------------------------*/
-void iniparser_unset(dictionary * ini, char * entry);
+void iniparser_unset(dictionary * ini, const char * entry);
/*-------------------------------------------------------------------------*/
/**
@@ -262,7 +277,7 @@ void iniparser_unset(dictionary * ini, char * entry);
of querying for the presence of sections in a dictionary.
*/
/*--------------------------------------------------------------------------*/
-int iniparser_find_entry(dictionary * ini, char * entry) ;
+int iniparser_find_entry(dictionary * ini, const char * entry) ;
/*-------------------------------------------------------------------------*/
/**
@@ -293,4 +308,8 @@ dictionary * iniparser_load(const char * ininame);
/*--------------------------------------------------------------------------*/
void iniparser_freedict(dictionary * d);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/src/strlib.c b/src/strlib.c
deleted file mode 100644
index f0d85ae..0000000
--- a/src/strlib.c
+++ /dev/null
@@ -1,211 +0,0 @@
-
-/*-------------------------------------------------------------------------*/
-/**
- @file strlib.c
- @author N. Devillard
- @date Jan 2001
- @version $Revision: 1.9 $
- @brief Various string handling routines to complement the C lib.
-
- This modules adds a few complementary string routines usually missing
- in the standard C library.
-*/
-/*--------------------------------------------------------------------------*/
-
-/*
- $Id: strlib.c,v 1.9 2006-09-27 11:04:11 ndevilla Exp $
- $Author: ndevilla $
- $Date: 2006-09-27 11:04:11 $
- $Revision: 1.9 $
-*/
-
-/*---------------------------------------------------------------------------
- Includes
- ---------------------------------------------------------------------------*/
-
-#include <string.h>
-#include <ctype.h>
-
-#include "strlib.h"
-
-/*---------------------------------------------------------------------------
- Defines
- ---------------------------------------------------------------------------*/
-#define ASCIILINESZ 1024
-
-/*---------------------------------------------------------------------------
- Function codes
- ---------------------------------------------------------------------------*/
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Convert a string to lowercase.
- @param s String to convert.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string
- containing a lowercased version of the input string. Do not free
- or modify the returned string! Since the returned string is statically
- allocated, it will be modified at each function call (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-
-char * strlwc(const char * s)
-{
- static char l[ASCIILINESZ+1];
- int i ;
-
- if (s==NULL) return NULL ;
- memset(l, 0, ASCIILINESZ+1);
- i=0 ;
- while (s[i] && i<ASCIILINESZ) {
- l[i] = (char)tolower((int)s[i]);
- i++ ;
- }
- l[ASCIILINESZ]=(char)0;
- return l ;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Convert a string to uppercase.
- @param s String to convert.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string
- containing an uppercased version of the input string. Do not free
- or modify the returned string! Since the returned string is statically
- allocated, it will be modified at each function call (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-
-char * strupc(char * s)
-{
- static char l[ASCIILINESZ+1];
- int i ;
-
- if (s==NULL) return NULL ;
- memset(l, 0, ASCIILINESZ+1);
- i=0 ;
- while (s[i] && i<ASCIILINESZ) {
- l[i] = (char)toupper((int)s[i]);
- i++ ;
- }
- l[ASCIILINESZ]=(char)0;
- return l ;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Skip blanks until the first non-blank character.
- @param s String to parse.
- @return Pointer to char inside given string.
-
- This function returns a pointer to the first non-blank character in the
- given string.
- */
-/*--------------------------------------------------------------------------*/
-
-char * strskp(char * s)
-{
- char * skip = s;
- if (s==NULL) return NULL ;
- while (isspace((int)*skip) && *skip) skip++;
- return skip ;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Remove blanks at the end of a string.
- @param s String to parse.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string,
- which is identical to the input string, except that all blank
- characters at the end of the string have been removed.
- Do not free or modify the returned string! Since the returned string
- is statically allocated, it will be modified at each function call
- (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-
-char * strcrop(char * s)
-{
- static char l[ASCIILINESZ+1];
- char * last ;
-
- if (s==NULL) return NULL ;
- memset(l, 0, ASCIILINESZ+1);
- strcpy(l, s);
- last = l + strlen(l);
- while (last > l) {
- if (!isspace((int)*(last-1)))
- break ;
- last -- ;
- }
- *last = (char)0;
- return l ;
-}
-
-
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Remove blanks at the beginning and the end of a string.
- @param s String to parse.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string,
- which is identical to the input string, except that all blank
- characters at the end and the beg. of the string have been removed.
- Do not free or modify the returned string! Since the returned string
- is statically allocated, it will be modified at each function call
- (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-char * strstrip(char * s)
-{
- static char l[ASCIILINESZ+1];
- char * last ;
-
- if (s==NULL) return NULL ;
-
- while (isspace((int)*s) && *s) s++;
-
- memset(l, 0, ASCIILINESZ+1);
- strcpy(l, s);
- last = l + strlen(l);
- while (last > l) {
- if (!isspace((int)*(last-1)))
- break ;
- last -- ;
- }
- *last = (char)0;
-
- return (char*)l ;
-}
-
-/* Test code */
-#ifdef TEST
-int main(int argc, char * argv[])
-{
- char * str ;
-
- str = "\t\tI'm a lumberkack and I'm OK " ;
- printf("lowercase: [%s]\n", strlwc(str));
- printf("uppercase: [%s]\n", strupc(str));
- printf("skipped : [%s]\n", strskp(str));
- printf("cropped : [%s]\n", strcrop(str));
- printf("stripped : [%s]\n", strstrip(str));
-
- return 0 ;
-}
-#endif
-/* vim: set ts=4 et sw=4 tw=75 */
diff --git a/src/strlib.h b/src/strlib.h
deleted file mode 100644
index cd70a62..0000000
--- a/src/strlib.h
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/*-------------------------------------------------------------------------*/
-/**
- @file strlib.h
- @author N. Devillard
- @date Jan 2001
- @version $Revision: 1.4 $
- @brief Various string handling routines to complement the C lib.
-
- This modules adds a few complementary string routines usually missing
- in the standard C library.
-*/
-/*--------------------------------------------------------------------------*/
-
-/*
- $Id: strlib.h,v 1.4 2006-09-27 11:04:11 ndevilla Exp $
- $Author: ndevilla $
- $Date: 2006-09-27 11:04:11 $
- $Revision: 1.4 $
-*/
-
-#ifndef _STRLIB_H_
-#define _STRLIB_H_
-
-/*---------------------------------------------------------------------------
- Includes
- ---------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/*---------------------------------------------------------------------------
- Function codes
- ---------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Convert a string to lowercase.
- @param s String to convert.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string
- containing a lowercased version of the input string. Do not free
- or modify the returned string! Since the returned string is statically
- allocated, it will be modified at each function call (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-char * strlwc(const char * s);
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Convert a string to uppercase.
- @param s String to convert.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string
- containing an uppercased version of the input string. Do not free
- or modify the returned string! Since the returned string is statically
- allocated, it will be modified at each function call (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-char * strupc(char * s);
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Skip blanks until the first non-blank character.
- @param s String to parse.
- @return Pointer to char inside given string.
-
- This function returns a pointer to the first non-blank character in the
- given string.
- */
-/*--------------------------------------------------------------------------*/
-char * strskp(char * s);
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Remove blanks at the end of a string.
- @param s String to parse.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string,
- which is identical to the input string, except that all blank
- characters at the end of the string have been removed.
- Do not free or modify the returned string! Since the returned string
- is statically allocated, it will be modified at each function call
- (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-char * strcrop(char * s);
-
-/*-------------------------------------------------------------------------*/
-/**
- @brief Remove blanks at the beginning and the end of a string.
- @param s String to parse.
- @return ptr to statically allocated string.
-
- This function returns a pointer to a statically allocated string,
- which is identical to the input string, except that all blank
- characters at the end and the beg. of the string have been removed.
- Do not free or modify the returned string! Since the returned string
- is statically allocated, it will be modified at each function call
- (not re-entrant).
- */
-/*--------------------------------------------------------------------------*/
-char * strstrip(char * s) ;
-
-#endif
diff --git a/test/Makefile b/test/Makefile
index aa8fcb2..3c8c410 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -12,13 +12,19 @@ RM = rm -f
default: all
-all: iniexample
+all: iniexample parse iniexample_thread
iniexample: iniexample.c
$(CC) $(CFLAGS) -o iniexample iniexample.c -I../src -L.. -liniparser
+parse: parse.c
+ $(CC) $(CFLAGS) -o parse parse.c -I../src -L.. -liniparser
+
+iniexample_thread: iniexample_thread.c
+ $(CC) $(CFLAGS) -o iniexample_thread iniexample_thread.c -I../src -L.. -liniparser -lpthread
+
clean veryclean:
- $(RM) iniexample example.ini
+ $(RM) iniexample example.ini parse iniexample_thread example_*.ini
diff --git a/test/iniexample.c b/test/iniexample.c
index 5e8e71c..1c567af 100644
--- a/test/iniexample.c
+++ b/test/iniexample.c
@@ -10,108 +10,91 @@ int parse_ini_file(char * ini_name);
int main(int argc, char * argv[])
{
- int status ;
-
- if (argc<2) {
- create_example_ini_file();
- status = parse_ini_file("example.ini");
- } else {
- status = parse_ini_file(argv[1]);
- }
- return status ;
+ int status ;
+
+ if (argc<2) {
+ create_example_ini_file();
+ status = parse_ini_file("example.ini");
+ } else {
+ status = parse_ini_file(argv[1]);
+ }
+ return status ;
}
void create_example_ini_file(void)
{
- FILE * ini ;
-
- ini = fopen("example.ini", "w");
- fprintf(ini, "\n\
-#\n\
-# This is an example of ini file\n\
-#\n\
-\n\
-[Pizza]\n\
-\n\
-Ham = yes ;\n\
-Mushrooms = TRUE ;\n\
-Capres = 0 ;\n\
-Cheese = NO ;\n\
-\n\
-\n\
-[Wine]\n\
-\n\
-Grape = Cabernet Sauvignon ;\n\
-Year = 1989 ;\n\
-Country = Spain ;\n\
-Alcohol = 12.5 ;\n\
-\n\
-#\n\
-# end of file\n\
-#\n");
-
- fclose(ini);
+ FILE * ini ;
+
+ ini = fopen("example.ini", "w");
+ fprintf(ini,
+ "#\n"
+ "# This is an example of ini file\n"
+ "#\n"
+ "\n"
+ "[Pizza]\n"
+ "\n"
+ "Ham = yes ;\n"
+ "Mushrooms = TRUE ;\n"
+ "Capres = 0 ;\n"
+ "Cheese = Non ;\n"
+ "\n"
+ "\n"
+ "[Wine]\n"
+ "\n"
+ "Grape = Cabernet Sauvignon ;\n"
+ "Year = 1989 ;\n"
+ "Country = Spain ;\n"
+ "Alcohol = 12.5 ;\n"
+ "\n");
+ fclose(ini);
}
int parse_ini_file(char * ini_name)
{
- dictionary * ini ;
-
- /* Some temporary variables to hold query results */
- int b ;
- int i ;
- double d ;
- char * s ;
-
- ini = iniparser_load(ini_name);
- if (ini==NULL) {
- fprintf(stderr, "cannot parse file [%s]", ini_name);
- return -1 ;
- }
- iniparser_dump(ini, stderr);
-
- /* Get pizza attributes */
- printf("Pizza:\n");
-
- b = iniparser_getboolean(ini, "pizza:ham", -1);
- printf("Ham: [%d]\n", b);
- b = iniparser_getboolean(ini, "pizza:mushrooms", -1);
- printf("Mushrooms: [%d]\n", b);
- b = iniparser_getboolean(ini, "pizza:capres", -1);
- printf("Capres: [%d]\n", b);
- b = iniparser_getboolean(ini, "pizza:cheese", -1);
- printf("Cheese: [%d]\n", b);
-
- /* Get wine attributes */
- printf("Wine:\n");
- s = iniparser_getstr(ini, "wine:grape");
- if (s) {
- printf("grape: [%s]\n", s);
- } else {
- printf("grape: not found\n");
- }
- i = iniparser_getint(ini, "wine:year", -1);
- if (i>0) {
- printf("year: [%d]\n", i);
- } else {
- printf("year: not found\n");
- }
- s = iniparser_getstr(ini, "wine:country");
- if (s) {
- printf("country: [%s]\n", s);
- } else {
- printf("country: not found\n");
- }
- d = iniparser_getdouble(ini, "wine:alcohol", -1.0);
- if (d>0.0) {
- printf("alcohol: [%g]\n", d);
- } else {
- printf("alcohol: not found\n");
- }
-
- iniparser_freedict(ini);
- return 0 ;
+ dictionary * ini ;
+
+ /* Some temporary variables to hold query results */
+ int b ;
+ int i ;
+ double d ;
+ char * s ;
+
+ ini = iniparser_load(ini_name);
+ if (ini==NULL) {
+ fprintf(stderr, "cannot parse file: %s\n", ini_name);
+ return -1 ;
+ }
+ iniparser_dump(ini, stderr);
+
+ /* Get pizza attributes */
+ printf("Pizza:\n");
+
+ b = iniparser_getboolean(ini, "pizza:ham", -1);
+ printf("Ham: [%d]\n", b);
+ b = iniparser_getboolean(ini, "pizza:mushrooms", -1);
+ printf("Mushrooms: [%d]\n", b);
+ b = iniparser_getboolean(ini, "pizza:capres", -1);
+ printf("Capres: [%d]\n", b);
+ b = iniparser_getboolean(ini, "pizza:cheese", -1);
+ printf("Cheese: [%d]\n", b);
+
+ /* Get wine attributes */
+ printf("Wine:\n");
+ s = iniparser_getstring(ini, "wine:grape", NULL);
+ printf("Grape: [%s]\n", s ? s : "UNDEF");
+
+ i = iniparser_getint(ini, "wine:year", -1);
+ printf("Year: [%d]\n", i);
+
+ s = iniparser_getstring(ini, "wine:country", NULL);
+ printf("Country: [%s]\n", s ? s : "UNDEF");
+
+ d = iniparser_getdouble(ini, "wine:alcohol", -1.0);
+ printf("Alcohol: [%g]\n", d);
+
+ iniparser_freedict(ini);
+ return 0 ;
}
diff --git a/test/iniexample_thread.c b/test/iniexample_thread.c
new file mode 100644
index 0000000..00467b3
--- /dev/null
+++ b/test/iniexample_thread.c
@@ -0,0 +1,170 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+
+
+#include "iniparser.h"
+
+void create_example_ini_file(char* ini_name);
+int parse_ini_file(int thread_no, char * ini_name);
+
+#define THREAD_NUM 5
+pthread_t threads[THREAD_NUM];
+int done[THREAD_NUM];
+
+void *thread_main(void *);
+
+
+int main(int argc, char * argv[])
+{
+ int i;
+ int rc;
+ int status;
+ char file_buf[1024];
+
+ for (i = 0; i < THREAD_NUM; i++) {
+ sprintf(file_buf, "%s_%d.ini", "example", i);
+ create_example_ini_file(file_buf);
+ }
+
+ for (i = 0; i < THREAD_NUM; i++) {
+ done[i] = 0;
+ pthread_create(&threads[i], NULL, &thread_main, (void *)i);
+ //printf("%d, %d\n", i, threads[i]);
+ }
+
+ for (i = THREAD_NUM - 1; i >= 0; i--) {
+ done[i] = 1;
+ rc = pthread_join(threads[i], (void **)&status);
+ if (rc == 0) {
+ printf("Completed join with thread %d status= %d\n",i, status);
+ }
+ else {
+ printf("ERROR; return code from pthread_join() is %d, thread %d\n", rc, i);
+ return -1;
+ }
+ }
+
+ return status ;
+}
+
+void *thread_main(void *arg)
+{
+ int i;
+ int status ;
+ char file_buf[1024];
+
+ //printf("therad: %d, %d\n", (int)arg, getpid());
+
+ sprintf(file_buf, "%s_%d.ini", "example", arg);
+
+ status = parse_ini_file(arg, file_buf);
+ if( status != 0 ){
+ printf("ERROR; parse_ini_file return error!\n");
+ }
+
+ pthread_exit((void *) 0);
+}
+
+void create_example_ini_file(char* ini_name)
+{
+ FILE * ini ;
+
+ if (ini = fopen(ini_name, "r"))
+ {
+ fclose(ini);
+ return;
+ }
+
+ ini = fopen(ini_name, "w");
+ fprintf(ini, "\n\
+#\n\
+# This is an example of ini file\n\
+#\n\
+\n\
+[Pizza]\n\
+\n\
+Ham = yes ;\n\
+Mushrooms = TRUE ;\n\
+Capres = 0 ;\n\
+Cheese = NO ;\n\
+\n\
+\n\
+[Wine]\n\
+\n\
+Grape = Cabernet Sauvignon ;\n\
+Year = 1989 ;\n\
+Country = Spain ;\n\
+Alcohol = 12.5 ;\n\
+\n\
+#\n\
+# end of file\n\
+#\n");
+
+ fclose(ini);
+}
+
+
+int parse_ini_file(int thread_no, char * ini_name)
+{
+ dictionary * ini ;
+
+ /* Some temporary variables to hold query results */
+ int b ;
+ int i ;
+ double d ;
+ char * s ;
+
+ ini = iniparser_load(ini_name);
+ if (ini==NULL) {
+ fprintf(stderr, "cannot parse file [%s]", ini_name);
+ return -1 ;
+ }
+ //iniparser_dump(ini, stderr);
+
+ /* Get pizza attributes */
+ //printf("Pizza:\n");
+
+ b = iniparser_getboolean(ini, "pizza:ham", -1);
+ printf("Thread %d: Ham: [%d]\n",thread_no, b);
+ b = iniparser_getboolean(ini, "pizza:mushrooms", -1);
+ printf("Thread %d: Mushrooms: [%d]\n",thread_no, b);
+ b = iniparser_getboolean(ini, "pizza:capres", -1);
+ printf("Thread %d: Capres: [%d]\n",thread_no, b);
+ b = iniparser_getboolean(ini, "pizza:cheese", -1);
+ printf("Thread %d: Cheese: [%d]\n",thread_no, b);
+
+ /* Get wine attributes */
+ //printf("Wine:\n");
+ s = iniparser_getstring(ini, "wine:grape", NULL);
+ if (s) {
+ printf("Thread %d: grape: [%s]\n",thread_no, s);
+ } else {
+ printf("Thread %d: grape: not found\n",thread_no);
+ }
+ i = iniparser_getint(ini, "wine:year", -1);
+ if (i>0) {
+ printf("Thread %d: year: [%d]\n",thread_no, i);
+ } else {
+ printf("Thread %d: year: not found\n",thread_no);
+ }
+ s = iniparser_getstring(ini, "wine:country", NULL);
+ if (s) {
+ printf("Thread %d: country: [%s]\n",thread_no, s);
+ } else {
+ printf("Thread %d: country: not found\n",thread_no);
+ }
+ d = iniparser_getdouble(ini, "wine:alcohol", -1.0);
+ if (d>0.0) {
+ printf("Thread %d: alcohol: [%g]\n", thread_no, d);
+ } else {
+ printf("Thread %d: alcohol: not found\n", thread_no);
+ }
+
+ iniparser_freedict(ini);
+ return 0 ;
+}
+
+
diff --git a/test/parse.c b/test/parse.c
new file mode 100644
index 0000000..37d07aa
--- /dev/null
+++ b/test/parse.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "iniparser.h"
+
+int main(int argc, char * argv[])
+{
+ dictionary * ini ;
+ char * ini_name ;
+
+ if (argc<2) {
+ ini_name = "twisted.ini";
+ } else {
+ ini_name = argv[1] ;
+ }
+
+ ini = iniparser_load(ini_name);
+ iniparser_dump(ini, stdout);
+ iniparser_freedict(ini);
+
+ return 0 ;
+}
diff --git a/test/test.sh b/test/test.sh
new file mode 100755
index 0000000..0798ded
--- /dev/null
+++ b/test/test.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+count=0
+
+echo "" > log.txt
+while [ $count -lt 1000 ]
+do
+ echo "Test [$count]"
+ echo "Test case [$count] ==============================" >> log.txt
+ ./iniexample_thread >> log.txt
+ count=`expr $count + 1`
+done
diff --git a/test/twisted-errors.ini b/test/twisted-errors.ini
new file mode 100644
index 0000000..4dc3bbe
--- /dev/null
+++ b/test/twisted-errors.ini
@@ -0,0 +1,9 @@
+#
+# All of these should trigger syntax errors
+#
+[section]
+hello
+world
+hello \
+world
+a + b ;
diff --git a/test/twisted-genhuge.py b/test/twisted-genhuge.py
new file mode 100644
index 0000000..570973c
--- /dev/null
+++ b/test/twisted-genhuge.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+import os
+import sys
+
+if __name__=="__main__":
+ f=open('twisted-massive.ini', 'w')
+ for i in range(100):
+ f.write('[%03d]\n' % i)
+ for j in range(100):
+ f.write('key-%03d=1;\n' % j)
+ f.close()
+
diff --git a/test/twisted-ofkey.ini b/test/twisted-ofkey.ini
new file mode 100644
index 0000000..4f2e72e
--- /dev/null
+++ b/test/twisted-ofkey.ini
@@ -0,0 +1,66 @@
+# Stress testing buffers for overflows
+[long]
+# Shitload key size
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1
+
diff --git a/test/twisted-ofval.ini b/test/twisted-ofval.ini
new file mode 100644
index 0000000..2a3cedf
--- /dev/null
+++ b/test/twisted-ofval.ini
@@ -0,0 +1,56 @@
+# Shitload data size
+[long]
+a=\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
+
diff --git a/test/twisted.ini b/test/twisted.ini
new file mode 100644
index 0000000..86e549f
--- /dev/null
+++ b/test/twisted.ini
@@ -0,0 +1,131 @@
+#
+# Twisted.ini
+# This file is meant for regression tests
+
+# Different blank settings around the equal sign
+[blanks]
+a=1
+b=1;
+c=1; comment
+d=1# comment
+
+e =1
+f =1;
+g =1; comment
+h =1# comment
+
+i= 1
+j= 1;
+k= 1; comment
+l= 1# comment
+
+m = 1
+n = 1;
+o = 1; comment
+p = 1# comment
+
+q=1 ;
+r=1 ; comment
+s=1 ;comment
+t=1 #comment
+
+# Empty values
+[empty]
+a = ''
+b = ""
+
+c = '' ;
+d = "" ;
+
+e = '' ; comment
+f = "" ; comment
+
+g =
+h = ;
+i = ; comment
+j = # comment
+
+k=
+l=;
+m=;comment
+n=#
+
+# Peculiar values
+[peculiar]
+a=';';
+b='#'#
+c=';';comment
+d='#'#comment
+e=\;
+f=\#
+g=\;comment
+h=\#comment
+i=;;
+j=##
+k=;;;;;;;;;;
+l=##########
+
+# Quotes
+[quotes]
+s1='
+s2=''
+s3='''
+s4=''''
+
+d1="
+d2=""
+d3="""
+d4=""""
+
+m1='"'
+m2="'"
+
+h1=hello'world
+h2='hello'world
+h3='hello'world'
+
+h4=hello"world
+h5="hello"world
+h6="hello"world"
+
+# Section names
+[a]
+[ b]
+[c ]
+[ d ]
+[ begin end ]
+[ open[ ]
+
+# Multi-line inputs
+[multi]
+a = begin\
+end
+b = begin \
+end
+c = begin \
+ end
+d = 1\
+2\
+3\
+4
+e = 1 \
+ 2 \
+ 3 \
+ 4
+f = 1 ; \
+hidden = because of the preceding backslash multi-lining the comment ;
+visible = 1
+g = 1 #\
+and now this comment is hidden too \
+and this one too
+h = 1
+multi \
+line \
+key = 1
+multi \
+line \
+key = \
+multi \
+line \
+value ;
+# end of file