From fee34ef959144312c665499da04a2e43e309a4ce Mon Sep 17 00:00:00 2001 From: madmurphy Date: Fri, 12 Oct 2018 01:48:37 +0100 Subject: [PATCH] Commit #122 --- ChangeLog | 12 +++++++ INSTALL | 14 +++++--- MANUAL.md | 2 +- Makefile.am | 1 - README | 6 ++++ autogen.sh | 61 ++++++++++++++++++-------------- configure.ac | 4 +-- docs/html/changelog.html | 6 ++++ docs/html/confini_8c.html | 5 +-- docs/html/confini_8h.html | 5 +-- docs/html/confini_8h_source.html | 54 ++++++++++++++-------------- docs/html/libconfini.html | 2 +- docs/html/readme.html | 3 +- docs/man/man3/IniDispatch.3 | 2 +- docs/man/man3/IniFormat.3 | 2 +- docs/man/man3/IniStatistics.3 | 2 +- docs/man/man3/confini.h.3 | 12 +++++-- docs/man/man3/libconfini.3 | 2 +- docs/manual.html | 2 +- examples/topics/load_ini_file.c | 2 +- package.json | 2 +- src/confini.c | 11 +++++- 22 files changed, 135 insertions(+), 77 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f472c0..32e9533 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,18 @@ Change Log {#changelog} ======================= +## 1.7.2 -- 2018-10-12 + +Changes: + +* Code review (`load_ini_path()` -- see issue + [#6](https://github.com/madmurphy/libconfini/issues/6) concerning file + access under Microsoft Windows) +* Documentation -- see issues + [#5](https://github.com/madmurphy/libconfini/issues/5) and + [#6](https://github.com/madmurphy/libconfini/issues/6) + + ## 1.7.1 -- 2018-10-08 Changes: diff --git a/INSTALL b/INSTALL index a249917..8171692 100644 --- a/INSTALL +++ b/INSTALL @@ -1,13 +1,19 @@ -On most Unix-like systems, you should be able to install libconfini using -the following common steps: +On most Unix-like systems, you should be able to install libconfini using the +following common steps: ./configure make make install -If you need to customize the target directories, or otherwise adjust the -build setting, use +If you need to customize the target directories, or otherwise adjust the build +setting, use ./configure --help to list the configure options. + +If the `configure` script is missing from your package you need to create it by +running the `autogen.sh` script. Use the `--noconfigure` parameter in order to +prevent `autogen.sh` from running automatically `configure` immediately after +having generated it. + diff --git a/MANUAL.md b/MANUAL.md index a7eba30..8ddcc2d 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -396,7 +396,7 @@ static int callback (IniDispatch * dispatch, void * v_null) { int main () { - FILE * const ini_file = fopen("ini_files/example.conf", "r"); + FILE * const ini_file = fopen("ini_files/example.conf", "rb"); if (ini_file == NULL) { diff --git a/Makefile.am b/Makefile.am index c3a3052..a086b37 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,6 @@ if ENABLE_DOC dist_doc_DATA += docs/manual.html \ ChangeLog \ - INSTALL \ NEWS \ README diff --git a/README b/README index 7ac92c1..9c68610 100644 --- a/README +++ b/README @@ -137,6 +137,12 @@ make make install ~~~~~~~~~~~~ +If the `configure` script is missing from your package you need to generate it +by running the `autogen.sh` script. By default `autogen.sh` will also run the +`configure` script immediately after having generated it, so you may directly +type the `make` command directly after `autogen.sh`. To list different options +use `autogen.sh --help`. + An unofficial port of **libconfini** for Cygwin [is also available][5]. diff --git a/autogen.sh b/autogen.sh index 25ea873..2b74771 100755 --- a/autogen.sh +++ b/autogen.sh @@ -4,8 +4,8 @@ DIE=0 CONFIGURE_ARGS=() -for AG_ARG; do - case "${AG_ARG}" in +for __AG_ARG__; do + case "${__AG_ARG__}" in -h|--help) echo "Usage: ${0} [option]" echo @@ -13,15 +13,15 @@ for AG_ARG; do echo " -h|--help Show this help message" echo " -n|--noconfigure Skip the configure process" echo - echo 'If this script is invoked without the `--noconfigure'\'' option all unrecognized' - echo 'arguments will be passed to `configure'\''.' + echo 'If this script is invoked without the `--noconfigure` option all unrecognized' + echo 'arguments will be passed to `configure`.' exit 0 ;; -n|--noconfigure) NOCONFIGURE='YES' ;; *) - CONFIGURE_ARGS+=("${AG_ARG}") + CONFIGURE_ARGS+=("${__AG_ARG__}") ;; esac done @@ -56,14 +56,14 @@ if [ -n "${GNOME2_DIR}" ]; then fi (test -f "${srcdir}/configure.ac") || { - echo -n "**Error**: Directory \`${srcdir}' does not look like the" + echo -n "**Error**: Directory \`${srcdir}\` does not look like the" echo " top-level package directory" exit 1 } (autoconf --version) < /dev/null > /dev/null 2>&1 || { echo - echo "**Error**: You must have \`autoconf' installed." + echo "**Error**: You must have \`autoconf\` installed." echo "Download the appropriate package for your distribution," echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" DIE=1 @@ -71,8 +71,8 @@ fi (grep "^IT_PROG_INTLTOOL" "${srcdir}/configure.ac" >/dev/null) && { (intltoolize --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: You must have \`intltool' installed." + echo + echo "**Error**: You must have \`intltool\` installed." echo "You can get it from:" echo " ftp://ftp.gnome.org/pub/GNOME/" DIE=1 @@ -82,7 +82,7 @@ fi (grep "^AM_PROG_XML_I18N_TOOLS" "${srcdir}/configure.ac" >/dev/null) && { (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || { echo - echo "**Error**: You must have \`xml-i18n-toolize' installed." + echo "**Error**: You must have \`xml-i18n-toolize\` installed." echo "You can get it from:" echo " ftp://ftp.gnome.org/pub/GNOME/" DIE=1 @@ -92,7 +92,7 @@ fi (grep "^LT_INIT" "${srcdir}/configure.ac" >/dev/null) && { ("${LIBTOOL}" --version) < /dev/null > /dev/null 2>&1 || { echo - echo "**Error**: You must have \`libtool' installed." + echo "**Error**: You must have \`libtool\` installed." echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" DIE=1 } @@ -102,7 +102,7 @@ fi (grep "sed.*POTFILES" "${srcdir}/configure.ac") > /dev/null || \ (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || { echo - echo "**Error**: You must have \`glib' installed." + echo "**Error**: You must have \`glib\` installed." echo "You can get it from: ftp://ftp.gtk.org/pub/gtk" DIE=1 } @@ -110,7 +110,7 @@ fi (automake --version) < /dev/null > /dev/null 2>&1 || { echo - echo "**Error**: You must have \`automake' installed." + echo "**Error**: You must have \`automake\` installed." echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" DIE=1 NO_AUTOMAKE=yes @@ -120,7 +120,7 @@ fi # if no automake, don't bother testing for aclocal test -n "${NO_AUTOMAKE}" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { echo - echo "**Error**: Missing \`aclocal'. The version of \`automake'" + echo "**Error**: Missing \`aclocal\`. The version of \`automake\`" echo "installed doesn't appear recent enough." echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/" DIE=1 @@ -131,16 +131,26 @@ if test "${DIE}" -eq 1; then fi if test "x${NOCONFIGURE}" = x; then - echo "I am going to prepare the build system and then run the \`configure' script." + echo 'I am going to prepare the build system and then run the `configure` script. If' + echo 'you wish differently, please specify the `--noconfigure` argument on the' + echo "\`${0}\` command line." if test -z "$*"; then echo - echo "**Warning**: I am going to run \`configure' with no arguments." - echo "If you wish to pass any to it, please specify them on the" - echo "\`${0}' command line." + echo '**Warning**: I am going to run `configure` with no arguments.' + echo 'If you wish to pass any to it, please specify them on the' + echo "\`${0}\` command line." echo fi else - echo "I am going to prepare the build system without running the \`configure' script." + echo 'I am going to prepare the build system without running the `configure` script.' + if test ${#CONFIGURE_ARGS[@]} -gt 0; then + echo + echo '**Warning**: The following arguments will be ignored:' + for __IDX__ in ${!CONFIGURE_ARGS[@]}; do + echo " $((__IDX__ + 1)). \`${CONFIGURE_ARGS[$__IDX__]}\`" + done + echo + fi fi echo 'Preparing the build system... please wait' @@ -151,8 +161,7 @@ case "${CC}" in ;; esac -for coin in `find "${srcdir}" -path "${srcdir}/CVS" -prune -o -name configure.ac -print` -do +for coin in `find "${srcdir}" -path "${srcdir}/CVS" -prune -o -name configure.ac -print`; do dr=`dirname "${coin}"` if test -f "${dr}/NO-AUTO-GEN"; then echo "skipping ${dr} -- flagged as no auto-gen" @@ -179,7 +188,7 @@ do xml-i18n-toolize --copy --force --automake fi if grep "^LT_INIT" configure.ac >/dev/null; then - if test -z "${NO_LIBTOOLIZE}" ; then + if test -z "${NO_LIBTOOLIZE}" ; then echo "Running libtoolize..." "${LIBTOOLIZE}" --force --copy fi @@ -200,14 +209,14 @@ done if test "x${NOCONFIGURE}" = x; then echo -n "Running ${srcdir}/configure" - for CF_ARG in "${CONFIGURE_ARGS[@]}"; do - echo -n " [${CF_ARG}]" + for __CF_ARG__ in "${CONFIGURE_ARGS[@]}"; do + echo -n " [${__CF_ARG__}]" done echo " ..." "${srcdir}/configure" "${CONFIGURE_ARGS[@]}" \ - && echo 'Now type `make'\'' to compile.' || exit 1 + && echo 'Now type `make` to compile.' || exit 1 else - echo 'Skipping configure process. Type `configure --help'\'' to list the configure' + echo 'Skipping configure process. Type `configure --help` to list the configure' echo 'options.' fi diff --git a/configure.ac b/configure.ac index 60d02dc..27a19ae 100644 --- a/configure.ac +++ b/configure.ac @@ -7,13 +7,13 @@ AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_ARG_ENABLE([doc], - [AS_HELP_STRING([--enable-doc], [Create package with documentation @<:@default=yes@:>@])], + [AS_HELP_STRING([--disable-doc], [Create package without documentation @<:@default=no@:>@])], [:], [enable_doc=yes] ) AC_ARG_ENABLE([examples], - [AS_HELP_STRING([--enable-examples], [Create package with examples @<:@default=yes@:>@])], + [AS_HELP_STRING([--disable-examples], [Create package without examples @<:@default=no@:>@])], [:], [enable_examples=yes] ) diff --git a/docs/html/changelog.html b/docs/html/changelog.html index 09f3b08..77bf46a 100644 --- a/docs/html/changelog.html +++ b/docs/html/changelog.html @@ -67,6 +67,12 @@

Record of notable changes

+

1.7.2 – 2018-10-12

+

Changes:

+
    +
  • Code review (load_ini_path() – see issue #6 concerning file access under Microsoft Windows)
  • +
  • Documentation – see issues #5 and #6
  • +

1.7.1 – 2018-10-08

Changes:

    diff --git a/docs/html/confini_8c.html b/docs/html/confini_8c.html index f33f3cb..781be70 100644 --- a/docs/html/confini_8c.html +++ b/docs/html/confini_8c.html @@ -1561,9 +1561,10 @@

    Returns
    Zero for success, otherwise an error code (see enum ConfiniInterruptNo)
    -

    The function f_init will be invoked with two arguments: statistics (a pointer to an IniStatistics object containing some properties about the file read) and init_other (the custom argument user_data previously passed). If f_init returns a non-zero value the caller function will be interrupted.

    +

    The ini_file parameter must be a FILE handle with read privileges. In some platforms, such as Microsoft Windows, it might be needed to add the binary specifier to the mode string ("b") in order to prevent discrepancies between the physical size of the file and its computed size:

    +
    FILE * my_file = fopen("example.conf", "rb");

    The function f_init will be invoked with two arguments: statistics (a pointer to an IniStatistics object containing some properties about the file read) and init_other (the custom argument user_data previously passed). If f_init returns a non-zero value the caller function will be interrupted.

    The function f_foreach will be invoked with two arguments: dispatch (a pointer to an IniDispatch object containing the parsed member of the INI file) and foreach_other (the custom argument user_data previously passed). If f_foreach returns a non-zero value the caller function will be interrupted.

    -
    /* examples/topics/load_ini_file.c */
    #include <stdio.h>
    #include <confini.h>
    static int callback (IniDispatch * dispatch, void * v_null) {
    printf(
    "DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
    dispatch->data, dispatch->value, dispatch->type
    );
    return 0;
    }
    int main () {
    FILE * const ini_file = fopen("ini_files/example.conf", "r");
    if (ini_file == NULL) {
    fprintf(stderr, "File doesn't exist :-(\n");
    return 1;
    }
    if (load_ini_file(ini_file, INI_DEFAULT_FORMAT, NULL, callback, NULL)) {
    fprintf(stderr, "Sorry, something went wrong :-(\n");
    return 1;
    }
    fclose(ini_file);
    return 0;
    }
    +
    /* examples/topics/load_ini_file.c */
    #include <stdio.h>
    #include <confini.h>
    static int callback (IniDispatch * dispatch, void * v_null) {
    printf(
    "DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
    dispatch->data, dispatch->value, dispatch->type
    );
    return 0;
    }
    int main () {
    FILE * const ini_file = fopen("ini_files/example.conf", "rb");
    if (ini_file == NULL) {
    fprintf(stderr, "File doesn't exist :-(\n");
    return 1;
    }
    if (load_ini_file(ini_file, INI_DEFAULT_FORMAT, NULL, callback, NULL)) {
    fprintf(stderr, "Sorry, something went wrong :-(\n");
    return 1;
    }
    fclose(ini_file);
    return 0;
    }

diff --git a/docs/html/confini_8h.html b/docs/html/confini_8h.html index 5c1cbc6..aa1ebeb 100644 --- a/docs/html/confini_8h.html +++ b/docs/html/confini_8h.html @@ -1476,9 +1476,10 @@

Returns
Zero for success, otherwise an error code (see enum ConfiniInterruptNo)
-

The function f_init will be invoked with two arguments: statistics (a pointer to an IniStatistics object containing some properties about the file read) and init_other (the custom argument user_data previously passed). If f_init returns a non-zero value the caller function will be interrupted.

+

The ini_file parameter must be a FILE handle with read privileges. In some platforms, such as Microsoft Windows, it might be needed to add the binary specifier to the mode string ("b") in order to prevent discrepancies between the physical size of the file and its computed size:

+
FILE * my_file = fopen("example.conf", "rb");

The function f_init will be invoked with two arguments: statistics (a pointer to an IniStatistics object containing some properties about the file read) and init_other (the custom argument user_data previously passed). If f_init returns a non-zero value the caller function will be interrupted.

The function f_foreach will be invoked with two arguments: dispatch (a pointer to an IniDispatch object containing the parsed member of the INI file) and foreach_other (the custom argument user_data previously passed). If f_foreach returns a non-zero value the caller function will be interrupted.

-
/* examples/topics/load_ini_file.c */
#include <stdio.h>
#include <confini.h>
static int callback (IniDispatch * dispatch, void * v_null) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
dispatch->data, dispatch->value, dispatch->type
);
return 0;
}
int main () {
FILE * const ini_file = fopen("ini_files/example.conf", "r");
if (ini_file == NULL) {
fprintf(stderr, "File doesn't exist :-(\n");
return 1;
}
if (load_ini_file(ini_file, INI_DEFAULT_FORMAT, NULL, callback, NULL)) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
}
fclose(ini_file);
return 0;
}
+
/* examples/topics/load_ini_file.c */
#include <stdio.h>
#include <confini.h>
static int callback (IniDispatch * dispatch, void * v_null) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
dispatch->data, dispatch->value, dispatch->type
);
return 0;
}
int main () {
FILE * const ini_file = fopen("ini_files/example.conf", "rb");
if (ini_file == NULL) {
fprintf(stderr, "File doesn't exist :-(\n");
return 1;
}
if (load_ini_file(ini_file, INI_DEFAULT_FORMAT, NULL, callback, NULL)) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
}
fclose(ini_file);
return 0;
}
diff --git a/docs/html/confini_8h_source.html b/docs/html/confini_8h_source.html index 9794834..6d6630c 100644 --- a/docs/html/confini_8h_source.html +++ b/docs/html/confini_8h_source.html @@ -70,21 +70,21 @@
confini.h
-Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 
14 #ifndef _LIBCONFINI_HEADER_
15 #define _LIBCONFINI_HEADER_
16 
17 #include <stdio.h>
18 #include <stdint.h>
19 
20 
21 
22 /* PRIVATE (HEADER-SCOPED) MACROS */
23 
24 
25 #define _LIBCONFINI_INIFORMAT_DECLARATION_(SIZE, PROPERTY, DEFAULT) unsigned char PROPERTY:SIZE;
26 #define _LIBCONFINI_INIFORMAT_ASSIGNEMENT_(SIZE, PROPERTY, DEFAULT) DEFAULT,
27 #define _LIBCONFINI_INIFORMAT_STRUCT_ struct IniFormat { _LIBCONFINI_INIFORMAT_AS_(_LIBCONFINI_INIFORMAT_DECLARATION_) }
28 #define _LIBCONFINI_DEFAULT_FORMAT_ { _LIBCONFINI_INIFORMAT_AS_(_LIBCONFINI_INIFORMAT_ASSIGNEMENT_) }
29 
30 
31 
32 /* PUBLIC MACROS */
33 
34 
35 #define _LIBCONFINI_INIFORMAT_AS_(______) /*-*\
36 
37  ______( BITS NAME DEFAULT VALUE )/--/
38  /-*/\
39  ______( 7, delimiter_symbol, INI_EQUALS ) \
40  ______( 1, case_sensitive, 0 )/*-/
41  /-*/\
42  ______( 2, semicolon_marker, INI_DISABLED_OR_COMMENT ) \
43  ______( 2, hash_marker, INI_DISABLED_OR_COMMENT ) \
44  ______( 2, section_paths, INI_ABSOLUTE_AND_RELATIVE ) \
45  ______( 2, multiline_nodes, INI_MULTILINE_EVERYWHERE )/*-/
46  /-*/\
47  ______( 1, no_single_quotes, 0 ) \
48  ______( 1, no_double_quotes, 0 ) \
49  ______( 1, no_spaces_in_names, 0 ) \
50  ______( 1, implicit_is_not_empty, 0 ) \
51  ______( 1, do_not_collapse_values, 0 ) \
52  ______( 1, preserve_empty_quotes, 0 ) \
53  ______( 1, disabled_after_space, 0 ) \
54  ______( 1, disabled_can_be_implicit, 0 )/*-/
55  /-*/
56 
57 
59 #define INIFORMAT_HAS_NO_ESC(FMT) (FMT.multiline_nodes == INI_NO_MULTILINE && FMT.no_double_quotes && FMT.no_single_quotes)
60 
61 
62 
63 /* PUBLIC TYPEDEFS */
64 
65 
67 typedef _LIBCONFINI_INIFORMAT_STRUCT_ IniFormat;
68 
70 typedef struct IniStatistics {
72  const size_t bytes;
73  const size_t members;
75 
77 typedef struct IniDispatch {
79  uint8_t type;
80  char * data;
81  char * value;
82  const char * append_to;
83  size_t d_len;
84  size_t v_len;
85  size_t at_len;
86  size_t dispatch_id;
87 } IniDispatch;
88 
90 typedef uint32_t IniFormatNum;
91 
92 
93 
94 /* PUBLIC FUNCTIONS */
95 
96 
97 extern int load_ini_file (
98  FILE * const ini_file,
99  const IniFormat format,
100  int (* const f_init) (
101  IniStatistics * statistics,
102  void * init_other
103  ),
104  int (* const f_foreach) (
105  IniDispatch * dispatch,
106  void * foreach_other
107  ),
108  void * const user_data
109 );
110 
111 extern int load_ini_path (
112  const char * const path,
113  const IniFormat format,
114  int (* const f_init) (
115  IniStatistics * statistics,
116  void * init_other
117  ),
118  int (* const f_foreach) (
119  IniDispatch * dispatch,
120  void * foreach_other
121  ),
122  void * const user_data
123 );
124 
125 extern _Bool ini_string_match_ss (
126  const char * const simple_string_a,
127  const char * const simple_string_b,
128  const IniFormat format
129 );
130 
131 extern _Bool ini_string_match_si (
132  const char * const simple_string,
133  const char * const ini_string,
134  const IniFormat format
135 );
136 
137 extern _Bool ini_string_match_ii (
138  const char * const ini_string_a,
139  const char * const ini_string_b,
140  const IniFormat format
141 );
142 
143 extern _Bool ini_array_match (
144  const char * const ini_string_a,
145  const char * const ini_string_b,
146  const char delimiter,
147  const IniFormat format
148 );
149 
150 extern size_t ini_unquote (
151  char * const ini_string,
152  const IniFormat format
153 );
154 
155 extern size_t ini_string_parse (
156  char * const ini_string,
157  const IniFormat format
158 );
159 
160 extern size_t ini_array_get_length (
161  const char * const ini_string,
162  const char delimiter,
163  const IniFormat format
164 );
165 
166 extern int ini_array_foreach (
167  const char * const ini_string,
168  const char delimiter,
169  const IniFormat format,
170  int (* const f_foreach) (
171  const char * fullstring,
172  size_t memb_offset,
173  size_t memb_length,
174  size_t memb_num,
175  IniFormat format,
176  void * foreach_other
177  ),
178  void * const user_data
179 );
180 
181 extern size_t ini_array_shift (
182  const char ** const ini_strptr,
183  const char delimiter,
184  const IniFormat format
185 );
186 
187 extern size_t ini_array_collapse (
188  char * const ini_string,
189  const char delimiter,
190  const IniFormat format
191 );
192 
193 extern char * ini_array_break (
194  char * const ini_string,
195  const char delimiter,
196  const IniFormat format
197 );
198 
199 extern char * ini_array_release (
200  char ** ini_strptr,
201  const char delimiter,
202  const IniFormat format
203 );
204 
205 extern int ini_array_split (
206  char * const ini_string,
207  const char delimiter,
208  const IniFormat format,
209  int (* const f_foreach) (
210  char * member,
211  size_t memb_length,
212  size_t memb_num,
213  IniFormat format,
214  void * foreach_other
215  ),
216  void * const user_data
217 );
218 
219 extern void ini_global_set_lowercase_mode (
220  _Bool lowercase
221 );
222 
223 extern void ini_global_set_implicit_value (
224  char * const implicit_value,
225  const size_t implicit_v_len
226 );
227 
228 extern IniFormatNum ini_fton (
229  const IniFormat format
230 );
231 
232 extern IniFormat ini_ntof (
233  IniFormatNum format_id
234 );
235 
236 extern signed int ini_get_bool (
237  const char * const ini_string,
238  const signed int return_value
239 );
240 
241 
242 
243 /* PUBLIC LINKS */
244 
245 
246 extern int (* const ini_get_int) (
247  const char * ini_string
248 );
249 
250 extern long int (* const ini_get_lint) (
251  const char * ini_string
252 );
253 
254 extern long long int (* const ini_get_llint) (
255  const char * ini_string
256 );
257 
258 extern double (* const ini_get_float) (
259  const char * ini_string
260 );
261 
262 
263 
264 /* PUBLIC CONSTANTS AND VARIABLES */
265 
266 
268 #define CONFINI_ERROR 252
269 
279 };
280 
284  INI_VALUE = 1,
285  INI_KEY = 2,
291 };
292 
296  INI_EQUALS = '=',
297  INI_COLON = ':',
298  INI_DOT = '.',
299  INI_COMMA = ','
300 };
301 
308 };
309 
316 };
317 
324 };
325 
327 static const IniFormat INI_DEFAULT_FORMAT = _LIBCONFINI_DEFAULT_FORMAT_;
328 
330 static const IniFormat INI_UNIXLIKE_FORMAT = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; /* All properties are set to `0` here. */
331 
333 extern _Bool INI_GLOBAL_LOWERCASE_MODE;
334 
336 extern char * INI_GLOBAL_IMPLICIT_VALUE;
337 
339 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
340 
341 
342 
343 /* CLEAN THE PRIVATE ENVIRONMENT */
344 
345 
346 #undef _LIBCONFINI_INIFORMAT_DECLARATION_
347 #undef _LIBCONFINI_INIFORMAT_ASSIGNEMENT_
348 #undef _LIBCONFINI_INIFORMAT_STRUCT_
349 #undef _LIBCONFINI_DEFAULT_FORMAT_
350 
351 
352 
353 /* END OF _LIBCONFINI_HEADER_ */
354 
355 
356 #endif
357 
358 
359 
360 /* EOF */
361 
void ini_global_set_lowercase_mode(_Bool lowercase)
Sets the value of the global variable INI_GLOBAL_LOWERCASE_MODE
Definition: confini.c:3891
-
int(*const ini_get_int)(const char *ini_string)
Link to atoi()
Definition: confini.c:4073
-
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, int(*const f_foreach)(const char *fullstring, size_t memb_offset, size_t memb_length, size_t memb_num, IniFormat format, void *foreach_other), void *const user_data)
Calls a custom function for each member of a stringified INI array without modifying the content of t...
Definition: confini.c:3247
-
int load_ini_file(FILE *const ini_file, const IniFormat format, int(*const f_init)(IniStatistics *statistics, void *init_other), int(*const f_foreach)(IniDispatch *dispatch, void *foreach_other), void *const user_data)
Parses an INI file and dispatches its content using a FILE structure as argument. ...
Definition: confini.c:1633
+Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 
14 #ifndef _LIBCONFINI_HEADER_
15 #define _LIBCONFINI_HEADER_
16 
17 #include <stdio.h>
18 #include <stdint.h>
19 
20 
21 
22 /* PRIVATE (HEADER-SCOPED) MACROS */
23 
24 
25 #define _LIBCONFINI_INIFORMAT_DECLARATION_(SIZE, PROPERTY, DEFAULT) unsigned char PROPERTY:SIZE;
26 #define _LIBCONFINI_INIFORMAT_ASSIGNEMENT_(SIZE, PROPERTY, DEFAULT) DEFAULT,
27 #define _LIBCONFINI_INIFORMAT_STRUCT_ struct IniFormat { _LIBCONFINI_INIFORMAT_AS_(_LIBCONFINI_INIFORMAT_DECLARATION_) }
28 #define _LIBCONFINI_DEFAULT_FORMAT_ { _LIBCONFINI_INIFORMAT_AS_(_LIBCONFINI_INIFORMAT_ASSIGNEMENT_) }
29 
30 
31 
32 /* PUBLIC MACROS */
33 
34 
35 #define _LIBCONFINI_INIFORMAT_AS_(______) /*-*\
36 
37  ______( BITS NAME DEFAULT VALUE )/--/
38  /-*/\
39  ______( 7, delimiter_symbol, INI_EQUALS ) \
40  ______( 1, case_sensitive, 0 )/*-/
41  /-*/\
42  ______( 2, semicolon_marker, INI_DISABLED_OR_COMMENT ) \
43  ______( 2, hash_marker, INI_DISABLED_OR_COMMENT ) \
44  ______( 2, section_paths, INI_ABSOLUTE_AND_RELATIVE ) \
45  ______( 2, multiline_nodes, INI_MULTILINE_EVERYWHERE )/*-/
46  /-*/\
47  ______( 1, no_single_quotes, 0 ) \
48  ______( 1, no_double_quotes, 0 ) \
49  ______( 1, no_spaces_in_names, 0 ) \
50  ______( 1, implicit_is_not_empty, 0 ) \
51  ______( 1, do_not_collapse_values, 0 ) \
52  ______( 1, preserve_empty_quotes, 0 ) \
53  ______( 1, disabled_after_space, 0 ) \
54  ______( 1, disabled_can_be_implicit, 0 )/*-/
55  /-*/
56 
57 
59 #define INIFORMAT_HAS_NO_ESC(FMT) (FMT.multiline_nodes == INI_NO_MULTILINE && FMT.no_double_quotes && FMT.no_single_quotes)
60 
61 
62 
63 /* PUBLIC TYPEDEFS */
64 
65 
67 typedef _LIBCONFINI_INIFORMAT_STRUCT_ IniFormat;
68 
70 typedef struct IniStatistics {
72  const size_t bytes;
73  const size_t members;
75 
77 typedef struct IniDispatch {
79  uint8_t type;
80  char * data;
81  char * value;
82  const char * append_to;
83  size_t d_len;
84  size_t v_len;
85  size_t at_len;
86  size_t dispatch_id;
87 } IniDispatch;
88 
90 typedef uint32_t IniFormatNum;
91 
92 
93 
94 /* PUBLIC FUNCTIONS */
95 
96 
97 extern int load_ini_file (
98  FILE * const ini_file,
99  const IniFormat format,
100  int (* const f_init) (
101  IniStatistics * statistics,
102  void * init_other
103  ),
104  int (* const f_foreach) (
105  IniDispatch * dispatch,
106  void * foreach_other
107  ),
108  void * const user_data
109 );
110 
111 extern int load_ini_path (
112  const char * const path,
113  const IniFormat format,
114  int (* const f_init) (
115  IniStatistics * statistics,
116  void * init_other
117  ),
118  int (* const f_foreach) (
119  IniDispatch * dispatch,
120  void * foreach_other
121  ),
122  void * const user_data
123 );
124 
125 extern _Bool ini_string_match_ss (
126  const char * const simple_string_a,
127  const char * const simple_string_b,
128  const IniFormat format
129 );
130 
131 extern _Bool ini_string_match_si (
132  const char * const simple_string,
133  const char * const ini_string,
134  const IniFormat format
135 );
136 
137 extern _Bool ini_string_match_ii (
138  const char * const ini_string_a,
139  const char * const ini_string_b,
140  const IniFormat format
141 );
142 
143 extern _Bool ini_array_match (
144  const char * const ini_string_a,
145  const char * const ini_string_b,
146  const char delimiter,
147  const IniFormat format
148 );
149 
150 extern size_t ini_unquote (
151  char * const ini_string,
152  const IniFormat format
153 );
154 
155 extern size_t ini_string_parse (
156  char * const ini_string,
157  const IniFormat format
158 );
159 
160 extern size_t ini_array_get_length (
161  const char * const ini_string,
162  const char delimiter,
163  const IniFormat format
164 );
165 
166 extern int ini_array_foreach (
167  const char * const ini_string,
168  const char delimiter,
169  const IniFormat format,
170  int (* const f_foreach) (
171  const char * fullstring,
172  size_t memb_offset,
173  size_t memb_length,
174  size_t memb_num,
175  IniFormat format,
176  void * foreach_other
177  ),
178  void * const user_data
179 );
180 
181 extern size_t ini_array_shift (
182  const char ** const ini_strptr,
183  const char delimiter,
184  const IniFormat format
185 );
186 
187 extern size_t ini_array_collapse (
188  char * const ini_string,
189  const char delimiter,
190  const IniFormat format
191 );
192 
193 extern char * ini_array_break (
194  char * const ini_string,
195  const char delimiter,
196  const IniFormat format
197 );
198 
199 extern char * ini_array_release (
200  char ** ini_strptr,
201  const char delimiter,
202  const IniFormat format
203 );
204 
205 extern int ini_array_split (
206  char * const ini_string,
207  const char delimiter,
208  const IniFormat format,
209  int (* const f_foreach) (
210  char * member,
211  size_t memb_length,
212  size_t memb_num,
213  IniFormat format,
214  void * foreach_other
215  ),
216  void * const user_data
217 );
218 
219 extern void ini_global_set_lowercase_mode (
220  _Bool lowercase
221 );
222 
223 extern void ini_global_set_implicit_value (
224  char * const implicit_value,
225  const size_t implicit_v_len
226 );
227 
228 extern IniFormatNum ini_fton (
229  const IniFormat format
230 );
231 
232 extern IniFormat ini_ntof (
233  IniFormatNum format_id
234 );
235 
236 extern signed int ini_get_bool (
237  const char * const ini_string,
238  const signed int return_value
239 );
240 
241 
242 
243 /* PUBLIC LINKS */
244 
245 
246 extern int (* const ini_get_int) (
247  const char * ini_string
248 );
249 
250 extern long int (* const ini_get_lint) (
251  const char * ini_string
252 );
253 
254 extern long long int (* const ini_get_llint) (
255  const char * ini_string
256 );
257 
258 extern double (* const ini_get_float) (
259  const char * ini_string
260 );
261 
262 
263 
264 /* PUBLIC CONSTANTS AND VARIABLES */
265 
266 
268 #define CONFINI_ERROR 252
269 
279 };
280 
284  INI_VALUE = 1,
285  INI_KEY = 2,
291 };
292 
296  INI_EQUALS = '=',
297  INI_COLON = ':',
298  INI_DOT = '.',
299  INI_COMMA = ','
300 };
301 
308 };
309 
316 };
317 
324 };
325 
327 static const IniFormat INI_DEFAULT_FORMAT = _LIBCONFINI_DEFAULT_FORMAT_;
328 
330 static const IniFormat INI_UNIXLIKE_FORMAT = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; /* All properties are set to `0` here. */
331 
333 extern _Bool INI_GLOBAL_LOWERCASE_MODE;
334 
336 extern char * INI_GLOBAL_IMPLICIT_VALUE;
337 
339 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
340 
341 
342 
343 /* CLEAN THE PRIVATE ENVIRONMENT */
344 
345 
346 #undef _LIBCONFINI_INIFORMAT_DECLARATION_
347 #undef _LIBCONFINI_INIFORMAT_ASSIGNEMENT_
348 #undef _LIBCONFINI_INIFORMAT_STRUCT_
349 #undef _LIBCONFINI_DEFAULT_FORMAT_
350 
351 
352 
353 /* END OF _LIBCONFINI_HEADER_ */
354 
355 
356 #endif
357 
358 
359 
360 /* EOF */
361 
void ini_global_set_lowercase_mode(_Bool lowercase)
Sets the value of the global variable INI_GLOBAL_LOWERCASE_MODE
Definition: confini.c:3900
+
int(*const ini_get_int)(const char *ini_string)
Link to atoi()
Definition: confini.c:4082
+
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, int(*const f_foreach)(const char *fullstring, size_t memb_offset, size_t memb_length, size_t memb_num, IniFormat format, void *foreach_other), void *const user_data)
Calls a custom function for each member of a stringified INI array without modifying the content of t...
Definition: confini.c:3256
+
int load_ini_file(FILE *const ini_file, const IniFormat format, int(*const f_init)(IniStatistics *statistics, void *init_other), int(*const f_foreach)(IniDispatch *dispatch, void *foreach_other), void *const user_data)
Parses an INI file and dispatches its content using a FILE structure as argument. ...
Definition: confini.c:1642
Definition: confini.h:321
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like CONF files (space characters are delimiters between keys and values) ...
Definition: confini.h:330
-
_Bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compares two simple strings and checks if they match.
Definition: confini.c:2191
+
_Bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compares two simple strings and checks if they match.
Definition: confini.c:2200
Definition: confini.h:284
-
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, int(*const f_foreach)(char *member, size_t memb_length, size_t memb_num, IniFormat format, void *foreach_other), void *const user_data)
Splits a stringified INI array into NUL-separated members and calls a custom function for each member...
Definition: confini.c:3786
+
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, int(*const f_foreach)(char *member, size_t memb_length, size_t memb_num, IniFormat format, void *foreach_other), void *const user_data)
Splits a stringified INI array into NUL-separated members and calls a custom function for each member...
Definition: confini.c:3795
Definition: confini.h:290
Definition: confini.h:277
Definition: confini.h:320
Definition: confini.h:275
Definition: confini.h:273
-
_Bool ini_array_match(const char *const ini_string_a, const char *const ini_string_b, const char delimiter, const IniFormat format)
Compares two INI arrays and checks if they match.
Definition: confini.c:2639
+
_Bool ini_array_match(const char *const ini_string_a, const char *const ini_string_b, const char delimiter, const IniFormat format)
Compares two INI arrays and checks if they match.
Definition: confini.c:2648
Definition: confini.h:323
Definition: confini.h:315
size_t v_len
Definition: confini.h:84
@@ -95,65 +95,65 @@
Global statistics about an INI file.
Definition: confini.h:70
uint8_t type
Definition: confini.h:79
Definition: confini.h:274
-
IniFormatNum ini_fton(const IniFormat format)
Calculates the IniFormatNum of an IniFormat
Definition: confini.c:3934
+
IniFormatNum ini_fton(const IniFormat format)
Calculates the IniFormatNum of an IniFormat
Definition: confini.c:3943
Definition: confini.h:299
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:67
Definition: confini.h:276
const size_t bytes
Definition: confini.h:72
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:327
-
double(*const ini_get_float)(const char *ini_string)
Link to atof()
Definition: confini.c:4079
-
int load_ini_path(const char *const path, const IniFormat format, int(*const f_init)(IniStatistics *statistics, void *init_other), int(*const f_foreach)(IniDispatch *dispatch, void *foreach_other), void *const user_data)
Parses an INI file and dispatches its content using a path as argument.
Definition: confini.c:2140
+
double(*const ini_get_float)(const char *ini_string)
Link to atof()
Definition: confini.c:4088
+
int load_ini_path(const char *const path, const IniFormat format, int(*const f_init)(IniStatistics *statistics, void *init_other), int(*const f_foreach)(IniDispatch *dispatch, void *foreach_other), void *const user_data)
Parses an INI file and dispatches its content using a path as argument.
Definition: confini.c:2149
IniDelimiters
Most used key-value and array delimiters (but a delimiter may also be any other ASCII character) ...
Definition: confini.h:294
char * data
Definition: confini.h:80
-
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescapes \\, \' and \" and removes all unescaped quotes (if single/double quotes are considered meta...
Definition: confini.c:2987
+
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescapes \\, \' and \" and removes all unescaped quotes (if single/double quotes are considered meta...
Definition: confini.c:2996
Definition: confini.h:312
IniMultiline
Possible values of IniFormat::multiline_nodes.
Definition: confini.h:319
IniNodeType
INI node types.
Definition: confini.h:282
Definition: confini.h:286
-
signed int ini_get_bool(const char *const ini_string, const signed int return_value)
Checks whether a string matches one of the booleans listed in the private constant INI_BOOLEANS (case...
Definition: confini.c:4010
+
signed int ini_get_bool(const char *const ini_string, const signed int return_value)
Checks whether a string matches one of the booleans listed in the private constant INI_BOOLEANS (case...
Definition: confini.c:4019
struct IniStatistics IniStatistics
Global statistics about an INI file.
Definition: confini.h:278
Definition: confini.h:288
-
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys – this may be any unsigned number, independently of th...
Definition: confini.c:4090
+
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys – this may be any unsigned number, independently of th...
Definition: confini.c:4099
Definition: confini.h:295
IniSectionPaths
Possible values of IniFormat::section_paths
Definition: confini.h:311
Definition: confini.h:304
-
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replaces the first delimiter found (together with the spaces that surround it) with \0 ...
Definition: confini.c:3645
+
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replaces the first delimiter found (together with the spaces that surround it) with \0 ...
Definition: confini.c:3654
Definition: confini.h:298
Definition: confini.h:287
Definition: confini.h:272
-
long long int(*const ini_get_llint)(const char *ini_string)
Link to atoll()
Definition: confini.c:4077
+
long long int(*const ini_get_llint)(const char *ini_string)
Link to atoll()
Definition: confini.c:4086
IniCommentMarker
Possible values of IniFormat::semicolon_marker and IniFormat::hash_marker (i.e., meaning of /\s+[#;]/...
Definition: confini.h:303
char * value
Definition: confini.h:81
Definition: confini.h:307
-
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compresses the distribution of the data of a stringified INI array by removing all the white spaces t...
Definition: confini.c:3452
-
IniFormat ini_ntof(IniFormatNum format_id)
Constructs a new IniFormat according to an IniFormatNum
Definition: confini.c:3961
+
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compresses the distribution of the data of a stringified INI array by removing all the white spaces t...
Definition: confini.c:3461
+
IniFormat ini_ntof(IniFormatNum format_id)
Constructs a new IniFormat according to an IniFormatNum
Definition: confini.c:3970
size_t d_len
Definition: confini.h:83
-
_Bool INI_GLOBAL_LOWERCASE_MODE
If set to TRUE, key and section names in case-insensitive INI formats will be dispatched lowercase...
Definition: confini.c:4086
+
_Bool INI_GLOBAL_LOWERCASE_MODE
If set to TRUE, key and section names in case-insensitive INI formats will be dispatched lowercase...
Definition: confini.c:4095
Definition: confini.h:322
Definition: confini.h:296
uint32_t IniFormatNum
The unique ID number of an INI format (24-bit maximum)
Definition: confini.h:90
ConfiniInterruptNo
Error codes – the actual value of each constant should be considered opaque.
Definition: confini.h:271
-
_Bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compares two INI strings and checks if they match.
Definition: confini.c:2448
-
char * ini_array_release(char **ini_strptr, const char delimiter, const IniFormat format)
Replaces the first delimiter found (together with the spaces that surround it) with \0...
Definition: confini.c:3718
+
_Bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compares two INI strings and checks if they match.
Definition: confini.c:2457
+
char * ini_array_release(char **ini_strptr, const char delimiter, const IniFormat format)
Replaces the first delimiter found (together with the spaces that surround it) with \0...
Definition: confini.c:3727
size_t at_len
Definition: confini.h:85
Definition: confini.h:283
Definition: confini.h:297
size_t dispatch_id
Definition: confini.h:86
-
long int(*const ini_get_lint)(const char *ini_string)
Link to atol()
Definition: confini.c:4075
-
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Sets the value to be to be assigned to implicit keys.
Definition: confini.c:3917
+
long int(*const ini_get_lint)(const char *ini_string)
Link to atol()
Definition: confini.c:4084
+
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Sets the value to be to be assigned to implicit keys.
Definition: confini.c:3926
const size_t members
Definition: confini.h:73
-
_Bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compares a simple string and an INI string and and checks if they match.
Definition: confini.c:2286
+
_Bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compares a simple string and an INI string and and checks if they match.
Definition: confini.c:2295
Dispatch of a single INI node.
Definition: confini.h:77
const char * append_to
Definition: confini.h:82
Definition: confini.h:306
-
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescapes \\, \' and \" and removes all unescaped quotes (if single/double quotes are considered meta...
Definition: confini.c:2863
-
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Gets the length of a stringified INI array in number of members.
Definition: confini.c:3136
-
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:4088
+
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescapes \\, \' and \" and removes all unescaped quotes (if single/double quotes are considered meta...
Definition: confini.c:2872
+
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Gets the length of a stringified INI array in number of members.
Definition: confini.c:3145
+
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:4097
Definition: confini.h:305
struct IniFormat IniFormat
24-bit bitfield representing the format of an INI file (INI dialect)
const IniFormat format
Definition: confini.h:78
-
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shifts the location pointed by ini_strptr to the next member of the INI array (without modifying the ...
Definition: confini.c:3360
+
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shifts the location pointed by ini_strptr to the next member of the INI array (without modifying the ...
Definition: confini.c:3369
Definition: confini.h:314
const IniFormat format
Definition: confini.h:71
diff --git a/docs/html/libconfini.html b/docs/html/libconfini.html index d5c9b3a..2b0c9de 100644 --- a/docs/html/libconfini.html +++ b/docs/html/libconfini.html @@ -128,7 +128,7 @@

KEYS

Both functions load_ini_file() and load_ini_path() will return zero if the INI file has been completely parsed, non-zero otherwise.

BASIC EXAMPLES

#1:

-
/* examples/topics/load_ini_file.c */
#include <stdio.h>
#include <confini.h>
static int callback (IniDispatch * dispatch, void * v_null) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
dispatch->data, dispatch->value, dispatch->type
);
return 0;
}
int main () {
FILE * const ini_file = fopen("ini_files/example.conf", "r");
if (ini_file == NULL) {
fprintf(stderr, "File doesn't exist :-(\n");
return 1;
}
ini_file,
NULL,
callback,
NULL
)) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
}
fclose(ini_file);
return 0;
}

#2:

+
/* examples/topics/load_ini_file.c */
#include <stdio.h>
#include <confini.h>
static int callback (IniDispatch * dispatch, void * v_null) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
dispatch->data, dispatch->value, dispatch->type
);
return 0;
}
int main () {
FILE * const ini_file = fopen("ini_files/example.conf", "rb");
if (ini_file == NULL) {
fprintf(stderr, "File doesn't exist :-(\n");
return 1;
}
ini_file,
NULL,
callback,
NULL
)) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
}
fclose(ini_file);
return 0;
}

#2:

/* examples/topics/load_ini_path.c */
#include <stdio.h>
#include <confini.h>
static int callback (IniDispatch * dispatch, void * v_null) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %d\n\n",
dispatch->data, dispatch->value, dispatch->type
);
return 0;
}
int main () {
"ini_files/example.conf",
NULL,
callback,
NULL
)) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
}
return 0;
}

HOW IT WORKS

The function load_ini_path() is a shortcut to the function load_ini_file() that requires a path instead of a FILE struct.

The function load_ini_file() dynamically allocates at once the whole INI file into the heap, and the two structures IniStatistics and IniDispatch into the stack. All members of the INI file are then dispatched to the custom listener f_foreach(). Finally the allocated memory gets automatically freed.

diff --git a/docs/html/readme.html b/docs/html/readme.html index 7ceb155..d9ec61c 100644 --- a/docs/html/readme.html +++ b/docs/html/readme.html @@ -95,7 +95,8 @@

Sample usage

Installation

Despite the small footprint (34 kB of compiled binary using GCC), libconfini has been conceived as a shared library (but it may be used as a static library as well).

On most Unix-like systems, it is possible to install libconfini using the following common steps:

-
./configure
make
make install

An unofficial port of libconfini for Cygwin is also available.

+
./configure
make
make install

If the configure script is missing from your package you need to generate it by running the autogen.sh script. By default autogen.sh will also run the configure script immediately after having generated it, so you may directly type the make command directly after autogen.sh. To list different options use autogen.sh --help.

+

An unofficial port of libconfini for Cygwin is also available.

Free software

This library is free software. You can redistribute it and/or modify it under the terms of the GPL3 license. See COPYING for details.

diff --git a/docs/man/man3/IniDispatch.3 b/docs/man/man3/IniDispatch.3 index b328d41..116a1d5 100644 --- a/docs/man/man3/IniDispatch.3 +++ b/docs/man/man3/IniDispatch.3 @@ -1,4 +1,4 @@ -.TH "IniDispatch" 3 "Mon Oct 8 2018" "libconfini" \" -*- nroff -*- +.TH "IniDispatch" 3 "Fri Oct 12 2018" "libconfini" \" -*- nroff -*- .ad l .nh .SH NAME diff --git a/docs/man/man3/IniFormat.3 b/docs/man/man3/IniFormat.3 index e591587..6ac9cc5 100644 --- a/docs/man/man3/IniFormat.3 +++ b/docs/man/man3/IniFormat.3 @@ -1,4 +1,4 @@ -.TH "IniFormat" 3 "Mon Oct 8 2018" "libconfini" \" -*- nroff -*- +.TH "IniFormat" 3 "Fri Oct 12 2018" "libconfini" \" -*- nroff -*- .ad l .nh .SH NAME diff --git a/docs/man/man3/IniStatistics.3 b/docs/man/man3/IniStatistics.3 index 7b0f954..17e73c4 100644 --- a/docs/man/man3/IniStatistics.3 +++ b/docs/man/man3/IniStatistics.3 @@ -1,4 +1,4 @@ -.TH "IniStatistics" 3 "Mon Oct 8 2018" "libconfini" \" -*- nroff -*- +.TH "IniStatistics" 3 "Fri Oct 12 2018" "libconfini" \" -*- nroff -*- .ad l .nh .SH NAME diff --git a/docs/man/man3/confini.h.3 b/docs/man/man3/confini.h.3 index e397088..27f567d 100644 --- a/docs/man/man3/confini.h.3 +++ b/docs/man/man3/confini.h.3 @@ -1,4 +1,4 @@ -.TH "src/confini.h" 3 "Mon Oct 8 2018" "libconfini" \" -*- nroff -*- +.TH "src/confini.h" 3 "Fri Oct 12 2018" "libconfini" \" -*- nroff -*- .ad l .nh .SH NAME @@ -1628,6 +1628,14 @@ Parses an INI file and dispatches its content using a \fCFILE\fP structure as ar Zero for success, otherwise an error code (see \fCenum\fP \fC\fBConfiniInterruptNo\fP\fP) .RE .PP +The \fCini_file\fP parameter must be a \fCFILE\fP handle with read privileges\&. In some platforms, such as Microsoft Windows, it might be needed to add the binary specifier to the mode string (\fC'b'\fP) in order to prevent discrepancies between the physical size of the file and its computed size: +.PP +.PP +.nf +FILE * my_file = fopen("example\&.conf", "rb"); +.fi +.PP +.PP The function \fCf_init\fP will be invoked with two arguments: \fCstatistics\fP (a pointer to an \fC\fBIniStatistics\fP\fP object containing some properties about the file read) and \fCinit_other\fP (the custom argument \fCuser_data\fP previously passed)\&. If \fCf_init\fP returns a non-zero value the caller function will be interrupted\&. .PP The function \fCf_foreach\fP will be invoked with two arguments: \fCdispatch\fP (a pointer to an \fC\fBIniDispatch\fP\fP object containing the parsed member of the INI file) and \fCforeach_other\fP (the custom argument \fCuser_data\fP previously passed)\&. If \fCf_foreach\fP returns a non-zero value the caller function will be interrupted\&. @@ -1652,7 +1660,7 @@ static int callback (IniDispatch * dispatch, void * v_null) { int main () { - FILE * const ini_file = fopen("ini_files/example\&.conf", "r"); + FILE * const ini_file = fopen("ini_files/example\&.conf", "rb"); if (ini_file == NULL) { diff --git a/docs/man/man3/libconfini.3 b/docs/man/man3/libconfini.3 index f4be728..2142bdc 100644 --- a/docs/man/man3/libconfini.3 +++ b/docs/man/man3/libconfini.3 @@ -476,7 +476,7 @@ static int callback (IniDispatch * dispatch, void * v_null) { int main () { - FILE * const ini_file = fopen("ini_files/example\.conf", "r"); + FILE * const ini_file = fopen("ini_files/example\.conf", "rb"); if (ini_file == NULL) { diff --git a/docs/manual.html b/docs/manual.html index ced57cb..129e610 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -451,7 +451,7 @@

BASIC EXAMPLES

int main () { - FILE * const ini_file = fopen("ini_files/example.conf", "r"); + FILE * const ini_file = fopen("ini_files/example.conf", "rb"); if (ini_file == NULL) { diff --git a/examples/topics/load_ini_file.c b/examples/topics/load_ini_file.c index b461414..8921014 100644 --- a/examples/topics/load_ini_file.c +++ b/examples/topics/load_ini_file.c @@ -16,7 +16,7 @@ static int callback (IniDispatch * dispatch, void * v_null) { int main () { - FILE * const ini_file = fopen("ini_files/example.conf", "r"); + FILE * const ini_file = fopen("ini_files/example.conf", "rb"); if (ini_file == NULL) { diff --git a/package.json b/package.json index cfdf92e..6178d29 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libconfini", - "version": "1.7.1", + "version": "1.7.2", "description": "Yet another INI parser", "homepage": "https://madmurphy.github.io/libconfini/", "author": "madmurphy333@gmail.com", diff --git a/src/confini.c b/src/confini.c index 23f46e1..152fa37 100644 --- a/src/confini.c +++ b/src/confini.c @@ -1615,6 +1615,15 @@ static size_t further_cuts (char * const segment, const IniFormat format) { @return Zero for success, otherwise an error code (see `enum` `#ConfiniInterruptNo`) + The @p ini_file parameter must be a `FILE` handle with read privileges. In some + platforms, such as Microsoft Windows, it might be needed to add the binary + specifier to the mode string (`"b"`) in order to prevent discrepancies between + the physical size of the file and its computed size: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} + FILE * my_file = fopen("example.conf", "rb"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + The function @p f_init will be invoked with two arguments: `statistics` (a pointer to an `IniStatistics` object containing some properties about the file read) and `init_other` (the custom argument @p user_data previously passed). If @@ -2148,7 +2157,7 @@ int load_ini_path ( void * const user_data ) { - FILE * const ini_file = fopen(path, "r"); + FILE * const ini_file = fopen(path, "rb"); if (ini_file == NULL) {