From 863999caf6efd04d3181aa86e3bdccbb284a2824 Mon Sep 17 00:00:00 2001 From: madmurphy Date: Sat, 25 Sep 2021 02:12:16 +0100 Subject: [PATCH] Commit 152 - Code readability - Documentation - Examples --- .editorconfig | 4 +- AUTHORS | 2 +- ChangeLog | 14 +- INSTALL | 26 +- MANUAL.md | 251 +- Makefile.am | 3 +- NEWS | 5 + README | 2 +- autostuff/doxygen/doxyfile.conf | 3 +- autostuff/m4/not-autotools.m4 | 196 +- configure.ac | 22 +- dev/hackings/all/confini-metadata.c | 2 +- dev/hackings/all/confini-metadata.h | 2 +- dev/hackings/baremetal/README.md | 27 +- dev/hackings/baremetal/str2num.c | 43 +- dev/marked-sources/confini-marked.c | 3759 +++++++++-------- dev/marked-sources/confini-marked.h | 9 +- .../null-byte_injection/null-byte_injection.c | 2 +- .../null-byte_injection.sh | 4 +- dev/tests/performance/prepare.sh | 2 +- dev/tests/performance/sprepare.sh_ | 2 +- dev/tests/performance/unprepare.sh | 2 +- dev/tests/playground/extreme_ini.conf | 1 + dev/tests/playground/playground.c | 96 + dev/tests/playground/playground.sh | 9 + docs/html/baremetal.html | 47 +- docs/html/confini_8c.html | 468 +- docs/html/confini_8h.html | 466 +- docs/html/confini_8h_source.html | 847 ++-- docs/html/install.html | 8 +- docs/html/libconfini.html | 277 +- docs/html/readme.html | 14 +- docs/man/man3/IniDispatch.3 | 2 +- docs/man/man3/IniFormat.3 | 2 +- docs/man/man3/IniStatistics.3 | 2 +- docs/man/man3/confini.h.3 | 376 +- docs/man/man3/libconfini.3 | 177 +- docs/manual.html | 247 +- examples/cplusplus/generic.cpp | 5 +- examples/cplusplus/map.cpp | 5 + examples/ini_files/extreme_ini.conf | 10 +- examples/miscellanea/colon_as_delimiter.c | 23 +- examples/miscellanea/disambiguate.c | 23 +- examples/miscellanea/dispatch_everything.c | 28 +- examples/miscellanea/glib_hash_table.c | 7 +- examples/miscellanea/parse_foreign.c | 25 +- examples/miscellanea/stats_only.c | 21 +- examples/miscellanea/toml-like.c | 33 +- examples/miscellanea/typed_ini.c | 21 +- examples/topics/ini_array_break.c | 35 +- examples/topics/ini_array_collapse.c | 59 +- examples/topics/ini_array_foreach.c | 12 +- examples/topics/ini_array_release.c | 35 +- examples/topics/ini_array_shift.c | 35 +- examples/topics/ini_array_split.c | 10 +- .../topics/ini_global_set_implicit_value.c | 21 +- examples/topics/ini_string_match_si.c | 5 +- examples/topics/ini_string_parse.c | 21 +- examples/topics/load_ini_file.c | 22 +- examples/topics/load_ini_path.c | 21 +- examples/topics/strip_ini_cache.c | 23 +- examples/utilities/clone_ini_dispatch.h | 29 +- examples/utilities/ini_string_preparse.h | 2 +- examples/utilities/make_strarray.h | 34 +- package.json | 4 +- src/Makefile.am | 3 +- src/confini.c | 3729 ++++++++-------- src/confini.h | 9 +- src/winres.rc | 8 +- tests/autotest.c | 2 +- 70 files changed, 6362 insertions(+), 5379 deletions(-) create mode 120000 dev/tests/playground/extreme_ini.conf create mode 100644 dev/tests/playground/playground.c create mode 100755 dev/tests/playground/playground.sh diff --git a/.editorconfig b/.editorconfig index 264b45f..d5f2671 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,12 +4,12 @@ root = true indent_style = tab indent_size = 2 -[{src/confini.c,dev/marked-sources/confini-marked.c,**.sh,configure.ac,**/Makefile.am,**.m4}] +[{src/confini.c,dev/marked-sources/confini-marked.c,dev/hackings/baremetal/str2num.c,**.sh,configure.ac,**/Makefile.am,**.m4}] charset = utf-8 indent_style = tab indent_size = 4 -[{src/confini.h,dev/marked-sources/confini-marked.h}] +[{src/confini.h,dev/marked-sources/confini-marked.h,dev/hackings/baremetal/str2num.h}] charset = utf-8 indent_style = space indent_size = 4 diff --git a/AUTHORS b/AUTHORS index 6e4c4cf..513363c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -madmurphy333 AT gmail DOT com +madmurphy diff --git a/ChangeLog b/ChangeLog index ae5c175..3b1d5de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,16 @@ Change Log ========== +## 1.16.2 (2021-09-25) + +Changes: + +* Issue [#16](https://github.com/madmurphy/libconfini/issues/16) has been fixed +* Code readability +* Documentation +* Examples + + ## 1.16.1 (2021-06-14) Changes: @@ -151,8 +161,8 @@ Changes: source-image` and † `make authors-suitcase` targets, renamed † `make install-manifest` target to `make manifest`, created `make portable-builds` and `make oblivion-clean` targets, improved `install-data-hook` and all the - helper targets; `src/Makefile.am`: moved the `CFLAGS` automatically guessed by - `AC_PROG_CC_C99` to `AM_CFLAGS`) + helper targets; `src/Makefile.am`: moved the `CFLAGS` automatically guessed + by `AC_PROG_CC_C99` to `AM_CFLAGS`) * Added call to `strip.exe` to the `mgwmake.bat` script diff --git a/INSTALL b/INSTALL index 1ba6716..e816947 100644 --- a/INSTALL +++ b/INSTALL @@ -59,7 +59,7 @@ Microsoft Windows ### MinGW If you are using Microsoft Windows, a batch script for compiling **libconfini** -under MinGW without GNU Make is available (`mgwmake.bat`). If you want instead +with MinGW without GNU Make is available (`mgwmake.bat`). If you want instead to compile the library manually, you can run: cd src @@ -79,8 +79,9 @@ If you want to generate also the `.def` file, use: strip.exe libconfini.dll If you want to build (and install) **libconfini** via GNU Make under Microsoft -Windows several options are available, such as MinGW + MSYS, MSYS2, GnuWin32 -and Cygwin (for which [an unofficial port][1] of **libconfini** exists). +Windows several options are available, such as MinGW + MSYS, MSYS2 (which ships +[an official port][1] of the library, Cygwin (for which [an unofficial port][2] +of **libconfini** exists) and GnuWin32. ### Microsoft Visual Studio @@ -131,7 +132,7 @@ standard `extern` keyword is used to access a shared `.data` segment. ### Precompiled DLL -Often a compiled DLL [is available][2] among the assets of each release of this +Often a compiled DLL [is available][3] among the assets of each release of this package on GitHub. @@ -146,9 +147,9 @@ Library is simply too heavy or just not implementable. In these situations it will be needed to get rid of every tie with the C Standard Library and compile **libconfini** as "bare metal". The `configure` -script has a `--without-io-api` option that allows to create a special fork of -the original library able to function in any environment. For information about -how to proceed, please see `dev/hackings/baremetal/README.md`. +script has two options for creating special forks of the original library able to +function in any environment, `--without-io-api` and `--without-libc`. For +information about how to proceed, please see `dev/hackings/baremetal/README.md`. Complex installations @@ -178,7 +179,7 @@ package names of all versions that are older than the current version. If you want to install a modified version of **libconfini** without generating conflicts with an original version already present in the system, or you simply want to install **libconfini** under a different name, you can use [Autoconf -transforming rules][3]. In particular, to prepend a prefix to the library name, +transforming rules][4]. In particular, to prepend a prefix to the library name, use `./configure --program-prefix=[PREFIX]`; to append a suffix, use `./configure --program-suffix=[SUFFIX]`; to perform a `sed` substitution, use `./configure --program-transform-name="s/[OLDTEXT]/[NEWTEXT]/[g]"`. Note that @@ -199,7 +200,7 @@ For any issue, drop a message at https://github.com/madmurphy/libconfini/issues. Distributing the source code ---------------------------- -If you aim to re-distribute the source code of **libconfini** you should first +If you aim to re-distribute the source code of **libconfini** you must first make sure that the `configure` script is present, for granting the possibility to compile the package without having Autotools installed. If the `configure` script is present and you have already launched it, use `make distclean` to @@ -215,7 +216,8 @@ particular platform. If you want to obtain the list of the files that are going to be installed, use `make manifest`. - [1]: https://github.com/fd00/yacp/tree/master/libconfini - [2]: https://github.com/madmurphy/libconfini/releases - [3]: https://www.gnu.org/software/automake/manual/html_node/Renaming.html + [1]: https://packages.msys2.org/base/mingw-w64-libconfini + [2]: https://github.com/fd00/yacp/tree/master/libconfini + [3]: https://github.com/madmurphy/libconfini/releases + [4]: https://www.gnu.org/software/automake/manual/html_node/Renaming.html diff --git a/MANUAL.md b/MANUAL.md index 11d234d..f0cf946 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -46,12 +46,12 @@ email = mario.rossi@example.com ## Supported syntaxes -During the years several interpretations of INI files have appeared. In some -implementations the colon character (`:`) has been adopted as delimiter between -keys and values instead of the classic equals sign (a typical example under +During the years several interpretations of INI files appeared. In some +implementations the colon character (`:`) was adopted as delimiter between keys +and values instead of the classic equals sign (a typical example under GNU/Linux is `/etc/nsswitch.conf`); in other implementations, under the influence of Unix standard configuration files, a sequence of one or more -spaces (`/[ \t\v\f]+/` or `/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) has been used +spaces (`/[ \t\v\f]+/` or `/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) was adopted instead (see for example `/etc/host.conf`). Equals sign used as delimiter between keys and values: @@ -81,12 +81,12 @@ home Champ de Mars, 5 Avenue Anatole city Paris ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**libconfini** has been born as a general INI parser for **GNU**, so the -support of most part of INI dialects has been implemented within it. +**libconfini** was born as a general INI parser for **GNU**, so the support of +most part of INI dialects has been implemented within it. -Especially in **Microsoft Windows** a more radical syntax variation has been -implemented: the use of semicolon, instead of new lines, as delimiter between -nodes, as in the following example: +Especially in **Microsoft Windows** a more radical syntax variation found its +way into INI files: the use of semicolon, instead of new lines, as delimiter +between nodes, as in the following example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.ini} # delivery.conf @@ -389,7 +389,10 @@ INI file has been completely dispatched, non-zero otherwise. #include #include -static int my_callback (IniDispatch * dispatch, void * v_null) { +static int my_callback ( + IniDispatch * const dispatch, + void * const v_null +) { printf( "DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n", @@ -402,6 +405,7 @@ static int my_callback (IniDispatch * dispatch, void * v_null) { int main () { + /* Use always `"rb"` with `load_ini_file()`! */ FILE * const ini_file = fopen("../ini_files/delivery.conf", "rb"); if (ini_file == NULL) { @@ -411,13 +415,15 @@ int main () { } - if (load_ini_file( - ini_file, - INI_DEFAULT_FORMAT, - NULL, - my_callback, - NULL - )) { + if ( + load_ini_file( + ini_file, + INI_DEFAULT_FORMAT, + NULL, + my_callback, + NULL + ) + ) { fprintf(stderr, "Sorry, something went wrong :-(\n"); return 1; @@ -439,7 +445,10 @@ int main () { #include #include -static int my_callback (IniDispatch * dispatch, void * v_null) { +static int my_callback ( + IniDispatch * const dispatch, + void * const v_null +) { printf( "DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n", @@ -452,13 +461,15 @@ static int my_callback (IniDispatch * dispatch, void * v_null) { int main () { - if (load_ini_path( - "../ini_files/delivery.conf", - INI_DEFAULT_FORMAT, - NULL, - my_callback, - NULL - )) { + if ( + load_ini_path( + "../ini_files/delivery.conf", + INI_DEFAULT_FORMAT, + NULL, + my_callback, + NULL + ) + ) { fprintf(stderr, "Sorry, something went wrong :-(\n"); return 1; @@ -538,13 +549,30 @@ If you want to automatize the process of making a copy of a read-only buffer, strip and parse the copy, then free the allocated memory, you can use the following function: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} /* examples/utilities/load_ini_buffer.h */ #include #include #include +/** + + @brief Parse a `const` string containing an INI file + @param ini_buffer The buffer containing the INI file to + parse + @param ini_length The length of @p ini_buffer + @param format The format of the INI file + @param f_init The function that will be invoked before + the first dispatch, or `NULL` + + @param f_foreach The function that will be invoked for + each dispatch, or `NULL` + @param user_data A custom argument, or `NULL` + @return Zero for success, otherwise an error code (see `enum` + #ConfiniInterruptNo) + +**/ int load_ini_buffer ( const char * const ini_buffer, const size_t ini_length, @@ -576,7 +604,7 @@ int load_ini_buffer ( return retval; } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The function above can then be invoked directly on a `const` buffer: @@ -946,24 +974,68 @@ since this is the only escape sequence automatically unescaped by **libconfini** before each dispatch. +## Arrays + +It is possible with **libconfini** to parse INI strings as arrays. In order to +avoid that any particular character be treated as a metacharacter throughout an +entire configuration file, INI arrays do not have a fixed delimiter symbol +specified in the INI format. + +Abstractly speaking, this means that array delimiters are not part of the INI +syntax, but of the INI semantics instead. Concretely speaking, it means that +developers have to provide a delimiter as soon as they decide to parse an INI +string as an array. + +Out in the wild, the most widespread INI array delimiter is probably the space +sequence (`INI_ANY_SPACE` -- i.e. `/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/` or +`/[ \t\v\f]+/`, depending on whether the format is multi-line or not). Another +widespread delimiter is the comma (`','` or `INI_COMMA`). Besides these two, +occasionally other characters can be found as array delimiters (`':'`, `'|'`, +`';'`, ...). + +For iterating through an INI array using a delimiter **libconfini** provides +the following tools: + +* `ini_array_get_length()` +* `ini_array_foreach()` +* `ini_array_collapse()` +* `ini_array_break()` +* `ini_array_release()` +* `ini_array_shift()` +* `ini_array_split()` + +None of the functions above actually ever allocates any array, as +**libconfini** does not know what kind of data type an array should be composed +of – the developer might be looking for an array of strings, or an array of +integers, or anything else. These tools only provide safe mechanisms to iterate +through, or tokenize, the members of INI arrays according to the format and the +delimiter given -- making sure for example that when the delimiter symbol is +found nested within quotes it is treated as a normal character -- but +allocating memory is something that must be done manually. + +An example function that parses INI strings as newly allocated arrays of C +strings is available under `examples/utilities/make_strarray.h`. If your +program requires other data types (such as integers, booleans, etc.) you may +adapt that example to your needs. + + ## Editing the dispatched data -The strings dispatched, as already said, must not be freed. _Nevertheless, -before being copied or analyzed they can be edited, **with some precautions**_: +The strings dispatched, as already said, must not be freed. Nevertheless, +_before being copied or analyzed they can be edited, **with some precautions**_: 1. Be sure that your edit remains within the buffer lengths given (see `IniDispatch::d_len` and `IniDispatch::v_len`). -2. If you want to edit the content of `IniDispatch::data` and this contains a - section path, the `IniDispatch::append_to` properties of its children will - either share this buffer or will concatenate it to another buffer. Hence, if - you edit its content -- and depending on how you edit it -- you might no - more be able to rely on the `IniDispatch::append_to` properties of this - node's children. You would not make any damage, the loop will continue just - fine: so if you think you are never going to use the property - `IniDispatch::append_to`, just do it; alternatively, use `strndup()`. If - instead `IniDispatch::data` contains a key name or a comment, it is granted - that no other dispatch will share this buffer, so feel free to edit it - before it gets lost. +2. Do not edit the `IniDispatch::data` field of a section: the + `IniDispatch::append_to` properties of its children will either share this + buffer or will concatenate it to another buffer. Thus, if you edit its + content -- and depending on how you edit it -- you might be no more able to + rely on the `IniDispatch::append_to` properties of this node's children. You + would not make any damage, the loop will continue just fine: so if you think + you are never going to use the property `IniDispatch::append_to`, just do + it; alternatively, use `strndup()`. If instead `IniDispatch::data` contains + a key name or a comment, it is granted that no other dispatch will share + this buffer, so feel free to edit it before it gets lost. 3. Regarding `IniDispatch::value`, if it does not represent an implicit value (see **§ Implicit keys**) or if `IniFormat::implicit_is_not_empty` is set to `false`, this buffer is never shared between dispatches, so feel free to @@ -1001,7 +1073,10 @@ Typical peaceful edits are the ones obtained by calling the functions #include #include -static int ini_listener (IniDispatch * dispatch, void * v_null) { +static int ini_listener ( + IniDispatch * const dispatch, + void * const v_null +) { if ( dispatch->type == INI_KEY || dispatch->type == INI_DISABLED_KEY @@ -1025,13 +1100,15 @@ static int ini_listener (IniDispatch * dispatch, void * v_null) { int main () { - if (load_ini_path( - "../ini_files/self_explaining.conf", - INI_DEFAULT_FORMAT, - NULL, - ini_listener, - NULL - )) { + if ( + load_ini_path( + "../ini_files/self_explaining.conf", + INI_DEFAULT_FORMAT, + NULL, + ini_listener, + NULL + ) + ) { fprintf(stderr, "Sorry, something went wrong :-(\n"); return 1; @@ -1168,7 +1245,10 @@ its `value` property with the global variable `#INI_GLOBAL_IMPLICIT_VALUE`: #include #include -static int ini_listener (IniDispatch * dispatch, void * v_null) { +static int ini_listener ( + IniDispatch * const dispatch, + void * const v_null +) { if (dispatch->value == INI_GLOBAL_IMPLICIT_VALUE) { @@ -1207,13 +1287,15 @@ int main () { my_format.implicit_is_not_empty = true; my_format.disabled_can_be_implicit = true; - if (load_ini_path( - "../ini_files/unix-like.conf", - my_format, - NULL, - ini_listener, - NULL - )) { + if ( + load_ini_path( + "../ini_files/unix-like.conf", + my_format, + NULL, + ini_listener, + NULL + ) + ) { fprintf(stderr, "Sorry, something went wrong :-(\n"); return 1; @@ -1267,7 +1349,10 @@ due to a parsing error. #include #include -static int passfinder (IniDispatch * disp, void * v_membid) { +static int passfinder ( + IniDispatch * const disp, + void * const v_membid +) { /* Search for `password = "hello world"` in the INI file */ if ( @@ -1499,7 +1584,7 @@ return 0; ### Storing the dispatched data In order to be as flexible as possible, **libconfini** does not store the -dispatched data, nor indicizes them. This gives the developer the power to deal +dispatched data, nor indicizes them. This gives developers the power to deal with them in many different ways. For small INI files a normal if/else chain, using `ini_array_match()` for @@ -1687,14 +1772,13 @@ of the ASCII range always as case-sensitive. For this reason, **libconfini** (and probably any senseful INI parser) will never perform case folding of Unicode characters out of the ASCII range within key and section names. -It must be said however that most Unicode characters do not possess a lower and -upper case, and most characters outside of the ASCII range could theoretically -appear without problems in key and section names also in case-insensitive INI -files (think of the character `§` for example). And, as for case-sensitive INI -files, no Unicode character would ever represent a problem. Nonetheless, it is -still generally more acceptable to use ASCII only within key and section names --- and possibly, if needed, non-ASCII Unicode characters within values and -comments. +It must be said that most Unicode characters do not possess a lower and upper +case, and most characters outside of the ASCII range could theoretically appear +without problems in key and section names also in case-insensitive INI files +(think of the character `§` for example). And, as for case-sensitive INI files, +no Unicode character would ever represent a problem. Nonetheless, it is +generally more acceptable to use ASCII only within key and section names -- and +possibly, if needed, non-ASCII Unicode characters within values and comments. That said, **libconfini** deals perfectly fine with UTF-8 (but is always case-sensitive outside of the ASCII range), so use the latter as you feel @@ -1739,7 +1823,7 @@ character. For example, foo = "bar ~~~~~~~~~~ -will always determine the same behavior as if it were +will always determine the same behavior as if it had been ~~~~~~~~~~~{.ini} foo = "bar" @@ -1883,7 +1967,7 @@ If we tried to parse it according to the format used below static int ini_listener (IniDispatch * dispatch, void * v_null) { printf( - "#%zu - Type: %u; Data: \"%s\"; Value: \"%s\"\n", + "Node #%zu - Type: %u; Data: \"%s\"; Value: \"%s\"\n", dispatch->dispatch_id, dispatch->type, dispatch->data, @@ -1900,8 +1984,8 @@ int main () { ((IniFormat) { \ .delimiter_symbol = INI_EQUALS, \ .case_sensitive = false, \ - .semicolon_marker = INI_IGNORE, \ - .hash_marker = INI_IS_NOT_A_MARKER, \ + .semicolon_marker = INI_DISABLED_OR_COMMENT, \ + .hash_marker = INI_DISABLED_OR_COMMENT, \ .multiline_nodes = INI_NO_MULTILINE, \ .section_paths = INI_ABSOLUTE_ONLY, \ .no_single_quotes = false, \ @@ -1936,14 +2020,15 @@ int main () { we would obtain the following result: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: Content of "ambiguous.conf" :: -#0 - Type: 2; Data: "# INI KEY/VALUE DELIMITER: `"; Value: "`" -#1 - Type: 3; Data: "some_section"; Value: "" -#2 - Type: 2; Data: "hello"; Value: "world" -#3 - Type: 2; Data: "##now"; Value: "Sunday April 3rd, 2016" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Node #0 - Type: 6; Data: "INI KEY/VALUE DELIMITER: `"; Value: "`" +Node #1 - Type: 3; Data: "some_section"; Value: "" +Node #2 - Type: 2; Data: "hello"; Value: "world" +Node #3 - Type: 6; Data: "foo"; Value: "bar" +Node #4 - Type: 4; Data: "now=Sunday April 3rd, 2016"; Value: "" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As you can see, all comments but `now=Sunday April 3rd, 2016` would be parsed as disabled entries -- which is not what the author intended. Therefore, to @@ -1974,15 +2059,15 @@ hello = world we obtain the wanted result: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: Content of "ambiguous.conf" :: -#0 - Type: 4; Data: " INI KEY/VALUE DELIMITER: `=`"; Value: "" -#1 - Type: 3; Data: "some_section"; Value: "" -#2 - Type: 2; Data: "hello"; Value: "world" -#3 - Type: 6; Data: "foo"; Value: "bar" -#4 - Type: 4; Data: "now=Sunday April 3rd, 2016"; Value: "" -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Node #0 - Type: 4; Data: " INI KEY/VALUE DELIMITER: `=`"; Value: "" +Node #1 - Type: 3; Data: "some_section"; Value: "" +Node #2 - Type: 2; Data: "hello"; Value: "world" +Node #3 - Type: 6; Data: "foo"; Value: "bar" +Node #4 - Type: 4; Data: "now=Sunday April 3rd, 2016"; Value: "" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **2. Intervene on the format.** There are cases where the INI file is automatically generated by machines (comments included), or distributed as diff --git a/Makefile.am b/Makefile.am index 32bd2ed..f5c2166 100644 --- a/Makefile.am +++ b/Makefile.am @@ -172,8 +172,7 @@ MOSTLYCLEANFILES = \ CLEANFILES = \ dev/tests/null-byte_injection/null-byte_injected.conf \ dev/tests/performance/big_file.ini \ - dev/tests/performance/speedtest \ - configure~ + dev/tests/performance/speedtest # Shell expansion is supported here _bootstrapclean_dirs_ = \ diff --git a/NEWS b/NEWS index 4c1aca6..308aa37 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ News ==== +## 1.16.2 + +* Issue [#16](https://github.com/madmurphy/libconfini/issues/16) has been fixed + + ## 1.16.1 * A batch script for compiling **libconfini** under **Microsoft Windows** with diff --git a/README b/README index 2d37a99..fe5ada1 100644 --- a/README +++ b/README @@ -169,7 +169,7 @@ by running the `bootstrap` script. By default, `bootstrap` will also run the If you are using **Microsoft Windows**, a batch script for compiling **libconfini** with [MinGW][7] without Bash is available (`mgwmake.bat`). If -you are interested in using GNU Make for compiling **libconfini** under +you are interested in using **GNU Make** for compiling **libconfini** under Microsoft Windows, you can integrate MinGW with [MSYS][8], or you can directly use [MSYS2][9] and [its official port][10] of the library. Alternatively, [an unofficial port][11] of **libconfini** for [Cygwin][12] is available. diff --git a/autostuff/doxygen/doxyfile.conf b/autostuff/doxygen/doxyfile.conf index 87735e3..4e2e187 100644 --- a/autostuff/doxygen/doxyfile.conf +++ b/autostuff/doxygen/doxyfile.conf @@ -968,7 +968,8 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = _LIBCONFINI_* \ +EXCLUDE_SYMBOLS = _CONFINI_* \ + _LIBCONFINI_* \ __* # The EXAMPLE_PATH tag can be used to specify one or more files or directories diff --git a/autostuff/m4/not-autotools.m4 b/autostuff/m4/not-autotools.m4 index 27c5d8e..0706c94 100644 --- a/autostuff/m4/not-autotools.m4 +++ b/autostuff/m4/not-autotools.m4 @@ -33,15 +33,16 @@ dnl dnl From: not-autotools/m4/not-m4sugar.m4 dnl m4_define([n4_case_in], - [m4_cond([m4_eval([$# < 2])], [1], - [], - [m4_argn([1], $2)], [$1], + [m4_if([$#], [0], [], [$#], [1], [], [$#], [2], [], + [m4_if(m4_argn([1], $2), [$1], [$3], - [m4_eval(m4_count($2)[ > 1])], [1], - [n4_case_in([$1], m4_dquote(m4_shift($2)), m4_shift2($@))], - [m4_eval([$# > 4])], [1], - [n4_case_in([$1], m4_shift3($@))], - [$4])]) + [m4_if(m4_count($2), [1], + [m4_if([$#], [3], [], [$#], [4], + [$4], + [n4_case_in([$1], m4_shift3($@))])], + [n4_case_in([$1], + m4_dquote(m4_shift($2)), + m4_shift2($@))])])])]) dnl n4_mem([macro-name1[, macro-name2[, ... macro-nameN]]], value) @@ -304,97 +305,106 @@ dnl From: not-autotools/m4/not-extended-config.m4 dnl AC_DEFUN_ONCE([NC_CONFIG_SHADOW_DIR], [ - AC_REQUIRE([AC_PROG_LN_S]) - m4_define([NC_SHADOW_DIR], [$1]) - m4_define([NC_CONFNEW_SUBDIR], [confnew]) - m4_define([NC_THREATENED_LIST], []) - AC_SUBST([confnewdir], [']NC_CONFNEW_SUBDIR[']) - - AC_ARG_ENABLE([extended-config], - [AS_HELP_STRING([--enable-extended-config@<:@=MODE@:>@], - [extend the configure process to files that normally do not need - to be re-configured, as their final content depends on upstream - changes only and not on the state of this machine; possible values - for MODE are: omitted or "yes" or "merge" for updating these files - immediately, "sandbox" for safely putting their updated version - into the `]m4_quote(NC_CONFNEW_SUBDIR)[` directory without modifying - the package tree, or "no" for doing nothing @<:@default=no@:>@])], - [AS_IF([test "x${enableval}" = x -o "x${enableval}" = xyes], - [AS_VAR_SET([enable_extended_config], ['merge'])], - [test "x${enableval}" != xsandbox -a "x${enableval}" != xmerge], [ - AS_VAR_SET([enable_extended_config], ['no']) - AC_MSG_WARN([unrecognized option: --enable-extended-config='${enableval}']) - ])], - [AS_VAR_SET([enable_extended_config], ['no'])]) - - AM_CONDITIONAL([HAVE_EXTENDED_CONFIG], [test "x${enable_extended_config}" != xno]) - AM_CONDITIONAL([HAVE_UPDATES], [test "x${enable_extended_config}" = xsandbox]) - - AM_COND_IF([HAVE_EXTENDED_CONFIG], [ - AS_MKDIR_P(["]m4_quote(NC_CONFNEW_SUBDIR)["]) - AC_CONFIG_COMMANDS([extended-config], [ - AS_IF([test "x${extconfmode}" = xmerge], [ - AS_VAR_SET([abs_srcdir], ["$(cd "${srcdir}" && pwd)"]) - echo "${threatlist}" | while read -r _FILE_; do - mv "NC_CONFNEW_SUBDIR/${_FILE_}" "${srcdir}/${_FILE_}" && \ - (cd "$(dirname "NC_CONFNEW_SUBDIR/${_FILE_}")" && \ - ${LN_S} "${abs_srcdir}/${_FILE_}" "$(basename "NC_CONFNEW_SUBDIR/${_FILE_}")") - done - AC_MSG_NOTICE([extended configuration has been merged with the package tree.]) - AS_UNSET([abs_srcdir]) - ], [ - AC_MSG_NOTICE([extended configuration has been saved in ./NC_CONFNEW_SUBDIR.]) - ]) - AS_UNSET([threatlist]) - AS_UNSET([extconfmode]) +AC_REQUIRE([AC_PROG_LN_S]) +m4_define([NC_SHADOW_DIR], [$1]) +m4_define([NC_CONFNEW_SUBDIR], [confnew]) +m4_define([NC_THREATENED_LIST], []) +AC_SUBST([confnewdir], [']NC_CONFNEW_SUBDIR[']) + +AC_ARG_ENABLE([extended-config], + [AS_HELP_STRING([--enable-extended-config@<:@=MODE@:>@], + [extend the configure process to files that normally do not need + to be re-configured, as their final content depends on upstream + changes only and not on the state of this machine; possible values + for MODE are: omitted or "yes" or "merge" for updating these files + immediately, "sandbox" for safely putting their updated version + into the `]m4_quote(NC_CONFNEW_SUBDIR)[` directory without modifying + the package tree, or "no" for doing nothing @<:@default=no@:>@])], + [AS_IF([test "x${enableval}" = x -o "x${enableval}" = xyes], + [AS_VAR_SET([enable_extended_config], ['merge'])], + [test "x${enableval}" != xsandbox -a "x${enableval}" != xmerge], [ + AS_VAR_SET([enable_extended_config], ['no']) + AC_MSG_WARN([unrecognized option: --enable-extended-config='${enableval}']) + ])], + [AS_VAR_SET([enable_extended_config], ['no'])]) + +AM_CONDITIONAL([HAVE_EXTENDED_CONFIG], [test "x${enable_extended_config}" != xno]) +AM_CONDITIONAL([HAVE_UPDATES], [test "x${enable_extended_config}" = xsandbox]) + +AM_COND_IF([HAVE_EXTENDED_CONFIG], [ + AS_MKDIR_P(["]m4_quote(NC_CONFNEW_SUBDIR)["]) + AC_CONFIG_COMMANDS([extended-config], [ + AS_IF([test "x${extconfmode}" = xmerge], [ + AS_VAR_SET([abs_srcdir], ["$(cd "${srcdir}" && pwd)"]) + echo "${threatlist}" | while read -r _FILE_; do + mv "NC_CONFNEW_SUBDIR/${_FILE_}" "${srcdir}/${_FILE_}" && \ + (cd "$(dirname "NC_CONFNEW_SUBDIR/${_FILE_}")" && \ + ${LN_S} "${abs_srcdir}/${_FILE_}" "$(basename "NC_CONFNEW_SUBDIR/${_FILE_}")") + done + AC_MSG_NOTICE([extended configuration has been merged with the package tree.]) + AS_UNSET([abs_srcdir]) ], [ - AS_VAR_SET([extconfmode], ['${enable_extended_config}']) - AS_VAR_SET([threatlist], ['${nc_threatlist}']) + AC_MSG_NOTICE([extended configuration has been saved in ./NC_CONFNEW_SUBDIR.]) ]) + AS_UNSET([threatlist]) + AS_UNSET([extconfmode]) + ], [ + AS_VAR_SET([extconfmode], ['${enable_extended_config}']) + AS_VAR_SET([threatlist], ['${nc_threatlist}']) ]) +]) - dnl NC_THREATEN_FILES(file1[, file2[, file3[, ... fileN]]]) - dnl ********************************************************************** - AC_DEFUN([NC_THREATEN_FILES], [ - AM_COND_IF([HAVE_EXTENDED_CONFIG], [ - AC_CONFIG_FILES(m4_foreach([_F_ITER_], m4_dquote(]m4_dquote(m4_map_args_sep([m4_normalize(], [)], [,], ][$][@][))[), - [m4_ifnblank(m4_quote(_F_ITER_), - [n4_case_in(m4_quote(_F_ITER_), m4_quote(NC_THREATENED_LIST), - [n4_case_in(m4_quote(_F_ITER_), m4_quote(NC_SHADOW_REDEF), [], - [m4_define([NC_SHADOW_REDEF], - m4_ifset([NC_SHADOW_REDEF], - [m4_dquote(NC_SHADOW_REDEF,[ ]_F_ITER_)], - [m4_dquote(_F_ITER_)]))])], - [m4_define([NC_THREATENED_LIST], - m4_ifset([NC_THREATENED_LIST], - [m4_dquote(NC_THREATENED_LIST, _F_ITER_)], - [m4_dquote(_F_ITER_)])) - m4_quote(NC_CONFNEW_SUBDIR[/]_F_ITER_[:]NC_SHADOW_DIR[/]_F_ITER_[.in])])])])) - ]) - AS_VAR_SET([nc_threatlist], ["]m4_join(m4_newline(), NC_THREATENED_LIST)["]) - m4_ifdef([NC_SHADOW_REDEF], - [m4_warn([syntax], [redefined threatened files ]m4_quote(NC_SHADOW_REDEF)[ - skip])]) +dnl NC_THREATEN_FILES(file1[, file2[, file3[, ... fileN]]]) +dnl ********************************************************************** +AC_DEFUN([NC_THREATEN_FILES], [ + AM_COND_IF([HAVE_EXTENDED_CONFIG], [ + AC_CONFIG_FILES(m4_foreach([_F_ITER_], m4_dquote(]m4_dquote(m4_map_args_sep([m4_normalize(], [)], [,], ][$][@][))[), + [m4_ifnblank(m4_quote(_F_ITER_), + [n4_case_in(m4_quote(_F_ITER_), m4_quote(NC_THREATENED_LIST), + [n4_case_in(m4_quote(_F_ITER_), m4_quote(NC_SHADOW_REDEF), [], + [m4_define([NC_SHADOW_REDEF], + m4_ifset([NC_SHADOW_REDEF], + [m4_dquote(NC_SHADOW_REDEF,[ ]_F_ITER_)], + [m4_dquote(_F_ITER_)]))])], + [m4_define([NC_THREATENED_LIST], + m4_ifset([NC_THREATENED_LIST], + [m4_dquote(NC_THREATENED_LIST, _F_ITER_)], + [m4_dquote(_F_ITER_)])) + m4_quote(NC_CONFNEW_SUBDIR[/]_F_ITER_[:]NC_SHADOW_DIR[/]_F_ITER_[.in])])])])) ]) + AS_VAR_SET([nc_threatlist], ["]m4_join(m4_newline(), NC_THREATENED_LIST)["]) + m4_ifdef([NC_SHADOW_REDEF], + [m4_warn([syntax], [redefined threatened files ]m4_quote(NC_SHADOW_REDEF)[ - skip])]) +]) - dnl NC_THREATEN_BLINDLY - dnl ********************************************************************** - AC_DEFUN_ONCE([NC_THREATEN_BLINDLY], - [NC_THREATEN_FILES(m4_shift(m4_bpatsubst(m4_quote(m4_esyscmd([find ']m4_quote(NC_SHADOW_DIR)[' -type f -name '*.in' -printf ", [[%P{/@/}]]"])), [\.in{/@/}], [])))]) - - dnl NC_SHADOW_AFTER_OUTPUT[(if-merge-cmds[, if-sandbox-cmds])] - dnl ********************************************************************** - AC_DEFUN_ONCE([NC_SHADOW_AFTER_OUTPUT], - [m4_ifset([NC_THREATENED_LIST], - [m4_ifnblank(m4_quote(]m4_dquote(][$][1][$][2][)[), - [AM_COND_IF([HAVE_UPDATES], - m4_ifblank(m4_quote(]m4_dquote(]m4_dquote(][$][2][)[)[), - [[:]], - [[m4_expand(m4_argn([2], - ]m4_dquote(]m4_dquote(]m4_dquote(]m4_dquote(][$][@][)[)[)[)[))]])[]m4_ifnblank(m4_quote(]m4_dquote(]m4_dquote(][$][1][)[)[), [, - [AM_COND_IF([HAVE_EXTENDED_CONFIG], - [m4_expand(m4_argn([1], - ]m4_dquote(]m4_dquote(]m4_dquote(]m4_dquote(]m4_dquote(][$][@][)[)[)[)[)[))])]]))])], - [m4_warn([syntax], [NC_CONFIG_SHADOW_DIR has been invoked but no files have been threatened.])])]) +dnl NC_THREATEN_BLINDLY() +dnl ********************************************************************** +AC_DEFUN_ONCE([NC_THREATEN_BLINDLY], + [NC_THREATEN_FILES(m4_shift(m4_bpatsubst(m4_quote(m4_esyscmd([find ']m4_quote(NC_SHADOW_DIR)[' -type f -name '*.in' -printf ", [[%P{/@/}]]"])), [\.in{/@/}], [])))]) + +dnl NC_SHADOW_AFTER_OUTPUT[(if-merge-cmds[, if-sandbox-cmds])] +dnl ********************************************************************** +dnl +dnl Example: +dnl +dnl NC_SHADOW_AFTER_OUTPUT([ +dnl AC_MSG_NOTICE([updating the source code with `${ac_make} all-official-sources`...]) +dnl "${ac_make}" all-official-sources +dnl ]) +dnl +dnl ********************************************************************** +AC_DEFUN_ONCE([NC_SHADOW_AFTER_OUTPUT], + [m4_ifset([NC_THREATENED_LIST], + [m4_ifnblank(m4_quote(]m4_dquote(][$][1][$][2][)[), + [AM_COND_IF([HAVE_UPDATES], + m4_ifblank(m4_quote(]m4_dquote(]m4_dquote(][$][2][)[)[), + [[:]], + [[m4_expand(m4_argn([2], + ]m4_dquote(]m4_dquote(]m4_dquote(]m4_dquote(][$][@][)[)[)[)[))]])[]m4_ifnblank(m4_quote(]m4_dquote(]m4_dquote(][$][1][)[)[), [, + [AM_COND_IF([HAVE_EXTENDED_CONFIG], + [m4_expand(m4_argn([1], + ]m4_dquote(]m4_dquote(]m4_dquote(]m4_dquote(]m4_dquote(][$][@][)[)[)[)[)[))])]]))])], + [m4_warn([syntax], [NC_CONFIG_SHADOW_DIR has been invoked but no files have been threatened.])])]) ]) diff --git a/configure.ac b/configure.ac index 17516a2..670ad8d 100644 --- a/configure.ac +++ b/configure.ac @@ -29,15 +29,15 @@ AC_INIT([lib]n4_mem([GL_PROJECT_NAME], [confini]), m4_joinall([.], n4_mem([GL_PROJECT_MAJVER], [1]), n4_mem([GL_PROJECT_MINVER], [16]), - n4_mem([GL_PROJECT_REVVER], [1])), + n4_mem([GL_PROJECT_REVVER], [2])), [madmurphy333@gmail.com], [lib]GL_PROJECT_NAME, [https://madmurphy.github.io/libconfini]) NC_GLOBAL_LITERALS( [INTERFACE_NUM], [5], - [IMPLEMENTATION_NUM], [0], [INTERFACES_SUPPORTED], [5], + [IMPLEMENTATION_NUM], [1], [PROJECT_DESCRIPTION], [Yet another INI parser], [LICENSE_STRING], [GNU General Public License, version 3 or any later version], @@ -248,7 +248,7 @@ AS_CASE(["${na_tmp_ioflavor}"], [NC_MSG_WARNBOX([It is strongly recommended to rename the package when compiling it without a I/O API (--without-io-api). For example, to rename `]AC_PACKAGE_TARNAME[` to - `lib]GL_PROJECT_NAME[-baremetal`, use `./configure --without-io-api + `]AC_PACKAGE_TARNAME[-baremetal` use `./configure --without-io-api --program-suffix='-baremetal'`. Type `./configure --help` for more information about renaming rules.])]) AS_VAR_SET([na_want_baremetal], ['yes']) @@ -686,7 +686,7 @@ AM_COND_IF([HAVE_EXTENDED_CONFIG], [ AS_VAR_SET([mergenew_recipe], m4_normalize([ 'echo '\''**Warning** Extended configuration has been - called on a renamed package. All'\'' && echo '\''updates + invoked on a renamed package. All'\'' && echo '\''updates will be reverted with `make clean` and will not be re-distributed with'\'' && echo '\''`make dist`!'\''; ]m4_foreach([__i__], [NC_THREATENED_LIST], [[ @@ -726,9 +726,9 @@ AM_COND_IF([HAVE_EXTENDED_CONFIG], [ the updates see the content of `./$(confnewdir)`).'\' ])) AM_COND_IF([RENAME_PACKAGE], [ - NC_MSG_WARNBOX([Extended configuration has been called on a renamed - package. Changes will be reverted with `make distclean` and will - not be re-distributed with `make dist`!]) + NC_MSG_WARNBOX([Extended configuration has been invoked on a + renamed package. Changes will be reverted with `make distclean` and + will not be re-distributed with `make dist`!]) m4_foreach([__i__], [NC_THREATENED_LIST], [test -f "${srcdir}/]__i__[.dist" || \ cp "${srcdir}/]__i__[" "${srcdir}/]__i__[.dist";]) @@ -933,13 +933,13 @@ NA_HELP_STRINGS( [launch `make uninstall` followed by `make clean`], [[make alldone]], [launch `make install-strip` followed by `make installcheck` - in case - of staged installations it is possible to pass a `DESTDIR` variable (see - below)], + of staged installations it is possible to pass a `DESTDIR` variable + (see below)], [[make binary-release], [make manifest]], [create respectively a package and a manifest in the current location containing all the files that would be installed by `make - install-strip` - if `make (all)` has not been launched yet, it will be - launched first], + install(-strip)` - if `make (all)` has not been launched yet, it will + be launched first], [[make portable-builds]], [create a package containing all the files that would be installed by `make install-exec-strip`, but without any directory structure - if diff --git a/dev/hackings/all/confini-metadata.c b/dev/hackings/all/confini-metadata.c index fb52c4f..61fc756 100644 --- a/dev/hackings/all/confini-metadata.c +++ b/dev/hackings/all/confini-metadata.c @@ -4,7 +4,7 @@ @brief libconfini functions @author Stefano Gioffré @copyright GNU General Public License, version 3 or any later version - @version 1.16.1 + @version 1.16.2 @date 2016-2021 @see https://madmurphy.github.io/libconfini diff --git a/dev/hackings/all/confini-metadata.h b/dev/hackings/all/confini-metadata.h index bd30475..9425d79 100644 --- a/dev/hackings/all/confini-metadata.h +++ b/dev/hackings/all/confini-metadata.h @@ -4,7 +4,7 @@ @brief libconfini header @author Stefano Gioffré @copyright GNU General Public License, version 3 or any later version - @version 1.16.1 + @version 1.16.2 @date 2016-2021 @see https://madmurphy.github.io/libconfini diff --git a/dev/hackings/baremetal/README.md b/dev/hackings/baremetal/README.md index 061ad69..3fe0c6d 100644 --- a/dev/hackings/baremetal/README.md +++ b/dev/hackings/baremetal/README.md @@ -1,12 +1,12 @@ Compiling without I/O {#baremetal} ================================== -Almost everything in **libconfini** is implemented from scratch, with the only +In **libconfini** almost everything is implemented from scratch, with the only notable exception of the I/O functions `load_ini_file()` and `load_ini_path()`, -which rely on standard libraries (either the C Standard or the POSIX Standard, -depending on the build settings). On some platforms, however, only a rather -exotic I/O API is available, while for some other platforms the C Standard -Library is simply too heavy or just not implementable. +which rely on standard libraries -- either the C Standard or the POSIX +Standard, depending on the build settings. On some platforms, however, only a +rather exotic I/O API is available, while for some other platforms the C +Standard Library is simply too heavy or just not implementable. In the past, the build environment of **libconfini** did not offer shortcuts for facing this kind of situations -- although, thanks to the modularity of the @@ -33,7 +33,7 @@ equivalently, with `--with-io-api=baremetal`), it assumes that no standard library at all could be present in the system. Hence it runs a series of tests and creates an inventory of what is present and what is not, in order to amend the source code accordingly -- to ignore all the tests and assume that -literally nothing from the C Standard Library is supported use +literally nothing from the C Standard Library is supported, use `--without-libc`. The amendments are necessary (instead of just relying on the C preprocessor) because it is required to change the public header, not just the compiled code. @@ -46,15 +46,15 @@ applied when launching `make all` or `make baremetal-source-code` after having launched `./configure --without-io-api` (the original source code will be preserved). -The file `str2num.c` constitutes a re-implementation of the functions +The `str2num.c` file contains re-implementation of the functions `ini_get_int()`, `ini_get_lint()`, `ini_get_llint()`, `ini_get_float()` and `ini_get_double()`, which in the original code are implemented as pointers to standard functions (see below). This file amends `src/confini.c`. -The file `str2num.h`, which amends `src/confini.h` (i.e. the public header), +The `str2num.h` file, which amends `src/confini.h` (i.e. the public header), exports the function headers of what `str2num.c` implements. -The file `confini-header.c` contains only a nominal workaround-amendment to +The `confini-header.c` file contains only a nominal workaround-amendment to `src/confini.c` (for facilitating the build system) that does not change the final C code compiled. @@ -83,7 +83,7 @@ The first four files (the ones located in the `dev/hackings/baremetal` subdirectory) are static and do not need any intervention from the user, unless (s)he wants to participate in the development of **libconfini**. The fifth file _might_ require manual intervention in some situations, depending on the -platform or on the user's choice (the build system will emit a warning in such +platform or the user's will (the build system will emit a warning in such cases). @@ -95,9 +95,10 @@ some kind of filesystem. If the C standard `fopen()`, `fseek()`, `ftell()`, `rewind()`, `fread()` and `fclose()` do not suit your needs, you can re-implement your own version of `load_ini_file()` and `load_ini_path()`. The only requirement is that at the end of the day you find a way to pass a -disposable buffer containing an entire INI file to `strip_ini_cache()`. A good -way to proceed is to hack the original pair of functions that rely on the C -standard I/O API and adapt them to your platform. +disposable buffer containing an entire INI file to `strip_ini_cache()`. + +A good way to proceed is to hack the original pair of functions that rely on +the C standard I/O API and adapt them to your platform: `````````````````````````````````````````````````````````````````````````` c #include diff --git a/dev/hackings/baremetal/str2num.c b/dev/hackings/baremetal/str2num.c index 2384f52..77f2047 100644 --- a/dev/hackings/baremetal/str2num.c +++ b/dev/hackings/baremetal/str2num.c @@ -1,4 +1,4 @@ -#define _LIBCONFINI_RADIX_POINT_ '.' +#define _CONFINI_RADIX_POINT_ '.' #define __INTEGER_DATA_TYPE__ 0 #define __FLOAT_DATA_TYPE__ 1 @@ -15,7 +15,7 @@ Mask `abcd` (6 bits used): FLAG_32 The number is negative */ -#define _LIBCONFINI_STR2NUM_FNBODY_(HAS_RADIX_PT, DATA_TYPE, STR) \ +#define _CONFINI_STR2NUM_FNBODY_(HAS_RADIX_PT, DATA_TYPE, STR) \ register uint_least8_t abcd = 9; \ register size_t idx = 0; \ register DATA_TYPE retval = 0; \ @@ -23,20 +23,21 @@ Mask `abcd` (6 bits used): DATA_TYPE fact = 1; \ ) \ do { \ - abcd = STR[idx] > 47 && STR[idx] < 58 ? \ - abcd | 18 \ - : !(abcd & 6) && STR[idx] == '-' ? \ - (abcd & 47) | 36 \ - : !(abcd & 6) && STR[idx] == '+' ? \ - (abcd & 15) | 4 \ - __PP_IIF__(HAS_RADIX_PT, \ - : (abcd & 8) && STR[idx] == _LIBCONFINI_RADIX_POINT_ ? \ - (abcd & 39) | 2 \ - ) \ - : !(abcd & 2) && is_some_space(STR[idx], _LIBCONFINI_WITH_EOL_) ? \ - (abcd & 47) | 1 \ - : \ - abcd & 46; \ + abcd = \ + STR[idx] > 47 && STR[idx] < 58 ? \ + abcd | 18 \ + : !(abcd & 6) && STR[idx] == '-' ? \ + (abcd & 47) | 36 \ + : !(abcd & 6) && STR[idx] == '+' ? \ + (abcd & 15) | 4 \ + __PP_IIF__(HAS_RADIX_PT, \ + : (abcd & 8) && STR[idx] == _CONFINI_RADIX_POINT_ ? \ + (abcd & 39) | 2 \ + ) \ + : !(abcd & 2) && is_some_space(STR[idx], _CONFINI_WITH_EOL_) ? \ + (abcd & 47) | 1 \ + : \ + abcd & 46; \ if (abcd & 16) { \ retval = __PP_IIF__(HAS_RADIX_PT, \ abcd & 8 ? \ @@ -52,25 +53,25 @@ Mask `abcd` (6 bits used): int ini_get_int (const char * const ini_string) { - _LIBCONFINI_STR2NUM_FNBODY_(__INTEGER_DATA_TYPE__, int, ini_string); + _CONFINI_STR2NUM_FNBODY_(__INTEGER_DATA_TYPE__, int, ini_string); } long int ini_get_lint (const char * const ini_string) { - _LIBCONFINI_STR2NUM_FNBODY_(__INTEGER_DATA_TYPE__, long int, ini_string); + _CONFINI_STR2NUM_FNBODY_(__INTEGER_DATA_TYPE__, long int, ini_string); } long long int ini_get_llint (const char * const ini_string) { - _LIBCONFINI_STR2NUM_FNBODY_(__INTEGER_DATA_TYPE__, long long int, ini_string); + _CONFINI_STR2NUM_FNBODY_(__INTEGER_DATA_TYPE__, long long int, ini_string); } float ini_get_float (const char * const ini_string) { - _LIBCONFINI_STR2NUM_FNBODY_(__FLOAT_DATA_TYPE__, float, ini_string); + _CONFINI_STR2NUM_FNBODY_(__FLOAT_DATA_TYPE__, float, ini_string); } double ini_get_double (const char * const ini_string) { - _LIBCONFINI_STR2NUM_FNBODY_(__FLOAT_DATA_TYPE__, double, ini_string); + _CONFINI_STR2NUM_FNBODY_(__FLOAT_DATA_TYPE__, double, ini_string); } diff --git a/dev/marked-sources/confini-marked.c b/dev/marked-sources/confini-marked.c index 8821205..c9acf63 100644 --- a/dev/marked-sources/confini-marked.c +++ b/dev/marked-sources/confini-marked.c @@ -1,11 +1,11 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* Please make sure that the TAB width in your editor is set to 4 spaces */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !START_OMISSION! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !START_OMISSION! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- This is a marked **exact copy** of `src/confini.c`, in which replaceable sections have been wrapped within special tags that can be parsed and amended by GNU Make -during the build process in order to create custom forks of the library. +during the build process, in order to create custom forks of the library. If you want to contribute to the development of this project, please **use this file**, as `src/confini.c` is automatically generated from here. @@ -16,8 +16,8 @@ For more information about the tags used here, please see the `NA_AMEND()` macro The code below is distributed under the terms of the GPL license version 3 or any later version. --@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !END_OMISSION! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@ !ENTRY_POINT(CONFINI_C_METADATA)! @@@@@@@@@@@@@@@@@@@@@@*/ +-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !END_OMISSION! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@ !ENTRY_POINT(CONFINI_C_METADATA)! @@@@@@@@@@@@@@@@@@@@@@@*/ /*/| @@ -34,7 +34,7 @@ later version. /** - @def INIFORMAT_TABLE_AS(_____) + @def INIFORMAT_TABLE_AS(_____) Content of the table: @@ -44,200 +44,200 @@ later version. - @typedef int (* IniStatsHandler) ( - IniStatistics * statistics, - void * user_data - ) - - @param statistics - A pointer to the #IniStatistics to handle - @param user_data - The custom argument previously passed to the caller function - - - - @typedef int (* IniDispHandler) ( - IniDispatch *dispatch, - void * user_data - ) - - @param dispatch - A pointer to the #IniDispatch to handle - @param user_data - The custom argument previously passed to the caller function - - - - @typedef int (* IniStrHandler) ( - char * ini_string, - size_t string_length, - size_t string_num, - IniFormat format, - void * user_data - ) - - @param ini_string - The INI string to handle - @param string_length - The length of the INI string in bytes - @param string_num - The unique number that identifies @p ini_string within a - sequence of INI strings; it equals zero if @p ini_string is the - first or the only member of the sequence - @param format - The format of the INI file from which @p ini_string has been - extracted - @param user_data - The custom argument previously passed to the caller function - - - - @typedef int (* IniSubstrHandler) ( - const char * ini_string, - size_t fragm_offset, - size_t fragm_length, - size_t fragm_num, - IniFormat format, - void * user_data - ) - - @param ini_string - The INI string containing the fragment to handle - @param fragm_offset - The offset of the selected fragment in bytes - @param fragm_length - The length of the selected fragment in bytes - @param fragm_num - The unique number that identifies the selected fragment within a - sequence of fragments of @p ini_string; it equals zero if the - fragment is the first or the only member of the sequence - @param format - The format of the INI file from which @p ini_string has been - extracted - @param user_data - The custom argument previously passed to the caller function - - - - @struct IniFormat - - @version 1.0 - @date October 6th, 2018 (version 1.7.0 of the library) - - @property IniFormat::delimiter_symbol - The key-value delimiter character (ASCII only allowed); if set - to `\0`, any space is delimiter - (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`); if, within the format - given, `IniFormat::delimiter_symbol` matches a metacharacter - (`'\\'`, `'\''`, `'\"'`), its role as metacharacter will have - higher priority than its role as delimiter symbol (i.e., the - format will have no key-value delimiter); you may use the - #IniDelimiters `enum` for this. - @property IniFormat::case_sensitive - If set to `true`, string comparisons will be always - case-sensitive. - @property IniFormat::semicolon_marker - The role of the semicolon character (use `enum` - #IniCommentMarker for this). - @property IniFormat::hash_marker - The role of the hash character (use `enum` #IniCommentMarker for - this). - @property IniFormat::section_paths - Defines whether and how the format supports sections (use `enum` - #IniSectionPaths for this). - @property IniFormat::multiline_nodes - Defines which class of entries are allowed to be multi-line (use - `enum` #IniMultiline for this). - @property IniFormat::no_spaces_in_names - If set to `true`, key and section names containing spaces (even - within quotes) will be dispatched as #INI_UNKNOWN. Note that - setting #IniFormat::delimiter_symbol to #INI_ANY_SPACE will not - automatically set this option to `true` (spaces will still be - allowed in section names). - @property IniFormat::no_single_quotes - If set to `true`, the single-quote character (`'`) will be - considered as a normal character. - @property IniFormat::no_double_quotes - If set to `true`, the double-quote character (`"`) will be - considered as a normal character. - @property IniFormat::implicit_is_not_empty - If set to `true`, implicit keys (see @ref libconfini) will - be always dispatched using the values provided by the global - variables #INI_GLOBAL_IMPLICIT_VALUE and - #INI_GLOBAL_IMPLICIT_V_LEN for the fields #IniDispatch::value - and to #IniDispatch::v_len respectively; if set to `false`, - implicit keys will be considered to be empty keys. - @property IniFormat::do_not_collapse_values - If set to `true`, sequences of one or more spaces in values - (`/\s+/`) will be dispatched verbatim. - @property IniFormat::preserve_empty_quotes - If set to `true`, and if single/double quotes are - metacharacters, ensures that, within values, empty strings - enclosed between quotes (`""` or `''`) will not be collapsed - together with the spaces that surround them. This option is - useful for values containing space-delimited arrays, in order to - preserve their empty members -- as in, for instance: - `coordinates = "" ""`. Note that, in section and key names, - empty strings enclosed between quotes are _always_ collapsed - together with their surrounding spaces. - @property IniFormat::disabled_after_space - If set to `true`, what follows `/[#;]\s/` is allowed to be - parsed as a disabled entry. - @property IniFormat::disabled_can_be_implicit - If set to `false`, comments that do not contain a key-value - delimiter will never be parsed as disabled keys, but always as - simple comments (even if the format supports implicit keys). - - - - @struct IniStatistics - - @property IniStatistics::format - The format of the INI file (see #IniFormat) - @property IniStatistics::bytes - The size of the parsed file in bytes - @property IniStatistics::members - The size of the parsed file in number of members (nodes) -- this - number always equals the number of dispatches that will be - produced by #load_ini_file(), #load_ini_path() or - #strip_ini_cache() - - - - @struct IniDispatch - - @property IniDispatch::format - The format of the INI file (see #IniFormat) - @property IniDispatch::type - The dispatch type (see `enum` #IniNodeType) - @property IniDispatch::data - It can contain a comment, a section path or a key name, - depending on #IniDispatch::type; it cannot be `NULL` - @property IniDispatch::value - It can contain the value of a key element, an empty string or it - can point to the address pointed by the global variable - #INI_GLOBAL_IMPLICIT_VALUE (_the latter is the only case in - which `IniDispatch::value` can be `NULL`_) - @property IniDispatch::append_to - The current section path; it cannot be `NULL` - @property IniDispatch::d_len - The length of the string #IniDispatch::data - @property IniDispatch::v_len - The length of the string #IniDispatch::value - @property IniDispatch::at_len - The length of the string #IniDispatch::append_to - @property IniDispatch::dispatch_id - The dispatch number (the first dispatch is number zero) - - - - @def INI_DISABLED_FLAG + @typedef int (* IniStatsHandler) ( + IniStatistics * statistics, + void * user_data + ) + + @param statistics + A pointer to the #IniStatistics to handle + @param user_data + The custom argument previously passed to the caller function + + + + @typedef int (* IniDispHandler) ( + IniDispatch *dispatch, + void * user_data + ) + + @param dispatch + A pointer to the #IniDispatch to handle + @param user_data + The custom argument previously passed to the caller function + + + + @typedef int (* IniStrHandler) ( + char * ini_string, + size_t string_length, + size_t string_num, + IniFormat format, + void * user_data + ) + + @param ini_string + The INI string to handle + @param string_length + The length of the INI string in bytes + @param string_num + The unique number that identifies @p ini_string within a + sequence of INI strings; it equals zero if @p ini_string is the + first or the only member of the sequence + @param format + The format of the INI file from which @p ini_string has been + extracted + @param user_data + The custom argument previously passed to the caller function + + + + @typedef int (* IniSubstrHandler) ( + const char * ini_string, + size_t fragm_offset, + size_t fragm_length, + size_t fragm_num, + IniFormat format, + void * user_data + ) + + @param ini_string + The INI string containing the fragment to handle + @param fragm_offset + The offset of the selected fragment in bytes + @param fragm_length + The length of the selected fragment in bytes + @param fragm_num + The unique number that identifies the selected fragment within a + sequence of fragments of @p ini_string; it equals zero if the + fragment is the first or the only member of the sequence + @param format + The format of the INI file from which @p ini_string has been + extracted + @param user_data + The custom argument previously passed to the caller function + + + + @struct IniFormat + + @version 1.0 + @date October 6th, 2018 (version 1.7.0 of the library) + + @property IniFormat::delimiter_symbol + The key-value delimiter character (ASCII only allowed); if set + to `\0`, any space is delimiter + (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`); if, within the format + given, `IniFormat::delimiter_symbol` matches a metacharacter + (`'\\'`, `'\''`, `'\"'`), its role as metacharacter will have + higher priority than its role as delimiter symbol (i.e., the + format will have no key-value delimiter); you may use the + #IniDelimiters `enum` for this. + @property IniFormat::case_sensitive + If set to `true`, string comparisons will be always + case-sensitive. + @property IniFormat::semicolon_marker + The role of the semicolon character (use `enum` + #IniCommentMarker for this). + @property IniFormat::hash_marker + The role of the hash character (use `enum` #IniCommentMarker for + this). + @property IniFormat::section_paths + Defines whether and how the format supports sections (use `enum` + #IniSectionPaths for this). + @property IniFormat::multiline_nodes + Defines which class of entries are allowed to be multi-line (use + `enum` #IniMultiline for this). + @property IniFormat::no_spaces_in_names + If set to `true`, key and section names containing spaces (even + within quotes) will be dispatched as #INI_UNKNOWN. Note that + setting #IniFormat::delimiter_symbol to #INI_ANY_SPACE will not + automatically set this option to `true` (spaces will still be + allowed in section names). + @property IniFormat::no_single_quotes + If set to `true`, the single-quote character (`'`) will be + considered as a normal character. + @property IniFormat::no_double_quotes + If set to `true`, the double-quote character (`"`) will be + considered as a normal character. + @property IniFormat::implicit_is_not_empty + If set to `true`, implicit keys (see @ref libconfini) will + be always dispatched using the values provided by the global + variables #INI_GLOBAL_IMPLICIT_VALUE and + #INI_GLOBAL_IMPLICIT_V_LEN for the fields #IniDispatch::value + and to #IniDispatch::v_len respectively; if set to `false`, + implicit keys will be considered to be empty keys. + @property IniFormat::do_not_collapse_values + If set to `true`, sequences of one or more spaces in values + (`/\s+/`) will be dispatched verbatim. + @property IniFormat::preserve_empty_quotes + If set to `true`, and if single/double quotes are + metacharacters, ensures that, within values, empty strings + enclosed between quotes (`""` or `''`) will not be collapsed + together with the spaces that surround them. This option is + useful for values containing space-delimited arrays, in order to + preserve their empty members -- as in, for instance: + `coordinates = "" ""`. Note that, in section and key names, + empty strings enclosed between quotes are _always_ collapsed + together with their surrounding spaces. + @property IniFormat::disabled_after_space + If set to `true`, what follows `/[#;]\s/` is allowed to be + parsed as a disabled entry. + @property IniFormat::disabled_can_be_implicit + If set to `false`, comments that do not contain a key-value + delimiter will never be parsed as disabled keys, but always as + simple comments (even if the format supports implicit keys). + + + + @struct IniStatistics + + @property IniStatistics::format + The format of the INI file (see #IniFormat) + @property IniStatistics::bytes + The size of the parsed file in bytes + @property IniStatistics::members + The size of the parsed file in number of members (nodes) -- this + number always equals the number of dispatches that will be + produced by #load_ini_file(), #load_ini_path() or + #strip_ini_cache() + + + + @struct IniDispatch + + @property IniDispatch::format + The format of the INI file (see #IniFormat) + @property IniDispatch::type + The dispatch type (see `enum` #IniNodeType) + @property IniDispatch::data + It can contain a comment, a section path or a key name, + depending on #IniDispatch::type; it cannot be `NULL` + @property IniDispatch::value + It can contain the value of a key element, an empty string or it + can point to the address pointed by the global variable + #INI_GLOBAL_IMPLICIT_VALUE (_the latter is the only case in + which `IniDispatch::value` can be `NULL`_) + @property IniDispatch::append_to + The current section path; it cannot be `NULL` + @property IniDispatch::d_len + The length of the string #IniDispatch::data + @property IniDispatch::v_len + The length of the string #IniDispatch::value + @property IniDispatch::at_len + The length of the string #IniDispatch::append_to + @property IniDispatch::dispatch_id + The dispatch number (the first dispatch is number zero) + + + + @def INI_DISABLED_FLAG Example #1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} if (dispatch->type & INI_DISABLED_FLAG) { - printf("This is not a real INI node...\n"); + printf("This is not a real INI node...\n"); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -245,7 +245,7 @@ later version. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} if ((dispatch->type | INI_DISABLED_FLAG) == INI_DISABLED_KEY) { - printf("Hey! This is either an INI_KEY or an INI_DISABLED_KEY!\n"); + printf("Hey! This is either an INI_KEY or an INI_DISABLED_KEY!\n"); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -277,7 +277,7 @@ later version. __PP_EVALUCAT__(__PP_UCAT__(__COND, CONDITION), _)(__VA_ARGS__, , ) #define __COND_0__(IF_TRUE, IF_FALSE, ...) IF_FALSE #define __COND_1__(IF_TRUE, ...) IF_TRUE -/*@@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(IO_FLAVORS)! @@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(IO_FLAVORS)! @@@@@@@@@@@@@@@@@@@@@@@@@*/ /* PREPROCESSOR ENVIRONMENT */ @@ -286,8 +286,8 @@ later version. #ifndef CONFINI_IO_FLAVOR /** - @brief The I/O API to use (possibly overridden via - `-DCONFINI_IO_FLAVOR=[FLAVOR]`) + @brief The I/O API to use (possibly overridden via + `-DCONFINI_IO_FLAVOR=[FLAVOR]`) Possible values are `CONFINI_STANDARD` and `CONFINI_POSIX` @@ -300,13 +300,13 @@ later version. /* PREPROCESSOR GLUE */ -#define _LIBCONFINI_PRIVATE_ITEM_(GROUP, ITEM) \ - __PP_EVALUCAT__(__PP_CAT__(_LIB, GROUP), __PP_CAT__(ITEM, _)) -#define _LIBCONFINI_CURRENT_FLAVOR_GET_(NAME) \ - _LIBCONFINI_PRIVATE_ITEM_(CONFINI_IO_FLAVOR, NAME) -#define _LIBCONFINI_IS_FLAVOR_(NAME) \ - _LIBCONFINI_PRIVATE_ITEM_(CONFINI_IO_FLAVOR, FLAVOR) == \ - _LIBCONFINI_PRIVATE_ITEM_(NAME, FLAVOR) +#define _CONFINI_PRIVATE_ITEM_(GROUP, ITEM) \ + __PP_EVALUCAT__(__PP_CAT__(_, GROUP), __PP_CAT__(ITEM, _)) +#define _CONFINI_CURRENT_FLAVOR_GET_(NAME) \ + _CONFINI_PRIVATE_ITEM_(CONFINI_IO_FLAVOR, NAME) +#define _CONFINI_IS_FLAVOR_(NAME) \ + _CONFINI_PRIVATE_ITEM_(CONFINI_IO_FLAVOR, FLAVOR) == \ + _CONFINI_PRIVATE_ITEM_(NAME, FLAVOR) @@ -314,48 +314,48 @@ later version. /* `-DCONFINI_IO_FLAVOR=CONFINI_STANDARD` (C99 Standard, default) */ -#define _LIBCONFINI_STANDARD_SEOF_FN_(FILEPTR) fseek(FILEPTR, 0, SEEK_END) -#define _LIBCONFINI_STANDARD_FT_FN_(FILEPTR) ftell(FILEPTR) -#define _LIBCONFINI_STANDARD_FT_T_ long signed int +#define _CONFINI_STANDARD_SEOF_FN_(FILEPTR) fseek(FILEPTR, 0, SEEK_END) +#define _CONFINI_STANDARD_FT_FN_(FILEPTR) ftell(FILEPTR) +#define _CONFINI_STANDARD_FT_T_ long signed int /* Any unique non-zero integer to identify this I/O API */ -#define _LIBCONFINI_STANDARD_FLAVOR_ 1 +#define _CONFINI_STANDARD_FLAVOR_ 1 /* `-DCONFINI_IO_FLAVOR=CONFINI_POSIX` */ -#define _LIBCONFINI_POSIX_SEOF_FN_(FILEPTR) fseeko(FILEPTR, 0, SEEK_END) -#define _LIBCONFINI_POSIX_FT_FN_(FILEPTR) ftello(FILEPTR) -#define _LIBCONFINI_POSIX_FT_T_ off_t +#define _CONFINI_POSIX_SEOF_FN_(FILEPTR) fseeko(FILEPTR, 0, SEEK_END) +#define _CONFINI_POSIX_FT_FN_(FILEPTR) ftello(FILEPTR) +#define _CONFINI_POSIX_FT_T_ off_t /* Any unique non-zero integer to identify this I/O API */ -#define _LIBCONFINI_POSIX_FLAVOR_ 2 +#define _CONFINI_POSIX_FLAVOR_ 2 /* Define `_POSIX_C_SOURCE` macro when `CONFINI_IO_FLAVOR == CONFINI_POSIX` */ -#if _LIBCONFINI_IS_FLAVOR_(CONFINI_POSIX) +#if _CONFINI_IS_FLAVOR_(CONFINI_POSIX) #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif #endif -/* It is possible to add other I/O APIs here. Feel free to contribute! */ +/* It is possible to add other I/O APIs here. Feel free to contribute! */ /* CHECKS */ -#if _LIBCONFINI_PRIVATE_ITEM_(CONFINI_IO_FLAVOR, FLAVOR) == 0 +#if _CONFINI_PRIVATE_ITEM_(CONFINI_IO_FLAVOR, FLAVOR) == 0 #error Unsupported I/O API defined in macro CONFINI_IO_FLAVOR #endif -/*@@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(IO_FLAVORS)! @@@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(IO_FLAVORS)! @@@@@@@@@@@@@@@@@@@@@@@@@@*/ /* HEADERS */ -/*@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(STANDARD_HEADERS)! @@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(STANDARD_HEADERS)! @@@@@@@@@@@@@@@@@@@@@@*/ #include -/*@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(STANDARD_HEADERS)! @@@@@@@@@@@@@@@@@@@@@@*/ -/*@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(CONFINI_HEADER)! @@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(STANDARD_HEADERS)! @@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(CONFINI_HEADER)! @@@@@@@@@@@@@@@@@@@@@@@*/ #include "confini.h" -/*@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(CONFINI_HEADER)! @@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(CONFINI_HEADER)! @@@@@@@@@@@@@@@@@@@@@@@@*/ @@ -375,36 +375,36 @@ later version. /* ALIASES */ -#define _LIBCONFINI_FALSE_ 0 -#define _LIBCONFINI_TRUE_ 1 -#define _LIBCONFINI_CHARBOOL_ unsigned char -#define _LIBCONFINI_SIMPLE_SPACE_ '\x20' -#define _LIBCONFINI_HT_ '\t' -#define _LIBCONFINI_FF_ '\f' -#define _LIBCONFINI_VT_ '\v' -#define _LIBCONFINI_CR_ '\r' -#define _LIBCONFINI_LF_ '\n' -#define _LIBCONFINI_BACKSLASH_ '\\' -#define _LIBCONFINI_OPEN_SECTION_ '[' -#define _LIBCONFINI_CLOSE_SECTION_ ']' -#define _LIBCONFINI_SUBSECTION_ '.' -#define _LIBCONFINI_SEMICOLON_ ';' -#define _LIBCONFINI_HASH_ '#' -#define _LIBCONFINI_DOUBLE_QUOTES_ '"' -#define _LIBCONFINI_SINGLE_QUOTES_ '\'' -/*@@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(IO_ALIASES)! @@@@@@@@@@@@@@@@@@@@@@@@*/ -#define _LIBCONFINI_SEEK_EOF_(FILEPTR) \ - _LIBCONFINI_CURRENT_FLAVOR_GET_(SEOF_FN)(FILEPTR) -#define _LIBCONFINI_FTELL_(FILEPTR) \ - _LIBCONFINI_CURRENT_FLAVOR_GET_(FT_FN)(FILEPTR) -#define _LIBCONFINI_OFF_T_ \ - _LIBCONFINI_CURRENT_FLAVOR_GET_(FT_T) -/*@@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(IO_ALIASES)! @@@@@@@@@@@@@@@@@@@@@@@@@*/ +#define _CONFINI_FALSE_ 0 +#define _CONFINI_TRUE_ 1 +#define _CONFINI_CHARBOOL_ unsigned char +#define _CONFINI_SIMPLE_SPACE_ '\x20' +#define _CONFINI_HT_ '\t' +#define _CONFINI_FF_ '\f' +#define _CONFINI_VT_ '\v' +#define _CONFINI_CR_ '\r' +#define _CONFINI_LF_ '\n' +#define _CONFINI_BACKSLASH_ '\\' +#define _CONFINI_OPEN_SECTION_ '[' +#define _CONFINI_CLOSE_SECTION_ ']' +#define _CONFINI_SUBSECTION_ '.' +#define _CONFINI_SEMICOLON_ ';' +#define _CONFINI_HASH_ '#' +#define _CONFINI_D_QUOTES_ '"' +#define _CONFINI_S_QUOTES_ '\'' +/*@@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(IO_ALIASES)! @@@@@@@@@@@@@@@@@@@@@@@@@*/ +#define _CONFINI_SEEK_EOF_(FILEPTR) \ + _CONFINI_CURRENT_FLAVOR_GET_(SEOF_FN)(FILEPTR) +#define _CONFINI_FTELL_(FILEPTR) \ + _CONFINI_CURRENT_FLAVOR_GET_(FT_FN)(FILEPTR) +#define _CONFINI_OFF_T_ \ + _CONFINI_CURRENT_FLAVOR_GET_(FT_T) +/*@@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(IO_ALIASES)! @@@@@@@@@@@@@@@@@@@@@@@@@@*/ /* The character that will replace sequences of one or more spaces (`/\s+/`) */ -#define _LIBCONFINI_COLLAPSED_ _LIBCONFINI_SIMPLE_SPACE_ +#define _CONFINI_COLLAPSED_ _CONFINI_SIMPLE_SPACE_ /* @@ -413,10 +413,10 @@ later version. leading spaces work pretty well as markers... */ -/* Internal marker of standard comments */ -#define _LIBCONFINI_SC_INT_MARKER_ _LIBCONFINI_SIMPLE_SPACE_ +/* Internal marker of comment blocks */ +#define _CONFINI_BC_INT_MARKER_ _CONFINI_SIMPLE_SPACE_ /* Internal marker of inline comments */ -#define _LIBCONFINI_IC_INT_MARKER_ _LIBCONFINI_HT_ +#define _CONFINI_IC_INT_MARKER_ _CONFINI_HT_ @@ -428,13 +428,13 @@ later version. Check whether a character can be escaped within a given format */ -#define _LIBCONFINI_IS_ESC_CHAR_(CHR, FMT) ( \ - CHR == _LIBCONFINI_BACKSLASH_ ? \ +#define _CONFINI_IS_ESC_CHAR_(CHR, FMT) ( \ + CHR == _CONFINI_BACKSLASH_ ? \ !INIFORMAT_HAS_NO_ESC(FMT) \ - : CHR == _LIBCONFINI_DOUBLE_QUOTES_ ? \ + : CHR == _CONFINI_D_QUOTES_ ? \ !FMT.no_double_quotes \ : \ - CHR == _LIBCONFINI_SINGLE_QUOTES_ && !FMT.no_single_quotes \ + CHR == _CONFINI_S_QUOTES_ && !FMT.no_single_quotes \ ) @@ -443,11 +443,11 @@ later version. Check whether a character represents any marker within a given format */ -#define _LIBCONFINI_IS_ANY_MARKER_(CHR, FMT) ( \ - CHR == _LIBCONFINI_HASH_ ? \ +#define _CONFINI_IS_ANY_MARKER_(CHR, FMT) ( \ + CHR == _CONFINI_HASH_ ? \ FMT.hash_marker != INI_IS_NOT_A_MARKER \ : \ - CHR == _LIBCONFINI_SEMICOLON_ && \ + CHR == _CONFINI_SEMICOLON_ && \ FMT.semicolon_marker != INI_IS_NOT_A_MARKER \ ) @@ -458,12 +458,12 @@ later version. given format */ -#define _LIBCONFINI_IS_N_I_MARKER_(CHR, FMT) ( \ - CHR == _LIBCONFINI_HASH_ ? \ +#define _CONFINI_IS_N_I_MARKER_(CHR, FMT) ( \ + CHR == _CONFINI_HASH_ ? \ FMT.hash_marker != INI_IS_NOT_A_MARKER && \ FMT.hash_marker != INI_IGNORE \ : \ - CHR == _LIBCONFINI_SEMICOLON_ && \ + CHR == _CONFINI_SEMICOLON_ && \ FMT.semicolon_marker != INI_IS_NOT_A_MARKER && \ FMT.semicolon_marker != INI_IGNORE \ ) @@ -475,11 +475,11 @@ later version. within a given format */ -#define _LIBCONFINI_IS_DIS_MARKER_(CHR, FMT) ( \ - CHR == _LIBCONFINI_HASH_ ? \ +#define _CONFINI_IS_DIS_MARKER_(CHR, FMT) ( \ + CHR == _CONFINI_HASH_ ? \ FMT.hash_marker == INI_DISABLED_OR_COMMENT \ : \ - CHR == _LIBCONFINI_SEMICOLON_ && \ + CHR == _CONFINI_SEMICOLON_ && \ FMT.semicolon_marker == INI_DISABLED_OR_COMMENT \ ) @@ -490,11 +490,11 @@ later version. a given format */ -#define _LIBCONFINI_IS_COM_MARKER_(CHR, FMT) ( \ - CHR == _LIBCONFINI_HASH_ ? \ +#define _CONFINI_IS_COM_MARKER_(CHR, FMT) ( \ + CHR == _CONFINI_HASH_ ? \ FMT.hash_marker == INI_ONLY_COMMENT \ : \ - CHR == _LIBCONFINI_SEMICOLON_ && \ + CHR == _CONFINI_SEMICOLON_ && \ FMT.semicolon_marker == INI_ONLY_COMMENT \ ) @@ -505,11 +505,11 @@ later version. given format */ -#define _LIBCONFINI_IS_IGN_MARKER_(CHR, FMT) ( \ - CHR == _LIBCONFINI_HASH_ ? \ +#define _CONFINI_IS_IGN_MARKER_(CHR, FMT) ( \ + CHR == _CONFINI_HASH_ ? \ FMT.hash_marker == INI_IGNORE \ : \ - CHR == _LIBCONFINI_SEMICOLON_ && \ + CHR == _CONFINI_SEMICOLON_ && \ FMT.semicolon_marker == INI_IGNORE \ ) @@ -521,16 +521,17 @@ later version. ASCII... */ -#define _LIBCONFINI_CHR_CASEFOLD_(CHR) (CHR > 0x40 && CHR < 0x5b ? CHR | 0x60 : CHR) +#define _CONFINI_CHR_CASEFOLD_(CHR) \ + (CHR > 0x40 && CHR < 0x5b ? CHR | 0x60 : CHR) /* - Constants related to `_LIBCONFINI_SPACES_` + Constants related to `_CONFINI_SPACES_` */ -#define _LIBCONFINI_EOL_IDX_ 0 -#define _LIBCONFINI_SPALEN_ 6 +#define _CONFINI_EOL_IDX_ 0 +#define _CONFINI_SPALEN_ 6 /* @@ -538,32 +539,32 @@ later version. The list of space characters -- do not change its order or its content! */ -static const char _LIBCONFINI_SPACES_[_LIBCONFINI_SPALEN_] = { - _LIBCONFINI_LF_, - _LIBCONFINI_CR_, - _LIBCONFINI_VT_, - _LIBCONFINI_FF_, - _LIBCONFINI_HT_, - _LIBCONFINI_SIMPLE_SPACE_ +static const char _CONFINI_SPACES_[_CONFINI_SPALEN_] = { + _CONFINI_LF_, + _CONFINI_CR_, + _CONFINI_VT_, + _CONFINI_FF_, + _CONFINI_HT_, + _CONFINI_SIMPLE_SPACE_ }; /* - Possible depths of `_LIBCONFINI_SPACES_` (see function #is_some_space()). + Possible depths of `_CONFINI_SPACES_` (see function #is_some_space()). Please, consider the following three constants as belonging together to a virtual opaque `enum`. */ -#define _LIBCONFINI_WITH_EOL_ -1 -#define _LIBCONFINI_NO_EOL_ 1 -#define _LIBCONFINI_JUST_S_T_ 3 +#define _CONFINI_WITH_EOL_ -1 +#define _CONFINI_NO_EOL_ 1 +#define _CONFINI_JUST_S_T_ 3 /** - @brief A list of possible string representations of boolean pairs + @brief A list of possible string representations of boolean pairs There may be infinite pairs here. Each pair must be organized according to the following order: @@ -571,7 +572,7 @@ static const char _LIBCONFINI_SPACES_[_LIBCONFINI_SPALEN_] = { 1. Signifier of `false` 2. Signifier of `true` - @note Everything **must** be lowercase in this list. + @note Everything **must** be lowercase in this list. **/ static const char * const INI_BOOLEANS[][2] = { @@ -586,7 +587,7 @@ static const char * const INI_BOOLEANS[][2] = { Other constants related to `INI_BOOLEANS` */ -#define _LIBCONFINI_BOOLLEN_ (sizeof(INI_BOOLEANS) / sizeof(const char * const [2])) +#define _CONFINI_BOOLLEN_ (sizeof(INI_BOOLEANS) / sizeof(const char * const [2])) @@ -595,33 +596,40 @@ static const char * const INI_BOOLEANS[][2] = { /** - @brief Check whether a character is a space - @param chr The target character - @param depth What is actually considered a space (possible - values: `_LIBCONFINI_WITH_EOL_`, - `_LIBCONFINI_NO_EOL_`, `_LIBCONFINI_JUST_S_T_`) - @return A boolean: `true` if the character matches, `false` otherwise + @brief Check whether a character is a space + @param chr The target character + @param depth What is actually considered a space (possible + values: `_CONFINI_WITH_EOL_`, `_CONFINI_NO_EOL_`, + `_CONFINI_JUST_S_T_`) + @return A boolean: `true` if the character matches, `false` otherwise **/ -static inline _LIBCONFINI_CHARBOOL_ is_some_space (const char chr, const int_least8_t depth) { +static inline _CONFINI_CHARBOOL_ is_some_space ( + const char chr, + const int_least8_t depth +) { register int_least8_t idx = depth; - while (++idx < _LIBCONFINI_SPALEN_ && chr != _LIBCONFINI_SPACES_[idx]); - return idx < _LIBCONFINI_SPALEN_; + while (++idx < _CONFINI_SPALEN_ && chr != _CONFINI_SPACES_[idx]); + return idx < _CONFINI_SPALEN_; } /** - @brief Soft left trim -- does not change the buffer - @param str The target string - @param offs The offset where to start the left trim - @param depth What is actually considered a space (possible - values: `_LIBCONFINI_WITH_EOL_`, - `_LIBCONFINI_NO_EOL_`, `_LIBCONFINI_JUST_S_T_`) - @return The offset of the first non-space character + @brief Soft left trim -- does not change the buffer + @param str The target string + @param offs The offset where to start the left trim + @param depth What is actually considered a space (possible + values: `_CONFINI_WITH_EOL_`, `_CONFINI_NO_EOL_`, + `_CONFINI_JUST_S_T_`) + @return The offset of the first non-space character **/ -static inline size_t ltrim_s (const char * const str, const size_t offs, const int_least8_t depth) { +static inline size_t ltrim_s ( + const char * const str, + const size_t offs, + const int_least8_t depth +) { register size_t idx = offs; while (is_some_space(str[idx++], depth)); return idx - 1; @@ -630,16 +638,20 @@ static inline size_t ltrim_s (const char * const str, const size_t offs, const i /** - @brief Hard left trim -- **does** change the buffer - @param str The target string - @param offs The offset where to start the left trim - @param depth What is actually considered a space (possible - values: `_LIBCONFINI_WITH_EOL_`, - `_LIBCONFINI_NO_EOL_`, `_LIBCONFINI_JUST_S_T_`) - @return The offset of the first non-space character + @brief Hard left trim -- **does** change the buffer + @param str The target string + @param offs The offset where to start the left trim + @param depth What is actually considered a space (possible + values: `_CONFINI_WITH_EOL_`, `_CONFINI_NO_EOL_`, + `_CONFINI_JUST_S_T_`) + @return The offset of the first non-space character **/ -static inline size_t ltrim_h (char * const str, const size_t offs, const int_least8_t depth) { +static inline size_t ltrim_h ( + char * const str, + const size_t offs, + const int_least8_t depth +) { register size_t idx = offs; while (is_some_space(str[idx], depth)) { str[idx++] = '\0'; } return idx; @@ -648,16 +660,20 @@ static inline size_t ltrim_h (char * const str, const size_t offs, const int_lea /** - @brief Shifting left trim -- **does** change the buffer - @param str The target string - @param offs The offset where to start the left trim - @param depth What is actually considered a space (possible - values: `_LIBCONFINI_WITH_EOL_`, - `_LIBCONFINI_NO_EOL_`, `_LIBCONFINI_JUST_S_T_`) - @return The new length of the string + @brief Shifting left trim -- **does** change the buffer + @param str The target string + @param offs The offset where to start the left trim + @param depth What is actually considered a space (possible + values: `_CONFINI_WITH_EOL_`, `_CONFINI_NO_EOL_`, + `_CONFINI_JUST_S_T_`) + @return The new length of the string **/ -static inline size_t ltrim_hh (char * const str, const size_t offs, const int_least8_t depth) { +static inline size_t ltrim_hh ( + char * const str, + const size_t offs, + const int_least8_t depth +) { register size_t idx_d = offs, idx_s = offs; while (is_some_space(str[idx_s++], depth)); if (--idx_s - idx_d) { @@ -672,16 +688,20 @@ static inline size_t ltrim_hh (char * const str, const size_t offs, const int_le /** - @brief Soft right trim -- does not change the buffer - @param str The target string - @param len The length of the string - @param depth What is actually considered a space (possible - values: `_LIBCONFINI_WITH_EOL_`, - `_LIBCONFINI_NO_EOL_`, `_LIBCONFINI_JUST_S_T_`) - @return The length of the string until the last non-space character + @brief Soft right trim -- does not change the buffer + @param str The target string + @param len The length of the string + @param depth What is actually considered a space (possible + values: `_CONFINI_WITH_EOL_`, `_CONFINI_NO_EOL_`, + `_CONFINI_JUST_S_T_`) + @return The length of the string until the last non-space character **/ -static inline size_t rtrim_s (const char * const str, const size_t len, const int_least8_t depth) { +static inline size_t rtrim_s ( + const char * const str, + const size_t len, + const int_least8_t depth +) { register size_t idx = len + 1; while (--idx > 0 && is_some_space(str[idx - 1], depth)); return idx; @@ -690,16 +710,20 @@ static inline size_t rtrim_s (const char * const str, const size_t len, const in /** - @brief Hard right trim -- **does** change the buffer - @param str The target string - @param len The length of the string - @param depth What is actually considered a space (possible - values: `_LIBCONFINI_WITH_EOL_`, - `_LIBCONFINI_NO_EOL_`, `_LIBCONFINI_JUST_S_T_`) - @return The new length of the string + @brief Hard right trim -- **does** change the buffer + @param str The target string + @param len The length of the string + @param depth What is actually considered a space (possible + values: `_CONFINI_WITH_EOL_`, `_CONFINI_NO_EOL_`, + `_CONFINI_JUST_S_T_`) + @return The new length of the string **/ -static inline size_t rtrim_h (char * const str, const size_t len, const int_least8_t depth) { +static inline size_t rtrim_h ( + char * const str, + const size_t len, + const int_least8_t depth +) { register size_t idx = len; while (idx > 0 && is_some_space(str[idx - 1], depth)) { str[--idx] = '\0'; } return idx; @@ -708,14 +732,17 @@ static inline size_t rtrim_h (char * const str, const size_t len, const int_leas /** - @brief Unparsed soft right trim (right trim of `/(?:\s|\\[\n\r])+$/`) - -- does not change the buffer - @param str The target string - @param len The length of the string - @return The length of the string until the last non-space character + @brief Unparsed soft right trim (right trim of `/(?:\s|\\[\n\r])+$/`) + -- does not change the buffer + @param str The target string + @param len The length of the string + @return The length of the string until the last non-space character **/ -static inline size_t urtrim_s (const char * const str, const size_t len) { +static inline size_t urtrim_s ( + const char * const str, + const size_t len +) { register uint_least8_t abcd = 1; register size_t idx = len; @@ -734,21 +761,21 @@ static inline size_t urtrim_s (const char * const str, const size_t len) { switch (str[--idx]) { - case _LIBCONFINI_VT_: - case _LIBCONFINI_FF_: - case _LIBCONFINI_HT_: - case _LIBCONFINI_SIMPLE_SPACE_: + case _CONFINI_VT_: + case _CONFINI_FF_: + case _CONFINI_HT_: + case _CONFINI_SIMPLE_SPACE_: abcd = 1; goto continue_urtrim; - case _LIBCONFINI_LF_: - case _LIBCONFINI_CR_: + case _CONFINI_LF_: + case _CONFINI_CR_: abcd = 3; goto continue_urtrim; - case _LIBCONFINI_BACKSLASH_: + case _CONFINI_BACKSLASH_: if (abcd >>= 1) { @@ -765,14 +792,16 @@ static inline size_t urtrim_s (const char * const str, const size_t len) { /** - @brief Convert an ASCII string to lower case - @param str The target string - @return Nothing + @brief Convert an ASCII string to lower case + @param str The target string + @return Nothing **/ -static inline void string_tolower (char * const str) { +static inline void string_tolower ( + char * const str +) { for (register char * chrptr = str; *chrptr; chrptr++) { - *chrptr = _LIBCONFINI_CHR_CASEFOLD_(*chrptr); + *chrptr = _CONFINI_CHR_CASEFOLD_(*chrptr); } } @@ -783,13 +812,13 @@ static inline void string_tolower (char * const str) { /** - @brief Unparsed hard left trim (left trim of - `/^(?:\s+|\\[\n\r]|''|"")+/`) -- **does** change the buffer - @param srcstr The target string (it may contain multi-line - escape sequences) - @param offs The offset where to start the left trim - @param format The format of the INI file - @return The offset of the first non-trivial character + @brief Unparsed hard left trim (left trim of + `/^(?:\s+|\\[\n\r]|''|"")+/`) -- **does** change the buffer + @param srcstr The target string (it may contain multi-line + escape sequences) + @param offs The offset where to start the left trim + @param format The format of the INI file + @return The offset of the first non-trivial character **/ static inline size_t qultrim_h ( @@ -809,47 +838,49 @@ static inline size_t qultrim_h ( FLAG_16 We are in an odd sequence of backslashes FLAG_32 Erase the previous character FLAG_64 Erase this character - FLAG_128 Continue the loop + FLAG_128 Continue the loop */ - register uint_least8_t - abcd = (format.no_double_quotes ? 130 : 128) | format.no_single_quotes; + register uint_least8_t abcd = + (format.no_double_quotes ? 130 : 128) | format.no_single_quotes; size_t idx = offs; do { - abcd = !(abcd & 28) && is_some_space(srcstr[idx], _LIBCONFINI_NO_EOL_) ? - (abcd & 207) | 64 - : !(abcd & 12) && ( - srcstr[idx] == _LIBCONFINI_LF_ || - srcstr[idx] == _LIBCONFINI_CR_ - ) ? - ( - abcd & 16 ? - (abcd & 239) | 96 - : - abcd | 64 - ) - : !(abcd & 25) && srcstr[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - abcd & 4 ? - (abcd & 235) | 96 - : - (abcd & 143) | 4 - ) - : !(abcd & 22) && srcstr[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - abcd & 8 ? - (abcd & 231) | 96 - : - (abcd & 159) | 8 - ) - : srcstr[idx] == _LIBCONFINI_BACKSLASH_ ? - (abcd & 159) ^ 16 + abcd = + + !(abcd & 28) && is_some_space(srcstr[idx], _CONFINI_NO_EOL_) ? + (abcd & 207) | 64 + : !(abcd & 12) && ( + srcstr[idx] == _CONFINI_LF_ || + srcstr[idx] == _CONFINI_CR_ + ) ? + ( + abcd & 16 ? + (abcd & 239) | 96 + : + abcd | 64 + ) + : !(abcd & 25) && srcstr[idx] == _CONFINI_S_QUOTES_ ? + ( + abcd & 4 ? + (abcd & 235) | 96 + : + (abcd & 143) | 4 + ) + : !(abcd & 22) && srcstr[idx] == _CONFINI_D_QUOTES_ ? + ( + abcd & 8 ? + (abcd & 231) | 96 : - abcd & 31; + (abcd & 159) | 8 + ) + : srcstr[idx] == _CONFINI_BACKSLASH_ ? + (abcd & 159) ^ 16 + : + abcd & 31; if (abcd & 32) { @@ -875,14 +906,14 @@ static inline size_t qultrim_h ( /** - @brief Soft left trim within an unparsed disabled entry (left trim of - `/(?:(?:^|\\?[\n\r])[ \t\v\f]*(?:#(?:[ \t\v\f]|''|"")*)?)+/`) - -- does not change the buffer - @param srcstr The target string (it may contain multi-line - escape sequences) - @param offs The offset where to start the left trim - @param format The format of the INI file - @return The offset of the first non-trivial character + @brief Soft left trim within an unparsed disabled entry (left trim of + `/(?:(?:^|\\?[\n\r])[ \t\v\f]*(?:#(?:[ \t\v\f]|''|"")*)?)+/`) + -- does not change the buffer + @param srcstr The target string (it may contain multi-line + escape sequences) + @param offs The offset where to start the left trim + @param format The format of the INI file + @return The offset of the first non-trivial character **/ static inline size_t dqultrim_s ( @@ -895,56 +926,59 @@ static inline size_t dqultrim_s ( Mask `abcd` (7 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes - FLAG_32 A new line has just begun - FLAG_64 Continue the left trim + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes + FLAG_32 A new line has just begun + FLAG_64 Continue the left trim */ - register uint_least16_t abcd = format.no_single_quotes | - (format.no_double_quotes << 1) | - 96; + register uint_least16_t abcd = + format.no_single_quotes | + (format.no_double_quotes << 1) | + 96; register size_t idx = offs; do { - abcd = is_some_space(srcstr[idx], _LIBCONFINI_NO_EOL_) ? - ( - abcd & 28 ? - abcd & 63 - : - abcd - ) - : srcstr[idx] == _LIBCONFINI_LF_ || srcstr[idx] == _LIBCONFINI_CR_ ? - ( - abcd & 12 ? - (abcd & 47) | 32 - : - (abcd & 111) | 32 - ) - : srcstr[idx] == _LIBCONFINI_BACKSLASH_ ? - ( - abcd & 28 ? - (abcd & 31) | 16 - : - (abcd & 95) | 16 - ) - : (abcd & 32) && _LIBCONFINI_IS_ANY_MARKER_(srcstr[idx], format) ? - abcd & 79 - : !(abcd & 54) && srcstr[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - (abcd & 95) ^ 8 - : !(abcd & 57) && srcstr[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - (abcd & 95) ^ 4 - : srcstr[idx] ? - abcd & 31 + abcd = + + is_some_space(srcstr[idx], _CONFINI_NO_EOL_) ? + ( + abcd & 28 ? + abcd & 63 + : + abcd + ) + : srcstr[idx] == _CONFINI_LF_ || srcstr[idx] == _CONFINI_CR_ ? + ( + abcd & 12 ? + (abcd & 47) | 32 + : + (abcd & 111) | 32 + ) + : srcstr[idx] == _CONFINI_BACKSLASH_ ? + ( + abcd & 28 ? + (abcd & 31) | 16 : - abcd & 19; + (abcd & 95) | 16 + ) + : (abcd & 32) && _CONFINI_IS_ANY_MARKER_(srcstr[idx], format) ? + abcd & 79 + : !(abcd & 54) && srcstr[idx] == _CONFINI_D_QUOTES_ ? + (abcd & 95) ^ 8 + : !(abcd & 57) && srcstr[idx] == _CONFINI_S_QUOTES_ ? + (abcd & 95) ^ 4 + : srcstr[idx] ? + abcd & 31 + : + abcd & 19; idx++; @@ -958,14 +992,14 @@ static inline size_t dqultrim_s ( /** - @brief Get the position of the first occurrence out of quotes of a - given character, stopping after a given number of charcters - @param str The string where to search - @param chr The character to to search - @param len The maximum number of characters to read - @param format The format of the INI file - @return The offset of the first occurrence of @p chr, or @p len if - @p chr has not been not found + @brief Get the position of the first occurrence out of quotes of a + given character, stopping after a given number of charcters + @param str The string where to search + @param chr The character to to search + @param len The maximum number of characters to read + @param format The format of the INI file + @return The offset of the first occurrence of @p chr, or @p len if + @p chr has not been not found **/ static inline size_t getn_metachar_pos ( @@ -981,32 +1015,33 @@ static inline size_t getn_metachar_pos ( Mask `abcd` (5 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes */ for ( - register uint_least8_t - abcd = (format.no_double_quotes << 1) | format.no_single_quotes; + register uint_least8_t abcd = + (format.no_double_quotes << 1) | format.no_single_quotes; idx < len && ( (abcd & 12) || ( chr ? str[idx] != chr : - !is_some_space(str[idx], _LIBCONFINI_WITH_EOL_) + !is_some_space(str[idx], _CONFINI_WITH_EOL_) ) ); - abcd = str[idx] == _LIBCONFINI_BACKSLASH_ ? abcd ^ 16 - : !(abcd & 22) && str[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? abcd ^ 8 - : !(abcd & 25) && str[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? abcd ^ 4 - : abcd & 15, + abcd = + str[idx] == _CONFINI_BACKSLASH_ ? abcd ^ 16 + : !(abcd & 22) && str[idx] == _CONFINI_D_QUOTES_ ? abcd ^ 8 + : !(abcd & 25) && str[idx] == _CONFINI_S_QUOTES_ ? abcd ^ 4 + : abcd & 15, idx++ ); @@ -1018,13 +1053,13 @@ static inline size_t getn_metachar_pos ( /** - @brief Get the position of the first occurrence out of quotes of a - given character - @param str The string where to search - @param chr The character to to search - @param format The format of the INI file - @return The offset of the first occurrence of @p chr or the length of - @p str if @p chr has not been not found + @brief Get the position of the first occurrence out of quotes of a + given character + @param str The string where to search + @param chr The character to to search + @param format The format of the INI file + @return The offset of the first occurrence of @p chr or the length of + @p str if @p chr has not been not found **/ static inline size_t get_metachar_pos ( @@ -1045,22 +1080,23 @@ static inline size_t get_metachar_pos ( for ( - register uint_least8_t - abcd = (format.no_double_quotes << 1) | format.no_single_quotes; + register uint_least8_t abcd = + (format.no_double_quotes << 1) | format.no_single_quotes; str[idx] && ( (abcd & 12) || ( chr ? str[idx] != chr : - !is_some_space(str[idx], _LIBCONFINI_NO_EOL_) + !is_some_space(str[idx], _CONFINI_NO_EOL_) ) ); - abcd = str[idx] == _LIBCONFINI_BACKSLASH_ ? abcd ^ 16 - : !(abcd & 22) && str[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? abcd ^ 8 - : !(abcd & 25) && str[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? abcd ^ 4 - : abcd & 15, + abcd = + str[idx] == _CONFINI_BACKSLASH_ ? abcd ^ 16 + : !(abcd & 22) && str[idx] == _CONFINI_D_QUOTES_ ? abcd ^ 8 + : !(abcd & 25) && str[idx] == _CONFINI_S_QUOTES_ ? abcd ^ 4 + : abcd & 15, idx++ ); @@ -1072,40 +1108,40 @@ static inline size_t get_metachar_pos ( /** - @brief Replace `/\\(\n\r?|\r\n?)[\t \v\f]*[#;]/` or `/\\(\n\r?|\r\n?)/` - with `"$1"` - @param srcstr The target string (it may contain multi-line - escape sequences) - @param len Length of the string - @param is_disabled The string represents a disabled entry - @param format The format of the INI file - @return The new length of the string + @brief Replace `/\\(\n\r?|\r\n?)[\t \v\f]*[#;]/` or `/\\(\n\r?|\r\n?)/` + with `"$1"` + @param srcstr The target string (it may contain multi-line + escape sequences) + @param len Length of the string + @param is_disabled The string represents a disabled entry + @param format The format of the INI file + @return The new length of the string **/ static size_t unescape_cr_lf ( char * const srcstr, const size_t len, - const _LIBCONFINI_CHARBOOL_ is_disabled, + const _CONFINI_CHARBOOL_ is_disabled, const IniFormat format ) { register size_t idx_s = 0, idx_d = 0; - register _LIBCONFINI_CHARBOOL_ eol_i = _LIBCONFINI_EOL_IDX_; - register _LIBCONFINI_CHARBOOL_ is_escaped = _LIBCONFINI_FALSE_; + register _CONFINI_CHARBOOL_ eol_i = _CONFINI_EOL_IDX_; + register _CONFINI_CHARBOOL_ is_escaped = _CONFINI_FALSE_; size_t probe; while (idx_s < len) { if ( is_escaped && ( - srcstr[idx_s] == _LIBCONFINI_SPACES_[eol_i] || - srcstr[idx_s] == _LIBCONFINI_SPACES_[eol_i ^= 1] + srcstr[idx_s] == _CONFINI_SPACES_[eol_i] || + srcstr[idx_s] == _CONFINI_SPACES_[eol_i ^= 1] ) ) { srcstr[idx_d - 1] = srcstr[idx_s++]; - if (srcstr[idx_s] == _LIBCONFINI_SPACES_[eol_i ^ 1]) { + if (srcstr[idx_s] == _CONFINI_SPACES_[eol_i ^ 1]) { srcstr[idx_d++] = srcstr[idx_s++]; @@ -1113,9 +1149,9 @@ static size_t unescape_cr_lf ( if (is_disabled) { - probe = ltrim_s(srcstr, idx_s, _LIBCONFINI_NO_EOL_); + probe = ltrim_s(srcstr, idx_s, _CONFINI_NO_EOL_); - if (_LIBCONFINI_IS_DIS_MARKER_(srcstr[probe], format)) { + if (_CONFINI_IS_DIS_MARKER_(srcstr[probe], format)) { idx_s = probe + 1; @@ -1123,15 +1159,15 @@ static size_t unescape_cr_lf ( } - is_escaped = _LIBCONFINI_FALSE_; + is_escaped = _CONFINI_FALSE_; } else { - is_escaped = srcstr[idx_s] == _LIBCONFINI_BACKSLASH_ ? - !is_escaped - : - _LIBCONFINI_FALSE_; - + is_escaped = + srcstr[idx_s] == _CONFINI_BACKSLASH_ ? + !is_escaped + : + _CONFINI_FALSE_; srcstr[idx_d++] = srcstr[idx_s++]; @@ -1139,7 +1175,11 @@ static size_t unescape_cr_lf ( } - for (idx_s = idx_d; idx_s < len; srcstr[idx_s++] = '\0'); + for ( + idx_s = idx_d; + idx_s < len; + srcstr[idx_s++] = '\0' + ); return idx_d; @@ -1148,10 +1188,10 @@ static size_t unescape_cr_lf ( /** - @brief Sanitize a section path - @param secpath The section path - @param format The format of the INI file - @return The new length of the string + @brief Sanitize a section path + @param secpath The section path + @param format The format of the INI file + @return The new length of the string Out of quotes, similar to ECMAScript `secpath.replace(/\.*\s*$|(?:\s*(\.))+\s*|^\s+/g, "$1").replace(/\s+/g, " ")` @@ -1161,29 +1201,32 @@ static size_t unescape_cr_lf ( quotes (if these are enabled) are prevented from changes. **/ -static size_t sanitize_section_path (char * const secpath, const IniFormat format) { +static size_t sanitize_section_path ( + char * const secpath, + const IniFormat format +) { /* Mask `abcd` (12 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes - FLAG_32 These are initial spaces - FLAG_64 This is a space out of quotes - FLAG_128 This is a dot out of quotes - FLAG_256 This is anything *but* an opening single/double quote - FLAG_512 Don't ignore the last two characters - FLAG_1024 Don't overwrite the previous character - FLAG_2048 Path contains at least one name + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes + FLAG_32 These are initial spaces + FLAG_64 This is a space out of quotes + FLAG_128 This is a dot out of quotes + FLAG_256 This is anything *but* an opening single/double quote + FLAG_512 Don't ignore the last two characters + FLAG_1024 Don't overwrite the previous character + FLAG_2048 Path contains at least one name */ - register uint_least16_t - abcd = (format.no_double_quotes ? 1826 : 1824) | format.no_single_quotes; + register uint_least16_t abcd = + (format.no_double_quotes ? 1826 : 1824) | format.no_single_quotes; register size_t idx_s = 0, idx_d = 0; @@ -1191,42 +1234,44 @@ static size_t sanitize_section_path (char * const secpath, const IniFormat forma /* Revision #2 */ - abcd = !(abcd & 12) && is_some_space(secpath[idx_s], _LIBCONFINI_WITH_EOL_) ? - ( - abcd & 224 ? - (abcd & 3055) | 832 - : - (abcd & 4079) | 1856 - ) - : !(abcd & 12) && secpath[idx_s] == _LIBCONFINI_SUBSECTION_ ? - ( - abcd & (abcd & 32 ? 128 : 192) ? - (abcd & 2959) | 896 - : - (abcd & 3983) | 1920 - ) - : !(abcd & 25) && secpath[idx_s] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - ~abcd & 4 ? - (abcd & 3839) | 1540 - : abcd & 256 ? - (abcd & 3867) | 3840 - : - (abcd & 3579) | 1280 - ) - : !(abcd & 22) && secpath[idx_s] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - ~abcd & 8 ? - (abcd & 3839) | 1544 - : abcd & 256 ? - (abcd & 3863) | 3840 - : - (abcd & 3575) | 1280 - ) - : secpath[idx_s] == _LIBCONFINI_BACKSLASH_ ? - ((abcd & 3871) | 3840) ^ 16 + abcd = + + !(abcd & 12) && is_some_space(secpath[idx_s], _CONFINI_WITH_EOL_) ? + ( + abcd & 224 ? + (abcd & 3055) | 832 + : + (abcd & 4079) | 1856 + ) + : !(abcd & 12) && secpath[idx_s] == _CONFINI_SUBSECTION_ ? + ( + abcd & (abcd & 32 ? 128 : 192) ? + (abcd & 2959) | 896 + : + (abcd & 3983) | 1920 + ) + : !(abcd & 25) && secpath[idx_s] == _CONFINI_S_QUOTES_ ? + ( + ~abcd & 4 ? + (abcd & 3839) | 1540 + : abcd & 256 ? + (abcd & 3867) | 3840 + : + (abcd & 3579) | 1280 + ) + : !(abcd & 22) && secpath[idx_s] == _CONFINI_D_QUOTES_ ? + ( + ~abcd & 8 ? + (abcd & 3839) | 1544 + : abcd & 256 ? + (abcd & 3863) | 3840 : - (abcd & 3855) | 3840; + (abcd & 3575) | 1280 + ) + : secpath[idx_s] == _CONFINI_BACKSLASH_ ? + ((abcd & 3871) | 3840) ^ 16 + : + (abcd & 3855) | 3840; if (abcd & 512) { @@ -1238,12 +1283,13 @@ static size_t sanitize_section_path (char * const secpath, const IniFormat forma idx_d - 1 : idx_d - ] = !(~abcd & 384) ? - _LIBCONFINI_SUBSECTION_ - : !(~abcd & 320) ? - _LIBCONFINI_COLLAPSED_ - : - secpath[idx_s]; + ] = + !(~abcd & 384) ? + _CONFINI_SUBSECTION_ + : !(~abcd & 320) ? + _CONFINI_COLLAPSED_ + : + secpath[idx_s]; } else if (idx_d) { @@ -1255,10 +1301,11 @@ static size_t sanitize_section_path (char * const secpath, const IniFormat forma for ( - idx_s = idx_d && (abcd & 2048) && (abcd & 192) ? - --idx_d - : - idx_d; + idx_s = + idx_d && (abcd & 2048) && (abcd & 192) ? + --idx_d + : + idx_d; secpath[idx_s]; @@ -1273,74 +1320,79 @@ static size_t sanitize_section_path (char * const secpath, const IniFormat forma /** - @brief Out of quotes similar to ECMAScript - `ini_string.replace(/''|""/g, "").replace(/^[\n\r]\s*|\s+/g, " ")` - @param ini_string The string to collapse -- multi-line escape - sequences must be already unescaped at - this stage - @param format The format of the INI file - @return The new length of the string + @brief Out of quotes similar to ECMAScript + `ini_string.replace(/''|""/g, "").replace(/^[\n\r]\s*|\s+/g, + " ")` + @param ini_string The string to collapse -- multi-line escape + sequences must be already unescaped at + this stage + @param format The format of the INI file + @return The new length of the string **/ -static size_t collapse_everything (char * const ini_string, const IniFormat format) { +static size_t collapse_everything ( + char * const ini_string, + const IniFormat format +) { /* Mask `abcd` (9 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes - FLAG_32 This is *not* a space out of quotes - FLAG_64 This is an opening single/double quote - FLAG_128 Don't ignore this character - FLAG_256 Jump this character and the one before this + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes + FLAG_32 This is *not* a space out of quotes + FLAG_64 This is an opening single/double quote + FLAG_128 Don't ignore this character + FLAG_256 Jump this character and the one before this */ register size_t idx_s = 0, idx_d = 0; - register uint_least16_t - abcd = (is_some_space(*ini_string, _LIBCONFINI_WITH_EOL_) ? 128 : 160) | - (format.no_double_quotes << 1) | - format.no_single_quotes; - + register uint_least16_t abcd = + (is_some_space(*ini_string, _CONFINI_WITH_EOL_) ? 128 : 160) | + (format.no_double_quotes << 1) | + format.no_single_quotes; for (; ini_string[idx_s]; idx_s++) { /* Revision #2 */ - abcd = !(abcd & 12) && is_some_space(ini_string[idx_s], _LIBCONFINI_WITH_EOL_) ? - ( - abcd & 32 ? - (abcd & 143) | 128 - : - abcd & 47 - ) - : !(abcd & 25) && ini_string[idx_s] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - ~abcd & 4 ? - (abcd & 239) | 196 - : abcd & 64 ? - (abcd & 299) | 256 - : - (abcd & 171) | 160 - ) - : !(abcd & 22) && ini_string[idx_s] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - ~abcd & 8 ? - (abcd & 239) | 200 - : abcd & 64 ? - (abcd & 295) | 256 - : - (abcd & 167) | 160 - ) - : ini_string[idx_s] == _LIBCONFINI_BACKSLASH_ ? - ((abcd & 191) | 160) ^ 16 + abcd = + + !(abcd & 12) && is_some_space(ini_string[idx_s], _CONFINI_WITH_EOL_) ? + ( + abcd & 32 ? + (abcd & 143) | 128 : - (abcd & 175) | 160; + abcd & 47 + ) + : !(abcd & 25) && ini_string[idx_s] == _CONFINI_S_QUOTES_ ? + ( + ~abcd & 4 ? + (abcd & 239) | 196 + : abcd & 64 ? + (abcd & 299) | 256 + : + (abcd & 171) | 160 + ) + : !(abcd & 22) && ini_string[idx_s] == _CONFINI_D_QUOTES_ ? + ( + ~abcd & 8 ? + (abcd & 239) | 200 + : abcd & 64 ? + (abcd & 295) | 256 + : + (abcd & 167) | 160 + ) + : ini_string[idx_s] == _CONFINI_BACKSLASH_ ? + ((abcd & 191) | 160) ^ 16 + : + (abcd & 175) | 160; if (abcd & 256) { @@ -1349,10 +1401,11 @@ static size_t collapse_everything (char * const ini_string, const IniFormat form } else if (abcd & 128) { - ini_string[idx_d++] = abcd & 44 ? - ini_string[idx_s] - : - _LIBCONFINI_COLLAPSED_; + ini_string[idx_d++] = + abcd & 44 ? + ini_string[idx_s] + : + _CONFINI_COLLAPSED_; } @@ -1360,10 +1413,11 @@ static size_t collapse_everything (char * const ini_string, const IniFormat form for ( - idx_s = !(abcd & 32) && idx_d ? - --idx_d - : - idx_d; + idx_s = + !(abcd & 32) && idx_d ? + --idx_d + : + idx_d; ini_string[idx_s]; @@ -1378,33 +1432,36 @@ static size_t collapse_everything (char * const ini_string, const IniFormat form /** - @brief Out of quotes similar to ECMAScript - `ini_string.replace(/\s+/g, " ")` - @param ini_string The string to collapse -- multi-line escape - sequences must be already unescaped at this - stage - @param format The format of the INI file - @return The new length of the string + @brief Out of quotes similar to ECMAScript + `ini_string.replace(/\s+/g, " ")` + @param ini_string The string to collapse -- multi-line escape + sequences must be already unescaped at this + stage + @param format The format of the INI file + @return The new length of the string **/ -static size_t collapse_spaces (char * const ini_string, const IniFormat format) { +static size_t collapse_spaces ( + char * const ini_string, + const IniFormat format +) { /* Mask `abcd` (7 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes - FLAG_32 This is a space out of quotes - FLAG_64 Jump this character + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes + FLAG_32 This is a space out of quotes + FLAG_64 Jump this character */ - register uint_least8_t - abcd = (format.no_double_quotes ? 34 : 32) | format.no_single_quotes; + register uint_least8_t abcd = + (format.no_double_quotes ? 34 : 32) | format.no_single_quotes; register size_t idx_s = 0; size_t idx_d = 0; @@ -1413,26 +1470,31 @@ static size_t collapse_spaces (char * const ini_string, const IniFormat format) /* Revision #1 */ - abcd = !(abcd & 12) && is_some_space(ini_string[idx_s], _LIBCONFINI_WITH_EOL_) ? - ( - abcd & 32 ? - (abcd & 111) | 64 - : - (abcd & 47) | 32 - ) - : !(abcd & 25) && ini_string[idx_s] == _LIBCONFINI_SINGLE_QUOTES_ ? - (abcd & 15) ^ 4 - : !(abcd & 22) && ini_string[idx_s] == _LIBCONFINI_DOUBLE_QUOTES_ ? - (abcd & 15) ^ 8 - : ini_string[idx_s] == _LIBCONFINI_BACKSLASH_ ? - (abcd & 31) ^ 16 - : - abcd & 15; + abcd = + !(abcd & 12) && is_some_space(ini_string[idx_s], _CONFINI_WITH_EOL_) ? + ( + abcd & 32 ? + (abcd & 111) | 64 + : + (abcd & 47) | 32 + ) + : !(abcd & 25) && ini_string[idx_s] == _CONFINI_S_QUOTES_ ? + (abcd & 15) ^ 4 + : !(abcd & 22) && ini_string[idx_s] == _CONFINI_D_QUOTES_ ? + (abcd & 15) ^ 8 + : ini_string[idx_s] == _CONFINI_BACKSLASH_ ? + (abcd & 31) ^ 16 + : + abcd & 15; if (~abcd & 64) { - ini_string[idx_d++] = abcd & 32 ? _LIBCONFINI_COLLAPSED_ : ini_string[idx_s]; + ini_string[idx_d++] = + abcd & 32 ? + _CONFINI_COLLAPSED_ + : + ini_string[idx_s]; } @@ -1440,10 +1502,11 @@ static size_t collapse_spaces (char * const ini_string, const IniFormat format) for ( - idx_s = (abcd & 32) && idx_d ? - --idx_d - : - idx_d; + idx_s = + (abcd & 32) && idx_d ? + --idx_d + : + idx_d; ini_string[idx_s]; @@ -1458,55 +1521,60 @@ static size_t collapse_spaces (char * const ini_string, const IniFormat format) /** - @brief Similar to ECMAScript `str.replace(/''|""/g, "")` - @param str The string to collapse - @param format The format of the INI file - @return The new length of the string + @brief Similar to ECMAScript `str.replace(/''|""/g, "")` + @param str The string to collapse + @param format The format of the INI file + @return The new length of the string **/ -static size_t collapse_empty_quotes (char * const str, const IniFormat format) { +static size_t collapse_empty_quotes ( + char * const str, + const IniFormat format +) { /* Mask `abcd` (7 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes - FLAG_32 This is an opening single/double quote - FLAG_64 These are empty quotes + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes + FLAG_32 This is an opening single/double quote + FLAG_64 These are empty quotes */ register uint_least8_t abcd = (format.no_double_quotes << 1) | format.no_single_quotes; - register size_t lshift = ltrim_s(str, 0, _LIBCONFINI_WITH_EOL_), idx = lshift; + register size_t lshift = ltrim_s(str, 0, _CONFINI_WITH_EOL_), idx = lshift; for (; str[idx]; idx++) { /* Revision #1 */ - abcd = str[idx] == _LIBCONFINI_BACKSLASH_ ? - (abcd & 31) ^ 16 - : !(abcd & 22) && str[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - ~abcd & 40 ? - ((abcd & 47) | 32) ^ 8 - : - (abcd & 71) | 64 - ) - : !(abcd & 25) && str[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - ~abcd & 36 ? - ((abcd & 47) | 32) ^ 4 - : - (abcd & 75) | 64 - ) + abcd = + + str[idx] == _CONFINI_BACKSLASH_ ? + (abcd & 31) ^ 16 + : !(abcd & 22) && str[idx] == _CONFINI_D_QUOTES_ ? + ( + ~abcd & 40 ? + ((abcd & 47) | 32) ^ 8 : - abcd & 15; + (abcd & 71) | 64 + ) + : !(abcd & 25) && str[idx] == _CONFINI_S_QUOTES_ ? + ( + ~abcd & 36 ? + ((abcd & 47) | 32) ^ 4 + : + (abcd & 75) | 64 + ) + : + abcd & 15; str[idx - lshift] = str[idx]; @@ -1521,29 +1589,34 @@ static size_t collapse_empty_quotes (char * const str, const IniFormat format) { for (idx -= lshift; str[idx]; str[idx++] = '\0'); - return rtrim_h(str, idx - lshift, _LIBCONFINI_WITH_EOL_); + return rtrim_h(str, idx - lshift, _CONFINI_WITH_EOL_); } /** - @brief Remove all comment initializers (`#` and/or `;`) from the - beginning of each line of a comment - @param srcstr The comment to parse (it may contain multi-line - escape sequences) - @param len The length of @p srcstr - @param format The format of the INI file - @return The new length of the string + @brief Remove all comment initializers (`#` and/or `;`) from the + beginning of each line of a comment + @param srcstr The comment to parse (it may contain multi-line + escape sequences) + @param len The length of @p srcstr + @param format The format of the INI file + @return The new length of the string - - In multi-line comments: `srcstr.replace(/^[#;]+|(\n\r?|\r\n?)[\t \v\f]*[#;]+/g, "$1")` - - In single-line comments: `srcstr.replace(/^[#;]+/, "")` + - Multi-line comments: `srcstr.replace(/^[#;]+|(\n\r?|\r\n?)[\t \v\f]*[#;]+/g, + "$1")` + - Single-line comments: `srcstr.replace(/^[#;]+/, "")` The argument @p srcstr may begin with a comment initializer (`#` or `;` depending on the format), or with the character that immediately follows it. **/ -static size_t uncomment (char * const srcstr, size_t len, const IniFormat format) { +static size_t uncomment ( + char * const srcstr, + size_t len, + const IniFormat format +) { register size_t idx_s = 0, idx_d = 0; @@ -1555,29 +1628,31 @@ static size_t uncomment (char * const srcstr, size_t len, const IniFormat format Mask `abcd` (6 bits used): - FLAG_1 Don't erase any character - FLAG_2 We are in an odd sequence of backslashes - FLAG_4 This new line character is escaped - FLAG_8 This character is a comment character and follows - `/(\n\s*|\r\s*)/` - FLAG_16 This character is a part of a group of spaces that follow - a new line (`/(\n|\r)[\t \v\f]+/`) - FLAG_32 This character is *not* a new line character (`/[\r\n]/`) + FLAG_1 Don't erase any character + FLAG_2 We are in an odd sequence of backslashes + FLAG_4 This new line character is escaped + FLAG_8 This character is a comment character and follows + `/(\n\s*|\r\s*)/` + FLAG_16 This character is a part of a group of spaces that follow + a new line (`/(\n|\r)[\t \v\f]+/`) + FLAG_32 This character is *not* a new line character (`/[\r\n]/`) */ for (register uint_least8_t abcd = 8; idx_s < len; idx_s++) { - abcd = srcstr[idx_s] == _LIBCONFINI_BACKSLASH_ ? - ((abcd & 35) | 32) ^ 2 - : srcstr[idx_s] == _LIBCONFINI_LF_ || srcstr[idx_s] == _LIBCONFINI_CR_ ? - (abcd << 1) & 4 - : !(abcd & 32) && _LIBCONFINI_IS_ANY_MARKER_(srcstr[idx_s], format) ? - (abcd & 40) | 8 - : !(abcd & 40) && is_some_space(srcstr[idx_s], _LIBCONFINI_NO_EOL_) ? - (abcd & 57) | 16 - : - (abcd & 33) | 32; + abcd = + + srcstr[idx_s] == _CONFINI_BACKSLASH_ ? + ((abcd & 35) | 32) ^ 2 + : srcstr[idx_s] == _CONFINI_LF_ || srcstr[idx_s] == _CONFINI_CR_ ? + (abcd << 1) & 4 + : !(abcd & 32) && _CONFINI_IS_ANY_MARKER_(srcstr[idx_s], format) ? + (abcd & 40) | 8 + : !(abcd & 40) && is_some_space(srcstr[idx_s], _CONFINI_NO_EOL_) ? + (abcd & 57) | 16 + : + (abcd & 33) | 32; if (!(abcd & 25)) { @@ -1596,12 +1671,11 @@ static size_t uncomment (char * const srcstr, size_t len, const IniFormat format /* The comment cannot be multi-line */ - for ( - ; - idx_s < len && - _LIBCONFINI_IS_ANY_MARKER_(srcstr[idx_s], format); - idx_s++ - ); + while (idx_s < len && _CONFINI_IS_ANY_MARKER_(srcstr[idx_s], format)) { + + idx_s++; + + } if (!idx_s) { @@ -1609,11 +1683,18 @@ static size_t uncomment (char * const srcstr, size_t len, const IniFormat format } - for (; idx_s < len; srcstr[idx_d++] = srcstr[idx_s++]); + while (idx_s < len) { + + srcstr[idx_d++] = srcstr[idx_s++]; + } } - for (idx_s = idx_d; idx_s < len; srcstr[idx_s++] = '\0'); + for ( + idx_s = idx_d; + idx_s < len; + srcstr[idx_s++] = '\0' + ); return idx_d; @@ -1622,28 +1703,28 @@ static size_t uncomment (char * const srcstr, size_t len, const IniFormat format /** - @brief Try to determine the type of a member "as if it was active" - @param srcstr String containing an individual node (it may - contain multi-line escape sequences) - @param len Length of the node - @param allow_implicit A boolean: `true` if keys without a key-value - delimiter are allowed, `false` otherwise - @param format The format of the INI file - @return The node type (see header) + @brief Try to determine the type of a member **assuming it is active** + @param srcstr String containing an individual node (it may + contain multi-line escape sequences) + @param len Length of the node + @param allow_implicit A boolean: `true` if keys without a key-value + delimiter are allowed, `false` otherwise + @param format The format of the INI file + @return The active node type (see confini.h) **/ static uint_least8_t get_type_as_active ( const char * const srcstr, const size_t len, - const _LIBCONFINI_CHARBOOL_ allow_implicit, + const _CONFINI_CHARBOOL_ allow_implicit, const IniFormat format ) { - const _LIBCONFINI_CHARBOOL_ - invalid_delimiter = _LIBCONFINI_IS_ESC_CHAR_(format.delimiter_symbol, format); + const _CONFINI_CHARBOOL_ invalid_delimiter = + _CONFINI_IS_ESC_CHAR_(format.delimiter_symbol, format); if ( - !len || _LIBCONFINI_IS_ANY_MARKER_(*srcstr, format) || ( + !len || _CONFINI_IS_ANY_MARKER_(*srcstr, format) || ( *((unsigned char *) srcstr) == format.delimiter_symbol && !invalid_delimiter ) @@ -1658,7 +1739,7 @@ static uint_least8_t get_type_as_active ( if ( format.section_paths != INI_NO_SECTIONS && - *srcstr == _LIBCONFINI_OPEN_SECTION_ + *srcstr == _CONFINI_OPEN_SECTION_ ) { if (format.no_spaces_in_names) { @@ -1676,75 +1757,76 @@ static uint_least8_t get_type_as_active ( Mask `abcd` (10 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Only one level of nesting is allowed (const) - FLAG_8 Unescaped single quotes are odd right now - FLAG_16 Unescaped double quotes are odd right now - FLAG_32 We are in an odd sequence of backslashes - FLAG_64 This is a space - FLAG_128 What follows cannot contain spaces - FLAG_256 Continue the loop - FLAG_512 Section path is *not* valid + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Only one level of nesting is allowed (const) + FLAG_8 Unescaped single quotes are odd right now + FLAG_16 Unescaped double quotes are odd right now + FLAG_32 We are in an odd sequence of backslashes + FLAG_64 This is a space + FLAG_128 What follows cannot contain spaces + FLAG_256 Continue the loop + FLAG_512 Section path is *not* valid */ - idx = 1; - abcd = (format.section_paths == INI_ONE_LEVEL_ONLY ? 772: 768) | - (format.no_double_quotes << 1) | - format.no_single_quotes; - + abcd = + (format.section_paths == INI_ONE_LEVEL_ONLY ? 772 : 768) | + (format.no_double_quotes << 1) | + format.no_single_quotes; do { /* Revision #2 */ - abcd = idx >= len ? + abcd = + + idx >= len ? + abcd & 767 + : !(abcd & 42) && srcstr[idx] == _CONFINI_D_QUOTES_ ? + (abcd & 991) ^ 16 + : !(abcd & 49) && srcstr[idx] == _CONFINI_S_QUOTES_ ? + (abcd & 991) ^ 8 + : srcstr[idx] == _CONFINI_LF_ || srcstr[idx] == _CONFINI_CR_ ? + (abcd & 991) | 64 + : is_some_space(srcstr[idx], _CONFINI_NO_EOL_) ? + ( + ~abcd & 32 ? + abcd | 64 + : ~abcd & 192 ? + (abcd & 991) | 192 + : + (abcd & 767) | 128 + ) + : !(abcd & 28) && srcstr[idx] == _CONFINI_SUBSECTION_ ? + ( + ~abcd & 224 ? + abcd & 799 + : abcd & 767 - : !(abcd & 42) && srcstr[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - (abcd & 991) ^ 16 - : !(abcd & 49) && srcstr[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - (abcd & 991) ^ 8 - : srcstr[idx] == _LIBCONFINI_LF_ || srcstr[idx] == _LIBCONFINI_CR_ ? - (abcd & 991) | 64 - : is_some_space(srcstr[idx], _LIBCONFINI_NO_EOL_) ? - ( - ~abcd & 32 ? - abcd | 64 - : ~abcd & 192 ? - (abcd & 991) | 192 - : - (abcd & 767) | 128 - ) - : !(abcd & 28) && srcstr[idx] == _LIBCONFINI_SUBSECTION_ ? - ( - ~abcd & 224 ? - abcd & 799 - : - abcd & 767 - ) - : !(abcd & 24) && srcstr[idx] == _LIBCONFINI_CLOSE_SECTION_ ? - ( - ~abcd & 224 ? - abcd & 159 - : - abcd & 767 - ) - : srcstr[idx] == _LIBCONFINI_BACKSLASH_ ? - ( - ~abcd & 32 ? - abcd | 32 - : ~abcd & 192 ? - (abcd & 991) | 128 - : - (abcd & 735) - ) + ) + : !(abcd & 24) && srcstr[idx] == _CONFINI_CLOSE_SECTION_ ? + ( + ~abcd & 224 ? + abcd & 159 + : + abcd & 767 + ) + : srcstr[idx] == _CONFINI_BACKSLASH_ ? + ( + ~abcd & 32 ? + abcd | 32 : ~abcd & 192 ? - (abcd & 927) | 128 + (abcd & 991) | 128 : - (abcd & 671) | 128; + (abcd & 735) + ) + : ~abcd & 192 ? + (abcd & 927) | 128 + : + (abcd & 671) | 128; idx++; @@ -1760,7 +1842,7 @@ static uint_least8_t get_type_as_active ( } else if ( (idx = getn_metachar_pos( srcstr, - _LIBCONFINI_CLOSE_SECTION_, + _CONFINI_CLOSE_SECTION_, len, format ) + 1) > len @@ -1782,12 +1864,12 @@ static uint_least8_t get_type_as_active ( Recycling variable `abcd` (6 bits used)...: - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes - FLAG_32 Continue the loop + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes + FLAG_32 Continue the loop */ @@ -1803,31 +1885,31 @@ static uint_least8_t get_type_as_active ( switch (srcstr[idx++]) { - case _LIBCONFINI_VT_: - case _LIBCONFINI_FF_: - case _LIBCONFINI_HT_: - case _LIBCONFINI_SIMPLE_SPACE_: + case _CONFINI_VT_: + case _CONFINI_FF_: + case _CONFINI_HT_: + case _CONFINI_SIMPLE_SPACE_: abcd = abcd & 28 ? 0 : abcd & 47; continue; - case _LIBCONFINI_LF_: - case _LIBCONFINI_CR_: + case _CONFINI_LF_: + case _CONFINI_CR_: abcd = abcd & 12 ? 0 : abcd & 47; continue; - case _LIBCONFINI_BACKSLASH_: + case _CONFINI_BACKSLASH_: abcd = abcd & 28 ? 0 : abcd | 16; continue; - case _LIBCONFINI_DOUBLE_QUOTES_: + case _CONFINI_D_QUOTES_: abcd = abcd & 22 ? 0 : (abcd & 47) ^ 8; continue; - case _LIBCONFINI_SINGLE_QUOTES_: + case _CONFINI_S_QUOTES_: abcd = abcd & 25 ? 0 : (abcd & 47) ^ 4; continue; @@ -1856,8 +1938,8 @@ static uint_least8_t get_type_as_active ( Recycling variable `abcd` (2 bits used)...: - FLAG_1 The delimiter **must** be present - FLAG_2 Search for spaces in names + FLAG_1 The delimiter **must** be present + FLAG_2 Search for spaces in names */ @@ -1884,7 +1966,7 @@ static uint_least8_t get_type_as_active ( do { - if (is_some_space(srcstr[--idx], _LIBCONFINI_WITH_EOL_)) { + if (is_some_space(srcstr[--idx], _CONFINI_WITH_EOL_)) { return INI_UNKNOWN; @@ -1903,44 +1985,46 @@ static uint_least8_t get_type_as_active ( /** - @brief Examine a (single-/multi-line) segment and check whether - it contains more than just one node - @param srcstr Segment to examine (it may contain multi-line - escape sequences) - @param format The format of the INI file - @return Number of entries found + @brief Examine a (single-/multi-line) segment and check whether + it contains more than just one node + @param srcstr Segment to examine (it may contain multi-line + escape sequences) + @param format The format of the INI file + @return Number of entries found **/ -static size_t further_cuts (char * const srcstr, const IniFormat format) { +static size_t further_cuts ( + char * const srcstr, + const IniFormat format +) { /* Shared flags of mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Do not allow disabled entries after space (const) - FLAG_8 Formats supports multi-line entries everywhere (const) - FLAG_16 Formats supports multi-line entries everywhere except in - comments (const) - FLAG_32 Unescaped single quotes are odd right now - FLAG_64 Unescaped double quotes are odd right now - FLAG_128 We are in an odd sequence of backslashes + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Do not allow disabled entries after space (const) + FLAG_8 Formats supports multi-line entries everywhere (const) + FLAG_16 Formats supports multi-line entries everywhere except in + comments (const) + FLAG_32 Unescaped single quotes are odd right now + FLAG_64 Unescaped double quotes are odd right now + FLAG_128 We are in an odd sequence of backslashes */ - register uint_least16_t - abcd = ((format.disabled_after_space << 2) ^ 4) | - (format.no_double_quotes << 1) | - format.no_single_quotes | ( - format.multiline_nodes == INI_MULTILINE_EVERYWHERE ? - 8 - : format.multiline_nodes == INI_BUT_COMMENTS ? - 16 - : - 0 - ); - + register uint_least16_t abcd = + ((format.disabled_after_space << 2) ^ 4) | + (format.no_double_quotes << 1) | + format.no_single_quotes | ( + format.multiline_nodes == INI_MULTILINE_EVERYWHERE ? + 8 + : format.multiline_nodes == INI_BUT_COMMENTS ? + 16 + : + 0 + ); register size_t idx; size_t focus_at, unparsable_at, search_at = 0, num_entries = 0; @@ -1959,20 +2043,22 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { unparsable_at = 0; - abcd = _LIBCONFINI_IS_DIS_MARKER_(srcstr[search_at], format) && ( - !(abcd & 4) || - !is_some_space(srcstr[search_at + 1], _LIBCONFINI_NO_EOL_) - ) ? - (abcd & 31) | 2560 - : _LIBCONFINI_IS_IGN_MARKER_(srcstr[search_at], format) ? - (abcd & 8 ? (abcd & 31) | 1024 : abcd & 31) - : (abcd & 8) && ( - srcstr[search_at] == _LIBCONFINI_IC_INT_MARKER_ || - _LIBCONFINI_IS_ANY_MARKER_(srcstr[search_at], format) - ) ? - (abcd & 31) | 3072 - : - (abcd & 31) | 2048; + abcd = + + _CONFINI_IS_DIS_MARKER_(srcstr[search_at], format) && ( + !(abcd & 4) || + !is_some_space(srcstr[search_at + 1], _CONFINI_NO_EOL_) + ) ? + (abcd & 31) | 2560 + : _CONFINI_IS_IGN_MARKER_(srcstr[search_at], format) ? + (abcd & 8 ? (abcd & 31) | 1024 : abcd & 31) + : (abcd & 8) && ( + srcstr[search_at] == _CONFINI_IC_INT_MARKER_ || + _CONFINI_IS_ANY_MARKER_(srcstr[search_at], format) + ) ? + (abcd & 31) | 3072 + : + (abcd & 31) | 2048; if (abcd & 2048) { @@ -1994,25 +2080,25 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { Mask `abcd` (14 bits used): - FLAG_256 This or the previous character was not a space - FLAG_512 We are in a disabled entry or a comment (semi-const) - FLAG_1024 We are in a simple comment or in a block that must be ignored - and format supports multi-line entries (semi-const) - FLAG_2048 We are *not* in a block that must be ignored (semi-const) - FLAG_4096 We have *not* just found an inline comment nested within a - disabled entry - FLAG_8192 We had previously found an inline comment nested in this - segment, but the entry that preceded it had been checked and - did not seem to represent a valid disabled entry - - NOTE: As for FLAG_1-FLAG_16 I keep the values already assigned at the - beginning of the function; all other flags are already set to - zero. For the meaning of flags FLAG_1-FLAG_128 see the beginning - of the function. + FLAG_256 This or the previous character was not a space + FLAG_512 We are in a disabled entry or a comment (semi-const) + FLAG_1024 We are in a simple comment or in a block that must be + ignored and format supports multi-line entries (semi-const) + FLAG_2048 We are *not* in a block that must be ignored (semi-const) + FLAG_4096 We have *not* just found an inline comment nested within a + disabled entry + FLAG_8192 We had previously found an inline comment nested in this + segment, but the entry that preceded it had been checked and + did not seem to represent a valid disabled entry + + NOTE: As for FLAG_1-FLAG_16 I keep the values already assigned at the + beginning of the function; all other flags are already set to zero. + For the meaning of flags FLAG_1-FLAG_128 see the beginning of the + function. */ - idx = ltrim_s(srcstr, search_at + 1, _LIBCONFINI_NO_EOL_) - 1; + idx = ltrim_s(srcstr, search_at + 1, _CONFINI_NO_EOL_) - 1; /* \ /\ @@ -2051,7 +2137,7 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { ) ) { - srcstr[search_at] = _LIBCONFINI_SC_INT_MARKER_; + srcstr[search_at] = _CONFINI_BC_INT_MARKER_; unparsable_at = search_at + 1; } @@ -2060,8 +2146,8 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { break; - case _LIBCONFINI_LF_: - case _LIBCONFINI_CR_: + case _CONFINI_LF_: + case _CONFINI_CR_: /* @@ -2071,19 +2157,20 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { */ focus_at = dqultrim_s(srcstr, search_at, format); - idx = ltrim_s(srcstr, idx + 1, _LIBCONFINI_WITH_EOL_); + idx = ltrim_s(srcstr, idx + 1, _CONFINI_WITH_EOL_); if ( idx <= focus_at && (abcd & 2048) && ( ( - _LIBCONFINI_IS_DIS_MARKER_(srcstr[idx], format) && !( + _CONFINI_IS_DIS_MARKER_(srcstr[idx], format) && !( (abcd & 24) && ( - (~abcd & 516) || - !is_some_space(srcstr[idx + 1], _LIBCONFINI_NO_EOL_) + (~abcd & 516) || !is_some_space( + srcstr[idx + 1], + _CONFINI_NO_EOL_ + ) ) ) - ) || - _LIBCONFINI_IS_COM_MARKER_(srcstr[idx], format) + ) || _CONFINI_IS_COM_MARKER_(srcstr[idx], format) ) ) { @@ -2097,7 +2184,7 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { */ - srcstr[search_at] = _LIBCONFINI_SC_INT_MARKER_; + srcstr[search_at] = _CONFINI_BC_INT_MARKER_; if (abcd & 8) { @@ -2115,9 +2202,11 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { abcd & 512 ? !(abcd & 24) || ( ( - !_LIBCONFINI_IS_DIS_MARKER_(srcstr[idx], format) || ( - (abcd & 4) && - is_some_space(srcstr[idx + 1], _LIBCONFINI_NO_EOL_) + !_CONFINI_IS_DIS_MARKER_(srcstr[idx], format) || ( + (abcd & 4) && is_some_space( + srcstr[idx + 1], + _CONFINI_NO_EOL_ + ) ) ) && ( idx > focus_at /* see issue #16 */ && @@ -2128,16 +2217,17 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { format ) ) - ) || - !_LIBCONFINI_IS_ANY_MARKER_(srcstr[idx], format) + ) || !_CONFINI_IS_ANY_MARKER_(srcstr[idx], format) : abcd & 2048 ? !(abcd & 8) || - !_LIBCONFINI_IS_N_I_MARKER_(srcstr[idx], format) + !_CONFINI_IS_N_I_MARKER_(srcstr[idx], format) : - !_LIBCONFINI_IS_IGN_MARKER_(srcstr[idx], format) + !_CONFINI_IS_IGN_MARKER_(srcstr[idx], format) ) { - rtrim_h(srcstr, idx, _LIBCONFINI_WITH_EOL_); + /* Split this line from the previous entry */ + + rtrim_h(srcstr, idx, _CONFINI_WITH_EOL_); search_at = qultrim_h(srcstr, idx, format); goto search_for_cuts; @@ -2150,34 +2240,37 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { */ - case _LIBCONFINI_VT_: - case _LIBCONFINI_FF_: - case _LIBCONFINI_HT_: - case _LIBCONFINI_SIMPLE_SPACE_: + case _CONFINI_VT_: + case _CONFINI_FF_: + case _CONFINI_HT_: + case _CONFINI_SIMPLE_SPACE_: abcd = (abcd & 15999) | 4096; goto inactive_cut; - case _LIBCONFINI_BACKSLASH_: + case _CONFINI_BACKSLASH_: abcd = (abcd | 4352) ^ 128; goto inactive_cut; default: - abcd = !(abcd & 1376) && (~abcd & 8200) && - _LIBCONFINI_IS_ANY_MARKER_(srcstr[idx], format) ? - (abcd & 12159) | 256 - : !(abcd & 162) && srcstr[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ((abcd & 16255) | 4352) ^ 64 - : !(abcd & 193) && srcstr[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ((abcd & 16255) | 4352) ^ 32 - : - (abcd & 16255) | 4352; + abcd = + + !(abcd & 1376) && (~abcd & 8200) && + _CONFINI_IS_ANY_MARKER_(srcstr[idx], format) ? + (abcd & 12159) | 256 + : !(abcd & 162) && srcstr[idx] == _CONFINI_D_QUOTES_ ? + ((abcd & 16255) | 4352) ^ 64 + : !(abcd & 193) && srcstr[idx] == _CONFINI_S_QUOTES_ ? + ((abcd & 16255) | 4352) ^ 32 + : + (abcd & 16255) | 4352; if (abcd & 4096) { + /* Nothing special has been found */ goto inactive_cut; } @@ -2193,16 +2286,18 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { focus_at = dqultrim_s(srcstr, search_at, format); - if (get_type_as_active( - srcstr + focus_at, - idx - focus_at, - format.disabled_can_be_implicit, - format - )) { + if ( + get_type_as_active( + srcstr + focus_at, + idx - focus_at, + format.disabled_can_be_implicit, + format + ) + ) { - if (!_LIBCONFINI_IS_IGN_MARKER_(srcstr[idx], format)) { + if (!_CONFINI_IS_IGN_MARKER_(srcstr[idx], format)) { - srcstr[idx] = _LIBCONFINI_IC_INT_MARKER_; + srcstr[idx] = _CONFINI_IC_INT_MARKER_; num_entries++; } @@ -2220,7 +2315,7 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { } else { - srcstr[search_at] = _LIBCONFINI_SC_INT_MARKER_; + srcstr[search_at] = _CONFINI_BC_INT_MARKER_; if (abcd & 8) { @@ -2239,7 +2334,7 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { } - } else if (_LIBCONFINI_IS_ANY_MARKER_(srcstr[search_at], format)) { + } else if (_CONFINI_IS_ANY_MARKER_(srcstr[search_at], format)) { /* @@ -2262,18 +2357,18 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { Recycling variable `abcd` (11 bits used)...: - FLAG_256 Comment marker follows an escaped new line made of only one - character (i.e., `"\\\n"` or `"\\\r"` but neither `"\\\r\n"` - or `"\\\n\r"`) - FLAG_512 This was neither a hash nor a semicolon character - FLAG_1024 This was not a space + FLAG_256 Comment marker follows an escaped new line made of only one + character (i.e., `"\\\n"` or `"\\\r"` but neither `"\\\r\n"` + nor `"\\\n\r"`) + FLAG_512 This was neither a hash nor a semicolon character + FLAG_1024 This was not a space - NOTE: As for FLAG_1-FLAG_16 I keep the values already assigned at the - beginning of the function; all other flags are already set to zero - (see previous usage of `abcd` within this function), with the only - exception of FLAG_2048, which I am going to overwrite immediately. - For the meaning of flags FLAG_1-FLAG_128 see the beginning of the - function. + NOTE: As for FLAG_1-FLAG_16 I keep the values already assigned at the + beginning of the function; all other flags are already set to zero + (see previous usage of `abcd` within this function), with the only + exception of FLAG_2048, which I am going to overwrite immediately. + For the meaning of flags FLAG_1-FLAG_128 see the beginning of the + function. */ @@ -2293,38 +2388,42 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { /* End of string */ break; - case _LIBCONFINI_VT_: - case _LIBCONFINI_FF_: - case _LIBCONFINI_HT_: - case _LIBCONFINI_SIMPLE_SPACE_: + case _CONFINI_VT_: + case _CONFINI_FF_: + case _CONFINI_HT_: + case _CONFINI_SIMPLE_SPACE_: abcd = (abcd & 639) | 512; goto active_cut; - case _LIBCONFINI_LF_: - case _LIBCONFINI_CR_: + case _CONFINI_LF_: + case _CONFINI_CR_: abcd = (abcd & 639) | ((abcd << 1) & 256) | 512; goto active_cut; - case _LIBCONFINI_BACKSLASH_: + case _CONFINI_BACKSLASH_: abcd = ((abcd & 1791) | 1536) ^ 128; goto active_cut; default: - abcd = _LIBCONFINI_IS_ANY_MARKER_(srcstr[idx], format) ? - abcd & 1407 - : !(abcd & 162) && srcstr[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ((abcd & 1791) | 1536) ^ 64 - : !(abcd & 193) && srcstr[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ((abcd & 1791) | 1536) ^ 32 - : - (abcd & 1791) | 1536; + abcd = + + _CONFINI_IS_ANY_MARKER_(srcstr[idx], format) ? + abcd & 1407 + : !(abcd & 162) && srcstr[idx] == _CONFINI_D_QUOTES_ ? + ((abcd & 1791) | 1536) ^ 64 + : !(abcd & 193) && srcstr[idx] == _CONFINI_S_QUOTES_ ? + ((abcd & 1791) | 1536) ^ 32 + : + (abcd & 1791) | 1536; + if (abcd & 1760) { + /* Nothing special has been found */ goto active_cut; } @@ -2353,9 +2452,9 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { srcstr[idx - 1] = '\0'; - if (!_LIBCONFINI_IS_IGN_MARKER_(srcstr[idx], format)) { + if (!_CONFINI_IS_IGN_MARKER_(srcstr[idx], format)) { - srcstr[idx] = _LIBCONFINI_IC_INT_MARKER_; + srcstr[idx] = _CONFINI_IC_INT_MARKER_; if (abcd & 8) { @@ -2390,7 +2489,7 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { for (idx = unparsable_at; srcstr[idx]; idx++) { - if (srcstr[idx] == _LIBCONFINI_LF_ || srcstr[idx] == _LIBCONFINI_CR_) { + if (srcstr[idx] == _CONFINI_LF_ || srcstr[idx] == _CONFINI_CR_) { search_at = qultrim_h(srcstr, idx, format); goto search_for_cuts; @@ -2420,22 +2519,22 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { /* LIBRARY'S MAIN FUNCTIONS */ - /** @utility{strip_ini_cache} **/ + /** @utility{strip_ini_cache} **/ /** - @brief Parse and tokenize a buffer containing an INI file, then - dispatch its content to a custom callback - @param ini_source The buffer containing the INI file to tokenize - @param ini_length The length of @p ini_source without counting the - NUL terminator (if any -- se below) - @param format The format of the INI file - @param f_init The function that will be invoked before the - first dispatch, or `NULL` - @param f_foreach The function that will be invoked for each - dispatch, or `NULL` - @param user_data A custom argument, or `NULL` - @return Zero for success, otherwise an error code (see `enum` - #ConfiniInterruptNo) + @brief Parse and tokenize a buffer containing an INI file, then + dispatch its content to a custom callback + @param ini_source The buffer containing the INI file to tokenize + @param ini_length The length of @p ini_source without counting the + NUL terminator (if any -- se below) + @param format The format of the INI file + @param f_init The function that will be invoked before the + first dispatch, or `NULL` + @param f_foreach The function that will be invoked for each + dispatch, or `NULL` + @param user_data A custom argument, or `NULL` + @return Zero for success, otherwise an error code (see `enum` + #ConfiniInterruptNo) The @p ini_source parameter must be a valid pointer to a buffer of size @p ini_length + 1 and cannot be `NULL`. The @p ini_source string does not need @@ -2476,9 +2575,9 @@ static size_t further_cuts (char * const srcstr, const IniFormat format) { ASCII (as they do, for example, in UTF-8 and ISO-8859-1), independently of platform-specific conventions. - @note In order to be null-byte-injection-safe, before dispatching the parsed - content this function will strip all `NUL` characters possibly present - in the buffer (with the exception of the last one). + @note In order to be null-byte-injection-safe, before dispatching the parsed + content this function strips all `NUL` characters possibly present in + the buffer (with the exception of the last one). Possible return values are: #CONFINI_SUCCESS, #CONFINI_IINTR, #CONFINI_FEINTR, #CONFINI_EOOR. @@ -2495,10 +2594,10 @@ int strip_ini_cache ( void * const user_data ) { - const _LIBCONFINI_CHARBOOL_ - valid_delimiter = !_LIBCONFINI_IS_ESC_CHAR_(format.delimiter_symbol, format); + const _CONFINI_CHARBOOL_ valid_delimiter = + !_CONFINI_IS_ESC_CHAR_(format.delimiter_symbol, format); - _LIBCONFINI_CHARBOOL_ tmp_bool; + _CONFINI_CHARBOOL_ tmp_bool; register size_t idx, tmp_fast_size_t_1, tmp_fast_size_t_2; size_t tmp_size_t_1, tmp_size_t_2; @@ -2517,16 +2616,17 @@ int strip_ini_cache ( #define __N_MEMBERS__ tmp_size_t_2 /* UTF-8 BOM */ - __LSHIFT__ = *((unsigned char *) ini_source) == 0xEF && - *((unsigned char *) ini_source + 1) == 0xBB && - *((unsigned char *) ini_source + 2) == 0xBF - ? 3 : 0; + __LSHIFT__ = + *((unsigned char *) ini_source) == 0xEF && + *((unsigned char *) ini_source + 1) == 0xBB && + *((unsigned char *) ini_source + 2) == 0xBF + ? 3 : 0; for ( __N_MEMBERS__ = 0, - __EOL_N__ = _LIBCONFINI_EOL_IDX_, - __ISNT_ESCAPED__ = _LIBCONFINI_TRUE_, + __EOL_N__ = _CONFINI_EOL_IDX_, + __ISNT_ESCAPED__ = _CONFINI_TRUE_, __NL_AT__ = 0, idx = __LSHIFT__; @@ -2539,8 +2639,8 @@ int strip_ini_cache ( ini_source[idx - __LSHIFT__] = ini_source[idx]; if ( - ini_source[idx] == _LIBCONFINI_SPACES_[__EOL_N__] || - ini_source[idx] == _LIBCONFINI_SPACES_[__EOL_N__ ^= 1] + ini_source[idx] == _CONFINI_SPACES_[__EOL_N__] || + ini_source[idx] == _CONFINI_SPACES_[__EOL_N__ ^= 1] ) { if (format.multiline_nodes == INI_NO_MULTILINE || __ISNT_ESCAPED__) { @@ -2552,22 +2652,22 @@ int strip_ini_cache ( ); __NL_AT__ = idx - __LSHIFT__ + 1; - } else if (ini_source[idx + 1] == _LIBCONFINI_SPACES_[__EOL_N__ ^ 1]) { + } else if (ini_source[idx + 1] == _CONFINI_SPACES_[__EOL_N__ ^ 1]) { idx++; ini_source[idx - __LSHIFT__] = ini_source[idx]; } - __ISNT_ESCAPED__ = _LIBCONFINI_TRUE_; + __ISNT_ESCAPED__ = _CONFINI_TRUE_; - } else if (ini_source[idx] == _LIBCONFINI_BACKSLASH_) { + } else if (ini_source[idx] == _CONFINI_BACKSLASH_) { __ISNT_ESCAPED__ = !__ISNT_ESCAPED__; } else if (ini_source[idx]) { - __ISNT_ESCAPED__ = _LIBCONFINI_TRUE_; + __ISNT_ESCAPED__ = _CONFINI_TRUE_; } else { @@ -2650,7 +2750,7 @@ int strip_ini_cache ( .dispatch_id = 0 }; - __PARENT_IS_DISABLED__ = _LIBCONFINI_FALSE_; + __PARENT_IS_DISABLED__ = _CONFINI_FALSE_; for (__NODE_AT__ = 0, idx = 0; idx <= real_length; idx++) { @@ -2662,7 +2762,7 @@ int strip_ini_cache ( if ( !ini_source[__NODE_AT__] || - _LIBCONFINI_IS_IGN_MARKER_(ini_source[__NODE_AT__], format) + _CONFINI_IS_IGN_MARKER_(ini_source[__NODE_AT__], format) ) { __NODE_AT__ = idx + 1; @@ -2688,9 +2788,9 @@ int strip_ini_cache ( dsp.v_len = 0; if ( - _LIBCONFINI_IS_DIS_MARKER_(*dsp.data, format) && ( + _CONFINI_IS_DIS_MARKER_(*dsp.data, format) && ( format.disabled_after_space || - !is_some_space(dsp.data[1], _LIBCONFINI_NO_EOL_) + !is_some_space(dsp.data[1], _CONFINI_NO_EOL_) ) ) { @@ -2725,14 +2825,15 @@ int strip_ini_cache ( default: - if (!_LIBCONFINI_IS_ANY_MARKER_(*dsp.data, format)) { + if (!_CONFINI_IS_ANY_MARKER_(*dsp.data, format)) { dsp.type = get_type_as_active( dsp.data, dsp.d_len, - _LIBCONFINI_TRUE_, + _CONFINI_TRUE_, format ); + break; } @@ -2740,12 +2841,12 @@ int strip_ini_cache ( /* No case break here, keep it like this! - `case _LIBCONFINI_SC_INT_MARKER_` must follow + `case _CONFINI_BC_INT_MARKER_` must follow (switch case fallthrough). */ - case _LIBCONFINI_SC_INT_MARKER_: + case _CONFINI_BC_INT_MARKER_: /* @@ -2755,10 +2856,9 @@ int strip_ini_cache ( */ dsp.type = INI_COMMENT; - break; - case _LIBCONFINI_IC_INT_MARKER_: + case _CONFINI_IC_INT_MARKER_: /* @@ -2796,13 +2896,13 @@ int strip_ini_cache ( real_parent_str[__REAL_PARENT_LEN__] = '\0'; __CURR_PARENT_LEN__ = __REAL_PARENT_LEN__; curr_parent_str = real_parent_str; - __PARENT_IS_DISABLED__ = _LIBCONFINI_FALSE_; + __PARENT_IS_DISABLED__ = _CONFINI_FALSE_; } else if (!__PARENT_IS_DISABLED__ && dsp.type == INI_DISABLED_SECTION) { __REAL_PARENT_LEN__ = __CURR_PARENT_LEN__; real_parent_str = curr_parent_str; - __PARENT_IS_DISABLED__ = _LIBCONFINI_TRUE_; + __PARENT_IS_DISABLED__ = _CONFINI_TRUE_; } @@ -2843,7 +2943,7 @@ int strip_ini_cache ( __ITER__ = getn_metachar_pos( dsp.data, - _LIBCONFINI_CLOSE_SECTION_, + _CONFINI_CLOSE_SECTION_, dsp.d_len, format ); @@ -2854,15 +2954,15 @@ int strip_ini_cache ( } - dsp.d_len = format.section_paths == INI_ONE_LEVEL_ONLY ? - collapse_everything(dsp.data, format) - : - sanitize_section_path(dsp.data, format); - + dsp.d_len = + format.section_paths == INI_ONE_LEVEL_ONLY ? + collapse_everything(dsp.data, format) + : + sanitize_section_path(dsp.data, format); if ( format.section_paths == INI_ONE_LEVEL_ONLY || - *dsp.data != _LIBCONFINI_SUBSECTION_ + *dsp.data != _CONFINI_SUBSECTION_ ) { /* @@ -2948,12 +3048,14 @@ int strip_ini_cache ( case 4: - dsp.value += ltrim_h(dsp.value, 0, _LIBCONFINI_WITH_EOL_); + dsp.value += ltrim_h(dsp.value, 0, _CONFINI_WITH_EOL_); + dsp.v_len = rtrim_h( dsp.value, dsp.d_len + dsp.data - dsp.value, - _LIBCONFINI_WITH_EOL_ + _CONFINI_WITH_EOL_ ); + /* No case break here (last case) */ } @@ -3010,25 +3112,25 @@ int strip_ini_cache ( } -/*@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(IO_FUNCTIONS)! @@@@@@@@@@@@@@@@@@@@@@@*/ - /** @utility{load_ini_file} **/ +/*@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(IO_FUNCTIONS)! @@@@@@@@@@@@@@@@@@@@@@@@*/ + /** @utility{load_ini_file} **/ /** - @brief Parse an INI file and dispatch its content to a custom callback - using a `FILE` structure as argument - @param ini_file The `FILE` handle pointing to the INI file to - parse - @param format The format of the INI file - @param f_init The function that will be invoked before the - first dispatch, or `NULL` - @param f_foreach The function that will be invoked for each - dispatch, or `NULL` - @param user_data A custom argument, or `NULL` - @return Zero for success, otherwise an error code (see `enum` - #ConfiniInterruptNo) - - @note This function is absent if the `--without-io-api` option was passed to - the `configure` script when the library was compiled + @brief Parse an INI file and dispatch its content to a custom callback + using a `FILE` structure as argument + @param ini_file The `FILE` handle pointing to the INI file to + parse + @param format The format of the INI file + @param f_init The function that will be invoked before the + first dispatch, or `NULL` + @param f_foreach The function that will be invoked for each + dispatch, or `NULL` + @param user_data A custom argument, or `NULL` + @return Zero for success, otherwise an error code (see `enum` + #ConfiniInterruptNo) + + @note This function is absent if the `--without-io-api` option was passed to + the `configure` script when the library was compiled The @p ini_file parameter must be a `FILE` handle with read privileges. On some platforms, such as Microsoft Windows, it might be necessary to add the binary @@ -3048,8 +3150,8 @@ int strip_ini_cache ( ASCII (as they do, for example, in UTF-8 and ISO-8859-1), independently of platform-specific conventions. - @note In order to be null-byte-injection safe, `NUL` characters, if present in - the file, will be removed from the dispatched strings. + @note In order to be null-byte-injection safe, `NUL` characters, if present in + the file, will be removed from the dispatched strings. Possible return values are: #CONFINI_SUCCESS, #CONFINI_IINTR, #CONFINI_FEINTR, #CONFINI_ENOMEM, #CONFINI_EIO, #CONFINI_EOOR, #CONFINI_EBADF, #CONFINI_EFBIG. @@ -3065,11 +3167,11 @@ int load_ini_file ( void * const user_data ) { - _LIBCONFINI_OFF_T_ file_size; + _CONFINI_OFF_T_ file_size; if ( - _LIBCONFINI_SEEK_EOF_(ini_file) || - (file_size = _LIBCONFINI_FTELL_(ini_file)) < 0 + _CONFINI_SEEK_EOF_(ini_file) || + (file_size = _CONFINI_FTELL_(ini_file)) < 0 ) { return CONFINI_EBADF; @@ -3114,23 +3216,23 @@ int load_ini_file ( } - /** @utility{load_ini_path} **/ + /** @utility{load_ini_path} **/ /** - @brief Parse an INI file and dispatch its content to a custom callback - using a path as argument - @param path The path of the INI file - @param format The format of the INI file - @param f_init The function that will be invoked before the - first dispatch, or `NULL` - @param f_foreach The function that will be invoked for each - dispatch, or `NULL` - @param user_data A custom argument, or `NULL` - @return Zero for success, otherwise an error code (see `enum` - #ConfiniInterruptNo) - - @note This function is absent if the `--without-io-api` option was passed to - the `configure` script when the library was compiled + @brief Parse an INI file and dispatch its content to a custom callback + using a path as argument + @param path The path of the INI file + @param format The format of the INI file + @param f_init The function that will be invoked before the + first dispatch, or `NULL` + @param f_foreach The function that will be invoked for each + dispatch, or `NULL` + @param user_data A custom argument, or `NULL` + @return Zero for success, otherwise an error code (see `enum` + #ConfiniInterruptNo) + + @note This function is absent if the `--without-io-api` option was passed to + the `configure` script when the library was compiled For the two parameters @p f_init and @p f_foreach see function #strip_ini_cache(). @@ -3141,8 +3243,8 @@ int load_ini_file ( ASCII (as they do, for example, in UTF-8 and ISO-8859-1), independently of platform-specific conventions. - @note In order to be null-byte-injection safe, `NUL` characters, if present in - the file, will be removed from the dispatched strings. + @note In order to be null-byte-injection safe, `NUL` characters, if present in + the file, will be removed from the dispatched strings. Possible return values are: #CONFINI_SUCCESS, #CONFINI_IINTR, #CONFINI_FEINTR, #CONFINI_ENOENT, #CONFINI_ENOMEM, #CONFINI_EIO, #CONFINI_EOOR, #CONFINI_EBADF, @@ -3167,11 +3269,11 @@ int load_ini_path ( } - _LIBCONFINI_OFF_T_ file_size; + _CONFINI_OFF_T_ file_size; if ( - _LIBCONFINI_SEEK_EOF_(ini_file) || - (file_size = _LIBCONFINI_FTELL_(ini_file)) < 0 + _CONFINI_SEEK_EOF_(ini_file) || + (file_size = _CONFINI_FTELL_(ini_file)) < 0 ) { return CONFINI_EBADF; @@ -3219,19 +3321,19 @@ int load_ini_path ( } -/*@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(IO_FUNCTIONS)! @@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(IO_FUNCTIONS)! @@@@@@@@@@@@@@@@@@@@@@@@@*/ /* OTHER UTILITIES (NOT REQUIRED BY LIBCONFINI'S MAIN FUNCTIONS) */ - /** @utility{ini_string_match_ss} **/ + /** @utility{ini_string_match_ss} **/ /** - @brief Compare two simple strings and check whether they match - @param simple_string_a The first simple string - @param simple_string_b The second simple string - @param format The format of the INI file - @return A boolean: `true` if the two strings match, `false` otherwise + @brief Compare two simple strings and check whether they match + @param simple_string_a The first simple string + @param simple_string_b The second simple string + @param format The format of the INI file + @return A boolean: `true` if the two strings match, `false` otherwise Simple strings are user-given strings or the result of #ini_string_parse(). The @p format argument is used for the following fields: @@ -3253,55 +3355,55 @@ bool ini_string_match_ss ( if (simple_string_a[idx] != simple_string_b[idx]) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } } while (simple_string_a[idx++]); - return _LIBCONFINI_TRUE_; + return _CONFINI_TRUE_; } do { if ( - _LIBCONFINI_CHR_CASEFOLD_(simple_string_a[idx]) != - _LIBCONFINI_CHR_CASEFOLD_(simple_string_b[idx]) + _CONFINI_CHR_CASEFOLD_(simple_string_a[idx]) != + _CONFINI_CHR_CASEFOLD_(simple_string_b[idx]) ) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } } while (simple_string_a[idx++]); - return _LIBCONFINI_TRUE_; + return _CONFINI_TRUE_; } - /** @utility{ini_string_match_si} **/ + /** @utility{ini_string_match_si} **/ /** - @brief Compare a simple string and an INI string and and check whether - they match - @param ini_string The INI string escaped according to - @p format - @param simple_string The simple string - @param format The format of the INI file - @return A boolean: `true` if the two strings match, `false` otherwise + @brief Compare a simple string and an INI string and and check whether + they match + @param ini_string The INI string escaped according to + @p format + @param simple_string The simple string + @param format The format of the INI file + @return A boolean: `true` if the two strings match, `false` otherwise This function grants that the result of the comparison between a simple string and an INI string ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} printf( - "%s\n", - ini_string_match_si(my_simple_string, my_ini_string, format) ? - "They match" - : - "They don't match" + "%s\n", + ini_string_match_si(my_simple_string, my_ini_string, format) ? + "They match" + : + "They don't match" ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3313,11 +3415,11 @@ bool ini_string_match_ss ( ini_string_parse(my_ini_string, format); printf( - "%s\n", - ini_string_match_ss(my_simple_string, my_ini_string, format) ? - "They match" - : - "They don't match" + "%s\n", + ini_string_match_ss(my_simple_string, my_ini_string, format) ? + "They match" + : + "They don't match" ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3350,25 +3452,25 @@ bool ini_string_match_si ( Mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Format supports escape sequences (const) - FLAG_8 Unescaped single quotes are odd right now - FLAG_16 Unescaped double quotes are odd right now - FLAG_32 This is an escaped single/double quote in a format that supports - single/double quotes - FLAG_64 This is a space - FLAG_128 Skip this character + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Format supports escape sequences (const) + FLAG_8 Unescaped single quotes are odd right now + FLAG_16 Unescaped double quotes are odd right now + FLAG_32 This is an escaped single/double quote in a format that supports + single/double quotes + FLAG_64 This is a space + FLAG_128 Skip this character */ - register uint_least8_t - abcd = INIFORMAT_HAS_NO_ESC(format) ? - 67 - : - 68 | - (format.no_double_quotes << 1) | - format.no_single_quotes; + register uint_least8_t abcd = + INIFORMAT_HAS_NO_ESC(format) ? + 67 + : + 68 | + (format.no_double_quotes << 1) | + format.no_single_quotes; register size_t idx_i = 0; size_t idx_s = 0, nbacksl = 0; @@ -3379,11 +3481,11 @@ bool ini_string_match_si ( \/ ______________________ \ */ - if ((abcd & 4) && ini_string[idx_i] == _LIBCONFINI_BACKSLASH_) { + if ((abcd & 4) && ini_string[idx_i] == _CONFINI_BACKSLASH_) { for ( abcd &= 63, nbacksl++; - ini_string[++idx_i] == _LIBCONFINI_BACKSLASH_; + ini_string[++idx_i] == _CONFINI_BACKSLASH_; nbacksl++ ); @@ -3391,26 +3493,28 @@ bool ini_string_match_si ( /* Keep this algorithm identical to #ini_get_bool_i() */ - abcd = !(abcd & 10) && ini_string[idx_i] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - nbacksl & 1 ? - (abcd & 63) | 32 - : - ((abcd & 223) | 128) ^ 16 - ) - : !(abcd & 17) && ini_string[idx_i] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - nbacksl & 1 ? - (abcd & 63) | 32 - : - ((abcd & 223) | 128) ^ 8 - ) - : (abcd & 24) || !is_some_space(ini_string[idx_i], _LIBCONFINI_WITH_EOL_) ? - abcd & 31 - : abcd & 64 ? - (abcd & 223) | 128 + abcd = + + !(abcd & 10) && ini_string[idx_i] == _CONFINI_D_QUOTES_ ? + ( + nbacksl & 1 ? + (abcd & 63) | 32 : - (abcd & 95) | 64; + ((abcd & 223) | 128) ^ 16 + ) + : !(abcd & 17) && ini_string[idx_i] == _CONFINI_S_QUOTES_ ? + ( + nbacksl & 1 ? + (abcd & 63) | 32 + : + ((abcd & 223) | 128) ^ 8 + ) + : (abcd & 24) || !is_some_space(ini_string[idx_i], _CONFINI_WITH_EOL_) ? + abcd & 31 + : abcd & 64 ? + (abcd & 223) | 128 + : + (abcd & 95) | 64; if (nbacksl) { @@ -3419,9 +3523,9 @@ bool ini_string_match_si ( while (--nbacksl) { - if (simple_string[idx_s++] != _LIBCONFINI_BACKSLASH_) { + if (simple_string[idx_s++] != _CONFINI_BACKSLASH_) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } @@ -3442,16 +3546,16 @@ bool ini_string_match_si ( if ( abcd & 64 ? - simple_string[idx_s] != _LIBCONFINI_COLLAPSED_ || + simple_string[idx_s] != _CONFINI_COLLAPSED_ || !simple_string[idx_s + 1] : format.case_sensitive ? ini_string[idx_i] != simple_string[idx_s] : - _LIBCONFINI_CHR_CASEFOLD_(ini_string[idx_i]) != - _LIBCONFINI_CHR_CASEFOLD_(simple_string[idx_s]) + _CONFINI_CHR_CASEFOLD_(ini_string[idx_i]) != + _CONFINI_CHR_CASEFOLD_(simple_string[idx_s]) ) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } @@ -3463,31 +3567,31 @@ bool ini_string_match_si ( } - return _LIBCONFINI_TRUE_; + return _CONFINI_TRUE_; } - /** @utility{ini_string_match_ii} **/ + /** @utility{ini_string_match_ii} **/ /** - @brief Compare two INI strings and check whether they match - @param ini_string_a The first INI string unescaped according to - @p format - @param ini_string_b The second INI string unescaped according to - @p format - @param format The format of the INI file - @return A boolean: `true` if the two strings match, `false` otherwise + @brief Compare two INI strings and check whether they match + @param ini_string_a The first INI string unescaped according to + @p format + @param ini_string_b The second INI string unescaped according to + @p format + @param format The format of the INI file + @return A boolean: `true` if the two strings match, `false` otherwise This function grants that the result of the comparison between two INI strings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} printf( - "%s\n", - ini_string_match_ii(my_ini_string_1, my_ini_string_2, format) ? - "They match" - : - "They don't match" + "%s\n", + ini_string_match_ii(my_ini_string_1, my_ini_string_2, format) ? + "They match" + : + "They don't match" ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3500,10 +3604,10 @@ bool ini_string_match_si ( ini_string_parse(my_ini_string_2, format); printf("%s\n", - ini_string_match_ss(my_ini_string_1, my_ini_string_2, format) ? - "They match" - : - "They don't match" + ini_string_match_ss(my_ini_string_1, my_ini_string_2, format) ? + "They match" + : + "They don't match" ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3529,25 +3633,25 @@ bool ini_string_match_ii ( const IniFormat format ) { - const _LIBCONFINI_CHARBOOL_ has_escape = !INIFORMAT_HAS_NO_ESC(format); - register _LIBCONFINI_CHARBOOL_ side = 1; - register _LIBCONFINI_CHARBOOL_ turn_allowed = _LIBCONFINI_TRUE_; + const _CONFINI_CHARBOOL_ has_escape = !INIFORMAT_HAS_NO_ESC(format); + register _CONFINI_CHARBOOL_ side = 1; + register _CONFINI_CHARBOOL_ turn_allowed = _CONFINI_TRUE_; uint_least8_t abcd_pair[2]; - const char * chrptr_pair[2] = { ini_string_a, ini_string_b }; + const char * ptr_pair[2] = { ini_string_a, ini_string_b }; size_t nbacksl_pair[2]; /* Masks `abcd_pair[0]` and `abcd_pair[1]` (7 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes and format supports - escape sequences - FLAG_32 This is a space - FLAG_64 Skip this character + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes and format supports + escape sequences + FLAG_32 This is a space + FLAG_64 Skip this character */ @@ -3562,26 +3666,27 @@ bool ini_string_match_ii ( nbacksl_pair[side] = 0; - if (has_escape && *chrptr_pair[side] == _LIBCONFINI_BACKSLASH_) { + if (has_escape && *ptr_pair[side] == _CONFINI_BACKSLASH_) { for ( nbacksl_pair[side]++; - *(++chrptr_pair[side]) == _LIBCONFINI_BACKSLASH_; + *(++ptr_pair[side]) == _CONFINI_BACKSLASH_; nbacksl_pair[side]++ ); - abcd_pair[side] = nbacksl_pair[side] & 1 ? - (abcd_pair[side] & 31) | 16 - : - abcd_pair[side] & 15; + abcd_pair[side] = + nbacksl_pair[side] & 1 ? + (abcd_pair[side] & 31) | 16 + : + abcd_pair[side] & 15; if ( ( (abcd_pair[side] & 9) || - *chrptr_pair[side] != _LIBCONFINI_SINGLE_QUOTES_ + *ptr_pair[side] != _CONFINI_S_QUOTES_ ) && ( (abcd_pair[side] & 6) || - *chrptr_pair[side] != _LIBCONFINI_DOUBLE_QUOTES_ + *ptr_pair[side] != _CONFINI_D_QUOTES_ ) ) { @@ -3591,24 +3696,26 @@ bool ini_string_match_ii ( } else { - abcd_pair[side] = !(abcd_pair[side] & 25) && - *chrptr_pair[side] == _LIBCONFINI_SINGLE_QUOTES_ ? - ((abcd_pair[side] & 111) | 64) ^ 4 - : !(abcd_pair[side] & 22) && - *chrptr_pair[side] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ((abcd_pair[side] & 111) | 64) ^ 8 - : !(abcd_pair[side] & 12) && - is_some_space(*chrptr_pair[side], _LIBCONFINI_WITH_EOL_) ? - (abcd_pair[side] & 111) | 96 - : *chrptr_pair[side] ? - abcd_pair[side] & 47 - : - abcd_pair[side] & 15; + abcd_pair[side] = + + !(abcd_pair[side] & 25) && + *ptr_pair[side] == _CONFINI_S_QUOTES_ ? + ((abcd_pair[side] & 111) | 64) ^ 4 + : !(abcd_pair[side] & 22) && + *ptr_pair[side] == _CONFINI_D_QUOTES_ ? + ((abcd_pair[side] & 111) | 64) ^ 8 + : !(abcd_pair[side] & 12) && + is_some_space(*ptr_pair[side], _CONFINI_WITH_EOL_) ? + (abcd_pair[side] & 111) | 96 + : *ptr_pair[side] ? + abcd_pair[side] & 47 + : + abcd_pair[side] & 15; if (abcd_pair[side] & 64) { - chrptr_pair[side]++; + ptr_pair[side]++; goto ii_match; } @@ -3622,13 +3729,13 @@ bool ini_string_match_ii ( } - turn_allowed = _LIBCONFINI_TRUE_; + turn_allowed = _CONFINI_TRUE_; if (nbacksl_pair[0] || nbacksl_pair[1]) { if (nbacksl_pair[0] >> 1 != nbacksl_pair[1] >> 1) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } @@ -3643,46 +3750,46 @@ bool ini_string_match_ii ( !(abcd_pair[side] & 32) : abcd_pair[(side ^= 1) ^ 1] & 32 - ) && *chrptr_pair[side] + ) && *ptr_pair[side] ) { - if (*chrptr_pair[side]++ != _LIBCONFINI_COLLAPSED_) { + if (*ptr_pair[side]++ != _CONFINI_COLLAPSED_) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } abcd_pair[side ^ 1] &= 95; - turn_allowed = _LIBCONFINI_FALSE_; + turn_allowed = _CONFINI_FALSE_; goto ii_match; } if ( format.case_sensitive ? - *chrptr_pair[0] != *chrptr_pair[1] + *ptr_pair[0] != *ptr_pair[1] : - _LIBCONFINI_CHR_CASEFOLD_(*chrptr_pair[0]) != - _LIBCONFINI_CHR_CASEFOLD_(*chrptr_pair[1]) + _CONFINI_CHR_CASEFOLD_(*ptr_pair[0]) != + _CONFINI_CHR_CASEFOLD_(*ptr_pair[1]) ) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } - if (*chrptr_pair[0]) { + if (*ptr_pair[0]) { - chrptr_pair[0]++; + ptr_pair[0]++; } - if (*chrptr_pair[1]) { + if (*ptr_pair[1]) { - chrptr_pair[1]++; + ptr_pair[1]++; } - if (*chrptr_pair[0] || *chrptr_pair[1]) { + if (*ptr_pair[0] || *ptr_pair[1]) { abcd_pair[0] &= 95; abcd_pair[1] &= 95; @@ -3691,22 +3798,22 @@ bool ini_string_match_ii ( } - return _LIBCONFINI_TRUE_; + return _CONFINI_TRUE_; } - /** @utility{ini_array_match} **/ + /** @utility{ini_array_match} **/ /** - @brief Compare two INI arrays and check whether they match - @param ini_string_a The first INI array - @param ini_string_b The second INI array - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @return A boolean: `true` if the two arrays match, `false` otherwise + @brief Compare two INI arrays and check whether they match + @param ini_string_a The first INI array + @param ini_string_b The second INI array + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @return A boolean: `true` if the two arrays match, `false` otherwise This function grants that the result of the comparison between two INI arrays will always match the the _literal_ comparison between the individual members @@ -3738,37 +3845,37 @@ bool ini_array_match ( const IniFormat format ) { - if (_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (_CONFINI_IS_ESC_CHAR_(delimiter, format)) { /* We have no delimiters (array has only one member) */ - return ini_string_match_ii(ini_string_a, ini_string_b, format); } - const _LIBCONFINI_CHARBOOL_ has_escape = !INIFORMAT_HAS_NO_ESC(format); - register _LIBCONFINI_CHARBOOL_ side = 1; - register _LIBCONFINI_CHARBOOL_ turn_allowed = _LIBCONFINI_TRUE_; + const _CONFINI_CHARBOOL_ has_escape = !INIFORMAT_HAS_NO_ESC(format); + register _CONFINI_CHARBOOL_ side = 1; + register _CONFINI_CHARBOOL_ turn_allowed = _CONFINI_TRUE_; uint_least8_t abcd_pair[2]; size_t nbacksl_pair[2]; - const char * chrptr_pair[2] = { - ini_string_a + ltrim_s(ini_string_a, 0, _LIBCONFINI_WITH_EOL_), - ini_string_b + ltrim_s(ini_string_b, 0, _LIBCONFINI_WITH_EOL_) + + const char * ptr_pair[2] = { + ini_string_a + ltrim_s(ini_string_a, 0, _CONFINI_WITH_EOL_), + ini_string_b + ltrim_s(ini_string_b, 0, _CONFINI_WITH_EOL_) }; /* Masks `abcd_pair[0]` and `abcd_pair[1]` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 We are in an odd sequence of backslashes and format supports - escape sequences - FLAG_32 This is a space - FLAG_64 This is a delimiter - FLAG_128 Skip this character + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 We are in an odd sequence of backslashes and format supports + escape sequences + FLAG_32 This is a space + FLAG_64 This is a delimiter + FLAG_128 Skip this character */ @@ -3783,26 +3890,25 @@ bool ini_array_match ( nbacksl_pair[side] = 0; - if (has_escape && *chrptr_pair[side] == _LIBCONFINI_BACKSLASH_) { + if (has_escape && *ptr_pair[side] == _CONFINI_BACKSLASH_) { for ( nbacksl_pair[side]++; - *(++chrptr_pair[side]) == _LIBCONFINI_BACKSLASH_; + *(++ptr_pair[side]) == _CONFINI_BACKSLASH_; nbacksl_pair[side]++ ); - abcd_pair[side] = nbacksl_pair[side] & 1 ? - (abcd_pair[side] & 31) | 16 - : - abcd_pair[side] & 15; + abcd_pair[side] = + nbacksl_pair[side] & 1 ? + (abcd_pair[side] & 31) | 16 + : + abcd_pair[side] & 15; if ( ( - (abcd_pair[side] & 9) || - *chrptr_pair[side] != _LIBCONFINI_SINGLE_QUOTES_ + (abcd_pair[side] & 9) || *ptr_pair[side] != _CONFINI_S_QUOTES_ ) && ( - (abcd_pair[side] & 6) || - *chrptr_pair[side] != _LIBCONFINI_DOUBLE_QUOTES_ + (abcd_pair[side] & 6) || *ptr_pair[side] != _CONFINI_D_QUOTES_ ) ) { @@ -3813,21 +3919,24 @@ bool ini_array_match ( } else { abcd_pair[side] = - !(abcd_pair[side] & 12) && - is_some_space(*chrptr_pair[side], _LIBCONFINI_WITH_EOL_) ? + + !(abcd_pair[side] & 12) && is_some_space( + *ptr_pair[side], + _CONFINI_WITH_EOL_ + ) ? ( delimiter || (abcd_pair[side] & 64) ? (abcd_pair[side] & 239) | 160 : (abcd_pair[side] & 111) | 96 ) - : delimiter && !(abcd_pair[side] & 12) && *chrptr_pair[side] == delimiter ? + : delimiter && !(abcd_pair[side] & 12) && *ptr_pair[side] == delimiter ? (abcd_pair[side] & 111) | 96 - : !(abcd_pair[side] & 25) && *chrptr_pair[side] == _LIBCONFINI_SINGLE_QUOTES_ ? + : !(abcd_pair[side] & 25) && *ptr_pair[side] == _CONFINI_S_QUOTES_ ? ((abcd_pair[side] & 175) | 128) ^ 4 - : !(abcd_pair[side] & 22) && *chrptr_pair[side] == _LIBCONFINI_DOUBLE_QUOTES_ ? + : !(abcd_pair[side] & 22) && *ptr_pair[side] == _CONFINI_D_QUOTES_ ? ((abcd_pair[side] & 175) | 128) ^ 8 - : *chrptr_pair[side] ? + : *ptr_pair[side] ? abcd_pair[side] & 47 : delimiter ? abcd_pair[side] & 15 @@ -3837,7 +3946,7 @@ bool ini_array_match ( if (abcd_pair[side] & 128) { - chrptr_pair[side]++; + ptr_pair[side]++; goto delimited_match; } @@ -3851,13 +3960,13 @@ bool ini_array_match ( } - turn_allowed = _LIBCONFINI_TRUE_; + turn_allowed = _CONFINI_TRUE_; if (nbacksl_pair[0] || nbacksl_pair[1]) { if (nbacksl_pair[0] >> 1 != nbacksl_pair[1] >> 1) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } @@ -3868,7 +3977,7 @@ bool ini_array_match ( if ((abcd_pair[0] ^ abcd_pair[1]) & 64) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } @@ -3878,17 +3987,17 @@ bool ini_array_match ( abcd_pair[side] & 96 : (abcd_pair[(side ^= 1) ^ 1] & 96) ^ 32 - ) && *chrptr_pair[side] + ) && *ptr_pair[side] ) { - if (*chrptr_pair[side]++ != _LIBCONFINI_COLLAPSED_) { + if (*ptr_pair[side]++ != _CONFINI_COLLAPSED_) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } abcd_pair[side ^ 1] &= 223; - turn_allowed = _LIBCONFINI_FALSE_; + turn_allowed = _CONFINI_FALSE_; goto delimited_match; } @@ -3897,13 +4006,13 @@ bool ini_array_match ( if ( format.case_sensitive ? - *chrptr_pair[0] != *chrptr_pair[1] + *ptr_pair[0] != *ptr_pair[1] : - _LIBCONFINI_CHR_CASEFOLD_(*chrptr_pair[0]) != - _LIBCONFINI_CHR_CASEFOLD_(*chrptr_pair[1]) + _CONFINI_CHR_CASEFOLD_(*ptr_pair[0]) != + _CONFINI_CHR_CASEFOLD_(*ptr_pair[1]) ) { - return _LIBCONFINI_FALSE_; + return _CONFINI_FALSE_; } @@ -3912,39 +4021,39 @@ bool ini_array_match ( } - if (*chrptr_pair[0]) { + if (*ptr_pair[0]) { - chrptr_pair[0]++; + ptr_pair[0]++; } - if (*chrptr_pair[1]) { + if (*ptr_pair[1]) { - chrptr_pair[1]++; + ptr_pair[1]++; } - if (*chrptr_pair[0] || *chrptr_pair[1]) { + if (*ptr_pair[0] || *ptr_pair[1]) { side = 1; goto delimited_match; } - return _LIBCONFINI_TRUE_; + return _CONFINI_TRUE_; } - /** @utility{ini_unquote} **/ + /** @utility{ini_unquote} **/ /** - @brief Unescape `\'`, `\"`, and `\\` and remove all unescaped quotes - (when single/double quotes are considered metacharacters in - respect to the format given) - @param ini_string The string to be unescaped - @param format The format of the INI file - @return The new length of the string + @brief Unescape `\'`, `\"`, and `\\` and remove all unescaped quotes + (when single/double quotes are considered metacharacters in + respect to the format given) + @param ini_string The string to be unescaped + @param format The format of the INI file + @return The new length of the string This function is very similar to #ini_string_parse(), except that does not bother collapsing the sequences of more than one space that might result from @@ -3962,9 +4071,9 @@ bool ini_array_match ( used as well). If the string does not contain quotes, or if quotes are considered to be normal characters, no changes will be made. - @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is - no-op and will only return the value of #INI_GLOBAL_IMPLICIT_V_LEN minus - the offset of @p ini_string within #INI_GLOBAL_IMPLICIT_VALUE. + @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is + no-op and will only return the value of #INI_GLOBAL_IMPLICIT_V_LEN minus + the offset of @p ini_string within #INI_GLOBAL_IMPLICIT_VALUE. The @p format argument is used for the following fields: @@ -3975,7 +4084,10 @@ bool ini_array_match ( @include topics/ini_string_parse.c **/ -size_t ini_unquote (char * const ini_string, const IniFormat format) { +size_t ini_unquote ( + char * const ini_string, + const IniFormat format +) { if (INI_IS_IMPLICIT_SUBSTR(ini_string)) { @@ -4006,14 +4118,14 @@ size_t ini_unquote (char * const ini_string, const IniFormat format) { Mask `abcd` (6 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Unescaped single quotes are odd right now - FLAG_8 Unescaped double quotes are odd right now - FLAG_16 This is an unescaped single quote and format supports single - quotes - FLAG_32 This is an unescaped double quote and format supports double - quotes + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Unescaped single quotes are odd right now + FLAG_8 Unescaped double quotes are odd right now + FLAG_16 This is an unescaped single quote and format supports single + quotes + FLAG_32 This is an unescaped double quote and format supports double + quotes */ @@ -4028,12 +4140,14 @@ size_t ini_unquote (char * const ini_string, const IniFormat format) { ) { - abcd = !(abcd & 6) && ini_string[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - (abcd & 47) | 32 - : !(abcd & 9) && ini_string[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - (abcd & 31) | 16 - : - abcd & 15; + abcd = + + !(abcd & 6) && ini_string[idx] == _CONFINI_D_QUOTES_ ? + (abcd & 47) | 32 + : !(abcd & 9) && ini_string[idx] == _CONFINI_S_QUOTES_ ? + (abcd & 31) | 16 + : + abcd & 15; if (!(nbacksl & 1) && (abcd & 48)) { @@ -4044,7 +4158,7 @@ size_t ini_unquote (char * const ini_string, const IniFormat format) { } - if (ini_string[idx] == _LIBCONFINI_BACKSLASH_) { + if (ini_string[idx] == _CONFINI_BACKSLASH_) { nbacksl++; @@ -4078,16 +4192,16 @@ size_t ini_unquote (char * const ini_string, const IniFormat format) { } - /** @utility{ini_string_parse} **/ + /** @utility{ini_string_parse} **/ /** - @brief Unescape `\'`, `\"`, and `\\` and remove all unescaped quotes - (when single/double quotes are considered metacharacters in - respect to the format given); if the format allows it, sequences - of one or more spaces out of quotes will be collapsed - @param ini_string The string to be unescaped - @param format The format of the INI file - @return The new length of the string + @brief Unescape `\'`, `\"`, and `\\` and remove all unescaped quotes + (when single/double quotes are considered metacharacters in + respect to the format given); if the format allows it, sequences + of one or more spaces out of quotes will be collapsed + @param ini_string The string to be unescaped + @param format The format of the INI file + @return The new length of the string This function is meant to be used to parse values. In order to parse key and section names please use #ini_unquote(). @@ -4102,9 +4216,9 @@ size_t ini_unquote (char * const ini_string, const IniFormat format) { used as well). If `format.do_not_collapse_values` is set to non-zero, spaces surrounding empty quotes will be collapsed together with the latter. - @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is - no-op and will only return the value of #INI_GLOBAL_IMPLICIT_V_LEN minus - the offset of @p ini_string within #INI_GLOBAL_IMPLICIT_VALUE. + @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is + no-op and will only return the value of #INI_GLOBAL_IMPLICIT_V_LEN minus + the offset of @p ini_string within #INI_GLOBAL_IMPLICIT_VALUE. The @p format argument is used for the following fields: @@ -4128,22 +4242,22 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { Mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Do not collapse spaces within members (const) - FLAG_8 Unescaped single quotes are odd right now - FLAG_16 Unescaped double quotes are odd right now - FLAG_32 This is an *escaped* single/double quote and format supports - single/double quotes - FLAG_64 This is a space - FLAG_128 Skip this character + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Do not collapse spaces within members (const) + FLAG_8 Unescaped single quotes are odd right now + FLAG_16 Unescaped double quotes are odd right now + FLAG_32 This is an *escaped* single/double quote and format supports + single/double quotes + FLAG_64 This is a space + FLAG_128 Skip this character */ - register uint_least8_t - abcd = (format.do_not_collapse_values ? 68 : 64) | - (format.no_double_quotes << 1) | - format.no_single_quotes; + register uint_least8_t abcd = + (format.do_not_collapse_values ? 68 : 64) | + (format.no_double_quotes << 1) | + format.no_single_quotes; size_t idx, lshift; @@ -4162,12 +4276,13 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { for (idx = 0, lshift = 0; ini_string[idx]; idx++) { - abcd = !is_some_space(ini_string[idx], _LIBCONFINI_WITH_EOL_) ? - 3 - : abcd & 64 ? - 195 - : - 67; + abcd = + !is_some_space(ini_string[idx], _CONFINI_WITH_EOL_) ? + 3 + : abcd & 64 ? + 195 + : + 67; if (abcd & 128) { @@ -4175,10 +4290,11 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { } else { - ini_string[idx - lshift] = abcd & 64 ? - _LIBCONFINI_COLLAPSED_ - : - ini_string[idx]; + ini_string[idx - lshift] = + abcd & 64 ? + _CONFINI_COLLAPSED_ + : + ini_string[idx]; } @@ -4186,10 +4302,11 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { for ( - idx -= (abcd & 64) && lshift < idx ? - ++lshift - : - lshift; + idx -= + (abcd & 64) && lshift < idx ? + ++lshift + : + lshift; ini_string[idx]; @@ -4204,14 +4321,14 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { /* There are no escape sequences and spaces do not need to be - collapsed, but left and right trim might still be necessary. + collapsed, but left and right trim might still be necessary... */ return rtrim_h( ini_string, - ltrim_hh(ini_string, 0, _LIBCONFINI_WITH_EOL_), - _LIBCONFINI_WITH_EOL_ + ltrim_hh(ini_string, 0, _CONFINI_WITH_EOL_), + _CONFINI_WITH_EOL_ ); } @@ -4228,26 +4345,28 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { for (idx = lshift = 0; ini_string[idx]; idx++) { - abcd = !(abcd & 10) && ini_string[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - nbacksl & 1 ? - (abcd & 63) | 32 - : - ((abcd & 223) | 128) ^ 16 - ) - : !(abcd & 17) && ini_string[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - nbacksl & 1 ? - (abcd & 63) | 32 - : - ((abcd & 223) | 128) ^ 8 - ) - : (abcd & 28) || !is_some_space(ini_string[idx], _LIBCONFINI_WITH_EOL_) ? - abcd & 31 - : abcd & 64 ? - (abcd & 223) | 128 + abcd = + + !(abcd & 10) && ini_string[idx] == _CONFINI_D_QUOTES_ ? + ( + nbacksl & 1 ? + (abcd & 63) | 32 + : + ((abcd & 223) | 128) ^ 16 + ) + : !(abcd & 17) && ini_string[idx] == _CONFINI_S_QUOTES_ ? + ( + nbacksl & 1 ? + (abcd & 63) | 32 : - (abcd & 95) | 64; + ((abcd & 223) | 128) ^ 8 + ) + : (abcd & 28) || !is_some_space(ini_string[idx], _CONFINI_WITH_EOL_) ? + abcd & 31 + : abcd & 64 ? + (abcd & 223) | 128 + : + (abcd & 95) | 64; if (abcd & 128) { @@ -4257,7 +4376,7 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { } - if (ini_string[idx] == _LIBCONFINI_BACKSLASH_) { + if (ini_string[idx] == _CONFINI_BACKSLASH_) { nbacksl++; @@ -4274,10 +4393,11 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { } - ini_string[idx - lshift] = abcd & 64 ? - _LIBCONFINI_COLLAPSED_ - : - ini_string[idx]; + ini_string[idx - lshift] = + abcd & 64 ? + _CONFINI_COLLAPSED_ + : + ini_string[idx]; } @@ -4285,10 +4405,11 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { for ( - idx -= (abcd & 64) && lshift < idx ? - ++lshift - : - lshift; + idx -= + (abcd & 64) && lshift < idx ? + ++lshift + : + lshift; ini_string[idx]; @@ -4296,32 +4417,33 @@ size_t ini_string_parse (char * const ini_string, const IniFormat format) { ); - return (abcd & 28) ^ 4 ? - idx - lshift - : - rtrim_h(ini_string, idx - lshift, _LIBCONFINI_WITH_EOL_); + return + (abcd & 28) ^ 4 ? + idx - lshift + : + rtrim_h(ini_string, idx - lshift, _CONFINI_WITH_EOL_); } - /** @utility{ini_array_get_length} **/ + /** @utility{ini_array_get_length} **/ /** - @brief Get the length of a stringified INI array in number of members - @param ini_string The stringified array (it can be `NULL`) - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @return The length of the INI array in number of members + @brief Get the length of a stringified INI array in number of members + @param ini_string The stringified array (it can be `NULL`) + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @return The length of the INI array in number of members Usually @p ini_string comes from an #IniDispatch (but any other string may be used as well). - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and - will contain only one member). + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and + will contain only one member). **/ size_t ini_array_get_length ( @@ -4336,10 +4458,9 @@ size_t ini_array_get_length ( } - if (_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (_CONFINI_IS_ESC_CHAR_(delimiter, format)) { /* We have no delimiters (array has only one member) */ - return 1; } @@ -4348,21 +4469,21 @@ size_t ini_array_get_length ( Mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Delimiter is not any space (const) - FLAG_8 Unescaped single quotes are odd right now - FLAG_16 Unescaped double quotes are odd right now - FLAG_32 We are in an odd sequence of backslashes - FLAG_64 This is a space - FLAG_128 This is a delimiter + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Delimiter is not any space (const) + FLAG_8 Unescaped single quotes are odd right now + FLAG_16 Unescaped double quotes are odd right now + FLAG_32 We are in an odd sequence of backslashes + FLAG_64 This is a space + FLAG_128 This is a delimiter */ - register uint_least8_t - abcd = (delimiter ? 64 : 68) | - (format.no_double_quotes << 1) | - format.no_single_quotes; + register uint_least8_t abcd = + (delimiter ? 64 : 68) | + (format.no_double_quotes << 1) | + format.no_single_quotes; size_t counter = 0; @@ -4370,23 +4491,25 @@ size_t ini_array_get_length ( /* Revision #1 */ - abcd = !(abcd & 28) && ini_string[idx] == delimiter ? - (abcd & 159) | 128 - : !(abcd & 24) && is_some_space(ini_string[idx], _LIBCONFINI_WITH_EOL_) ? - ( - (abcd & 68) ^ 4 ? - (abcd & 95) | 64 - : - (abcd & 223) | 192 - ) - : ini_string[idx] == _LIBCONFINI_BACKSLASH_ ? - (abcd & 63) ^ 32 - : !(abcd & 42) && ini_string[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - (abcd & 31) ^ 16 - : !(abcd & 49) && ini_string[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - (abcd & 31) ^ 8 + abcd = + + !(abcd & 28) && ini_string[idx] == delimiter ? + (abcd & 159) | 128 + : !(abcd & 24) && is_some_space(ini_string[idx], _CONFINI_WITH_EOL_) ? + ( + (abcd & 68) ^ 4 ? + (abcd & 95) | 64 : - abcd & 31; + (abcd & 223) | 192 + ) + : ini_string[idx] == _CONFINI_BACKSLASH_ ? + (abcd & 63) ^ 32 + : !(abcd & 42) && ini_string[idx] == _CONFINI_D_QUOTES_ ? + (abcd & 31) ^ 16 + : !(abcd & 49) && ini_string[idx] == _CONFINI_S_QUOTES_ ? + (abcd & 31) ^ 8 + : + abcd & 31; if (abcd & 128) { @@ -4397,30 +4520,31 @@ size_t ini_array_get_length ( } - return !counter || (~abcd & 68) ? - counter + 1 - : - counter; + return + !counter || (~abcd & 68) ? + counter + 1 + : + counter; } - /** @utility{ini_array_foreach} **/ + /** @utility{ini_array_foreach} **/ /** - @brief Call a custom function for each member of a stringified INI - array, without modifying the content of the buffer -- useful for - read-only (`const`) stringified arrays - @param ini_string The stringified array (it can be `NULL`) - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @param f_foreach The function that will be invoked for each array - member - @param user_data A custom argument, or `NULL` - @return Zero for success, otherwise an error code (see `enum` - #ConfiniInterruptNo) + @brief Call a custom function for each member of a stringified INI + array, without modifying the content of the buffer -- useful for + read-only (`const`) stringified arrays + @param ini_string The stringified array (it can be `NULL`) + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @param f_foreach The function that will be invoked for each array + member + @param user_data A custom argument, or `NULL` + @return Zero for success, otherwise an error code (see `enum` + #ConfiniInterruptNo) Usually @p ini_string comes from an #IniDispatch (but any other string may be used as well). @@ -4433,10 +4557,10 @@ size_t ini_array_get_length ( @p f_foreach returns a non-zero value the function #ini_array_foreach() will be interrupted. - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and - will contain only one member). + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and + will contain only one member). Possible return values are: #CONFINI_SUCCESS, #CONFINI_FEINTR. @@ -4461,21 +4585,21 @@ int ini_array_foreach ( Mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Delimiter is not any space (const) - FLAG_8 Unescaped single quotes are odd until now - FLAG_16 Unescaped double quotes are odd until now - FLAG_32 We are in an odd sequence of backslashes - FLAG_64 This is not a delimiter - FLAG_128 Stop the loop + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Delimiter is not any space (const) + FLAG_8 Unescaped single quotes are odd until now + FLAG_16 Unescaped double quotes are odd until now + FLAG_32 We are in an odd sequence of backslashes + FLAG_64 This is not a delimiter + FLAG_128 Stop the loop */ register size_t idx; - size_t offs = ltrim_s(ini_string, 0, _LIBCONFINI_WITH_EOL_); + size_t offs = ltrim_s(ini_string, 0, _CONFINI_WITH_EOL_); - if (_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (_CONFINI_IS_ESC_CHAR_(delimiter, format)) { /* We have no delimiters (array has only one member) */ @@ -4486,7 +4610,7 @@ int ini_array_foreach ( return f_foreach( ini_string, offs, - rtrim_s(ini_string + offs, idx - offs - 1, _LIBCONFINI_WITH_EOL_), + rtrim_s(ini_string + offs, idx - offs - 1, _CONFINI_WITH_EOL_), 0, format, user_data @@ -4494,10 +4618,10 @@ int ini_array_foreach ( } - register uint_least8_t - abcd = (delimiter ? 4 : 0) | - (format.no_double_quotes << 1) | - format.no_single_quotes; + register uint_least8_t abcd = + (delimiter ? 4 : 0) | + (format.no_double_quotes << 1) | + format.no_single_quotes; size_t memb_num = 0; @@ -4505,23 +4629,25 @@ int ini_array_foreach ( do { - abcd = ( - delimiter ? - ini_string[idx] == delimiter - : - is_some_space(ini_string[idx], _LIBCONFINI_WITH_EOL_) - ) ? - abcd & 159 - : ini_string[idx] == _LIBCONFINI_BACKSLASH_ ? - (abcd | 64) ^ 32 - : !(abcd & 42) && ini_string[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ((abcd & 223) | 64) ^ 16 - : !(abcd & 49) && ini_string[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ((abcd & 223) | 64) ^ 8 - : ini_string[idx] ? - (abcd & 223) | 64 - : - 128; + abcd = + + ( + delimiter ? + ini_string[idx] == delimiter + : + is_some_space(ini_string[idx], _CONFINI_WITH_EOL_) + ) ? + abcd & 159 + : ini_string[idx] == _CONFINI_BACKSLASH_ ? + (abcd | 64) ^ 32 + : !(abcd & 42) && ini_string[idx] == _CONFINI_D_QUOTES_ ? + ((abcd & 223) | 64) ^ 16 + : !(abcd & 49) && ini_string[idx] == _CONFINI_S_QUOTES_ ? + ((abcd & 223) | 64) ^ 8 + : ini_string[idx] ? + (abcd & 223) | 64 + : + 128; if (!(abcd & 88)) { @@ -4530,7 +4656,7 @@ int ini_array_foreach ( f_foreach( ini_string, offs, - rtrim_s(ini_string + offs, idx - offs, _LIBCONFINI_WITH_EOL_), + rtrim_s(ini_string + offs, idx - offs, _CONFINI_WITH_EOL_), memb_num++, format, user_data @@ -4541,10 +4667,11 @@ int ini_array_foreach ( } - offs = abcd & 128 ? - idx + 1 - : - ltrim_s(ini_string, idx + 1, _LIBCONFINI_WITH_EOL_); + offs = + abcd & 128 ? + idx + 1 + : + ltrim_s(ini_string, idx + 1, _CONFINI_WITH_EOL_); } @@ -4561,28 +4688,28 @@ int ini_array_foreach ( } - /** @utility{ini_array_shift} **/ + /** @utility{ini_array_shift} **/ /** - @brief Shift the location pointed by @p ini_strptr to the next member - of the INI array (without modifying the content of the buffer), - or to `NULL` if the INI array has no more members -- useful for - read-only (`const`) stringified arrays - @param ini_strptr The memory location of the stringified array -- - it cannot be `NULL`, but it can point to `NULL` - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @return The length of the array member that has been left behind + @brief Shift the location pointed by @p ini_strptr to the next member + of the INI array (without modifying the content of the buffer), + or to `NULL` if the INI array has no more members -- useful for + read-only (`const`) stringified arrays + @param ini_strptr The memory location of the stringified array -- + it cannot be `NULL`, but it can point to `NULL` + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @return The length of the array member that has been left behind Usually @p ini_strptr comes from an #IniDispatch (but any other string may be used as well). - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and - will contain only one member). + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and + will contain only one member). @include topics/ini_array_shift.c @@ -4595,21 +4722,21 @@ size_t ini_array_shift ( size_t toklen = 0; - if (*ini_strptr && !_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (*ini_strptr && !_CONFINI_IS_ESC_CHAR_(delimiter, format)) { if (!delimiter) { - toklen = ltrim_s(*ini_strptr, 0, _LIBCONFINI_WITH_EOL_); + toklen = ltrim_s(*ini_strptr, 0, _CONFINI_WITH_EOL_); } toklen += get_metachar_pos(*ini_strptr + toklen, delimiter, format); *ini_strptr += toklen; - toklen = rtrim_s(*ini_strptr - toklen, toklen, _LIBCONFINI_WITH_EOL_); + toklen = rtrim_s(*ini_strptr - toklen, toklen, _CONFINI_WITH_EOL_); if (**ini_strptr) { - *ini_strptr += ltrim_s(*ini_strptr, 1, _LIBCONFINI_WITH_EOL_); + *ini_strptr += ltrim_s(*ini_strptr, 1, _CONFINI_WITH_EOL_); if (delimiter || **ini_strptr) { @@ -4627,22 +4754,22 @@ size_t ini_array_shift ( } - /** @utility{ini_array_collapse} **/ + /** @utility{ini_array_collapse} **/ /** - @brief Compress the distribution of the data in a stringified INI array - by removing all the white spaces that surround its delimiters, - empty quotes, collapsable spaces, etc - @param ini_string The stringified array - @param delimiter The delimiter between the array members -- - if zero (`INI_ANY_SPACE`) any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @return The new length of the stringified array - - Out of quotes similar to ECMAScript - `ini_string.replace(new RegExp("^\\s+|\\s*(?:(" + delimiter + ")\\s*|($))", "g"), "$1$2")`. - If #INI_ANY_SPACE (`0`) is used as delimiter, one or more different spaces + @brief Compress the distribution of the data in a stringified INI array + by removing all the white spaces that surround its delimiters, + empty quotes, collapsable spaces, etc + @param ini_string The stringified array + @param delimiter The delimiter between the array members -- + if zero (`INI_ANY_SPACE`) any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @return The new length of the stringified array + + Out of quotes similar to ECMAScript `ini_string.replace(new + RegExp("^\\s+|\\s*(?:(" + delimiter + ")\\s*|($))", "g"), "$1$2")`. If + #INI_ANY_SPACE (`0`) is used as delimiter, one or more different spaces (`/[\t \v\f\n\r]+/`) will be always collapsed to one space, independently of what the format says. @@ -4670,19 +4797,19 @@ size_t ini_array_shift ( third     etc.   ` - After: `first second third etc.` - @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is - no-op and will only return the value of #INI_GLOBAL_IMPLICIT_V_LEN minus - the offset of @p ini_string within #INI_GLOBAL_IMPLICIT_VALUE. + @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is + no-op and will only return the value of #INI_GLOBAL_IMPLICIT_V_LEN minus + the offset of @p ini_string within #INI_GLOBAL_IMPLICIT_VALUE. - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and - will contain only one member). + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and + will contain only one member). @include topics/ini_array_collapse.c - @note The actual space occupied by the array might get reduced further after - each member is parsed by #ini_string_parse(). + @note The actual space occupied by the array might get reduced further after + each member is parsed by #ini_string_parse(). **/ size_t ini_array_collapse ( @@ -4697,7 +4824,7 @@ size_t ini_array_collapse ( } - if (_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (_CONFINI_IS_ESC_CHAR_(delimiter, format)) { /* We have no delimiters (array has only one member) */ @@ -4709,11 +4836,14 @@ size_t ini_array_collapse ( case 0: return collapse_everything(ini_string, format); case 1: return collapse_empty_quotes(ini_string, format); case 2: return collapse_spaces(ini_string, format); - case 3: return rtrim_h( - ini_string, - ltrim_hh(ini_string, 0, _LIBCONFINI_WITH_EOL_), - _LIBCONFINI_WITH_EOL_ - ); + + case 3: + + return rtrim_h( + ini_string, + ltrim_hh(ini_string, 0, _CONFINI_WITH_EOL_), + _CONFINI_WITH_EOL_ + ); } @@ -4723,109 +4853,111 @@ size_t ini_array_collapse ( Mask `abcd` (16 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Do not collapse spaces within members (const) - FLAG_8 Preserve empty quotes (const) - FLAG_16 Any space is delimiter (const) - FLAG_32 Unescaped single quotes are odd right now - FLAG_64 Unescaped double quotes are odd right now - FLAG_128 We are in an odd sequence of backslashes - FLAG_256 This is *not* a delimiter out of quotes - FLAG_512 This is *not* a space out of quotes - FLAG_1024 These are some quotes - FLAG_2048 These are some quotes or among the last spaces are some empty - quotes - FLAG_4096 Save current `idx_d` in `fallback` - FLAG_8192 Restore `idx_d` from `fallback` before writing - FLAG_16384 Decrease `idx_d` before writing - FLAG_32768 Keep increasing `idx_d` after writing + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Do not collapse spaces within members (const) + FLAG_8 Preserve empty quotes (const) + FLAG_16 Any space is delimiter (const) + FLAG_32 Unescaped single quotes are odd right now + FLAG_64 Unescaped double quotes are odd right now + FLAG_128 We are in an odd sequence of backslashes + FLAG_256 This is *not* a delimiter out of quotes + FLAG_512 This is *not* a space out of quotes + FLAG_1024 These are some quotes + FLAG_2048 These are some quotes or among the last spaces are some empty + quotes + FLAG_4096 Save current `idx_d` in `fallback` + FLAG_8192 Restore `idx_d` from `fallback` before writing + FLAG_16384 Decrease `idx_d` before writing + FLAG_32768 Keep increasing `idx_d` after writing */ size_t idx_s = 0, idx_d = 0, fallback = 0; - register uint_least16_t - abcd = (delimiter ? 0 : 16) | - (format.preserve_empty_quotes << 3) | - (format.do_not_collapse_values << 2) | - (format.no_double_quotes << 1) | - format.no_single_quotes; + register uint_least16_t abcd = + (delimiter ? 0 : 16) | + (format.preserve_empty_quotes << 3) | + (format.do_not_collapse_values << 2) | + (format.no_double_quotes << 1) | + format.no_single_quotes; for (; ini_string[idx_s]; idx_s++) { /* Revision #1 */ - abcd = !(abcd & 112) && ini_string[idx_s] == delimiter ? - ( - (abcd & 536) && ((abcd & 1560) ^ 8) && - ((abcd & 1560) ^ 1544) && ((abcd & 1304) ^ 1032) ? - (abcd & 33407) | 33280 - : - (abcd & 41599) | 41472 - ) - : !(abcd & 96) && is_some_space(ini_string[idx_s], _LIBCONFINI_WITH_EOL_) ? - ( - !((abcd & 1816) ^ 1800) ? - (abcd & 43391) | 40960 - : !(~abcd & 1560) ? - (abcd & 41087) | 40960 - : !((abcd & 536) ^ 528) || !((abcd & 1560) ^ 536) || - !((abcd & 1560) ^ 1048) ? - (abcd & 32895) | 32768 - : !(abcd & 540) || !((abcd & 1564) ^ 8) || - !((abcd & 536) ^ 16) || !((abcd & 1560) ^ 24) ? - abcd & 2431 - : ((abcd & 540) ^ 4) && ((abcd & 796) ^ 12) && - ((abcd & 1564) ^ 12) && ((abcd & 1308) ^ 1032) ? - (abcd & 39295) | 36864 - : - (abcd & 35199) | 32768 - ) - : !(abcd & 193) && ini_string[idx_s] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - !((abcd & 3896) ^ 8) ? - (abcd & 44927) | 44064 - : !((abcd & 3896) ^ 2056) ? - (abcd & 36735) | 36128 - : !((abcd & 1056) ^ 32) ? - (abcd & 33631) | 33536 - : !(abcd & 40) || !(~abcd & 1064) ? - ((abcd & 36735) | 35840) ^ 32 - : ((abcd & 1064) ^ 1032) && ((abcd & 1064) ^ 1056) ? - (abcd & 40831) | 39968 - : - ((abcd & 20351) | 19456) ^ 32 - ) - : !(abcd & 162) && ini_string[idx_s] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - !((abcd & 3928) ^ 8) ? - (abcd & 44927) | 44096 - : !((abcd & 3928) ^ 2056) ? - (abcd & 36735) | 36160 - : !((abcd & 1088) ^ 64) ? - (abcd & 33599) | 33536 - : !(abcd & 72) || !(~abcd & 1096) ? - ((abcd & 36735) | 35840) ^ 64 - : ((abcd & 1096) ^ 1088) && ((abcd & 1096) ^ 1032) ? - (abcd & 40831) | 40000 - : - ((abcd & 20351) | 19456) ^ 64 - ) - : ini_string[idx_s] == _LIBCONFINI_BACKSLASH_ ? - ( - (abcd & 888) && ((abcd & 1144) ^ 1032) && - ((abcd & 1144) ^ 1048) && ((abcd & 2936) ^ 8) ? - ((abcd & 33791) | 33536) ^ 128 - : - ((abcd & 41983) | 41728) ^ 128 - ) - : (abcd & 888) && ((abcd & 1144) ^ 1032) && + abcd = + + !(abcd & 112) && ini_string[idx_s] == delimiter ? + ( + (abcd & 536) && ((abcd & 1560) ^ 8) && + ((abcd & 1560) ^ 1544) && ((abcd & 1304) ^ 1032) ? + (abcd & 33407) | 33280 + : + (abcd & 41599) | 41472 + ) + : !(abcd & 96) && is_some_space(ini_string[idx_s], _CONFINI_WITH_EOL_) ? + ( + !((abcd & 1816) ^ 1800) ? + (abcd & 43391) | 40960 + : !(~abcd & 1560) ? + (abcd & 41087) | 40960 + : !((abcd & 536) ^ 528) || !((abcd & 1560) ^ 536) || + !((abcd & 1560) ^ 1048) ? + (abcd & 32895) | 32768 + : !(abcd & 540) || !((abcd & 1564) ^ 8) || + !((abcd & 536) ^ 16) || !((abcd & 1560) ^ 24) ? + abcd & 2431 + : ((abcd & 540) ^ 4) && ((abcd & 796) ^ 12) && + ((abcd & 1564) ^ 12) && ((abcd & 1308) ^ 1032) ? + (abcd & 39295) | 36864 + : + (abcd & 35199) | 32768 + ) + : !(abcd & 193) && ini_string[idx_s] == _CONFINI_S_QUOTES_ ? + ( + !((abcd & 3896) ^ 8) ? + (abcd & 44927) | 44064 + : !((abcd & 3896) ^ 2056) ? + (abcd & 36735) | 36128 + : !((abcd & 1056) ^ 32) ? + (abcd & 33631) | 33536 + : !(abcd & 40) || !(~abcd & 1064) ? + ((abcd & 36735) | 35840) ^ 32 + : ((abcd & 1064) ^ 1032) && ((abcd & 1064) ^ 1056) ? + (abcd & 40831) | 39968 + : + ((abcd & 20351) | 19456) ^ 32 + ) + : !(abcd & 162) && ini_string[idx_s] == _CONFINI_D_QUOTES_ ? + ( + !((abcd & 3928) ^ 8) ? + (abcd & 44927) | 44096 + : !((abcd & 3928) ^ 2056) ? + (abcd & 36735) | 36160 + : !((abcd & 1088) ^ 64) ? + (abcd & 33599) | 33536 + : !(abcd & 72) || !(~abcd & 1096) ? + ((abcd & 36735) | 35840) ^ 64 + : ((abcd & 1096) ^ 1088) && ((abcd & 1096) ^ 1032) ? + (abcd & 40831) | 40000 + : + ((abcd & 20351) | 19456) ^ 64 + ) + : ini_string[idx_s] == _CONFINI_BACKSLASH_ ? + ( + (abcd & 888) && ((abcd & 1144) ^ 1032) && ((abcd & 1144) ^ 1048) && ((abcd & 2936) ^ 8) ? - (abcd & 33663) | 33536 + ((abcd & 33791) | 33536) ^ 128 : - (abcd & 41855) | 41728; + ((abcd & 41983) | 41728) ^ 128 + ) + : (abcd & 888) && ((abcd & 1144) ^ 1032) && + ((abcd & 1144) ^ 1048) && ((abcd & 2936) ^ 8) ? + (abcd & 33663) | 33536 + : + (abcd & 41855) | 41728; ini_string[ @@ -4837,10 +4969,11 @@ size_t ini_array_collapse ( (fallback = idx_d) : idx_d - ] = (abcd & 1636) && ((abcd & 1392) ^ 16) ? - ini_string[idx_s] - : - _LIBCONFINI_COLLAPSED_; + ] = + (abcd & 1636) && ((abcd & 1392) ^ 16) ? + ini_string[idx_s] + : + _CONFINI_COLLAPSED_; if (abcd & 32768) { @@ -4853,18 +4986,19 @@ size_t ini_array_collapse ( for ( - idx_s = ((abcd & 16) && !idx_d) || (!(~abcd & 1040) && idx_d < 4) ? - (idx_d = 0) - : !(abcd & 536) || !(~abcd & 1544) || !((abcd & 1560) ^ 8) || - !((abcd & 1304) ^ 1032) ? - (idx_d = fallback) - : !((abcd & 1624) ^ 1104) || !((abcd & 1592) ^ 1072) ? - (idx_d -= 2) - : ((abcd & 1552) ^ 16) && ((abcd & 632) ^ 16) && - ((abcd & 1624) ^ 1616) && ((abcd & 1592) ^ 1584) ? - idx_d - : - --idx_d; + idx_s = + ((abcd & 16) && !idx_d) || (!(~abcd & 1040) && idx_d < 4) ? + (idx_d = 0) + : !(abcd & 536) || !(~abcd & 1544) || !((abcd & 1560) ^ 8) || + !((abcd & 1304) ^ 1032) ? + (idx_d = fallback) + : !((abcd & 1624) ^ 1104) || !((abcd & 1592) ^ 1072) ? + (idx_d -= 2) + : ((abcd & 1552) ^ 16) && ((abcd & 632) ^ 16) && + ((abcd & 1624) ^ 1616) && ((abcd & 1592) ^ 1584) ? + idx_d + : + --idx_d; ini_string[idx_s]; @@ -4877,18 +5011,18 @@ size_t ini_array_collapse ( } - /** @utility{ini_array_break} **/ + /** @utility{ini_array_break} **/ /** - @brief Replace the first delimiter found (together with the spaces that - surround it) with `\0` - @param ini_string The stringified array (it can be `NULL`) - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @return A pointer to the remaining INI array or `NULL` if the remaining - array is empty + @brief Replace the first delimiter found (together with the spaces that + surround it) with `\0` + @param ini_string The stringified array (it can be `NULL`) + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @return A pointer to the remaining INI array or `NULL` if the remaining + array is empty Usually @p ini_string comes from an #IniDispatch (but any other string may be used as well). @@ -4896,12 +5030,12 @@ size_t ini_array_collapse ( Similarly to `strtok_r()` this function can be used only once for a given string. - @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is - no-op and will return `NULL`. + @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is + no-op and will return `NULL`. - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and will contain only one member). @include topics/ini_array_break.c @@ -4917,7 +5051,7 @@ char * ini_array_break ( char * remnant; - if (_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (_CONFINI_IS_ESC_CHAR_(delimiter, format)) { /* We have no delimiters (array has only one member) */ @@ -4925,7 +5059,7 @@ char * ini_array_break ( while (*remnant++); - rtrim_h(ini_string, remnant - ini_string - 1, _LIBCONFINI_WITH_EOL_); + rtrim_h(ini_string, remnant - ini_string - 1, _CONFINI_WITH_EOL_); } else { @@ -4934,8 +5068,8 @@ char * ini_array_break ( if (*remnant) { *remnant = '\0'; - rtrim_h(ini_string, remnant - ini_string, _LIBCONFINI_WITH_EOL_); - remnant += ltrim_h(remnant, 1, _LIBCONFINI_WITH_EOL_); + rtrim_h(ini_string, remnant - ini_string, _CONFINI_WITH_EOL_); + remnant += ltrim_h(remnant, 1, _CONFINI_WITH_EOL_); if (delimiter || *remnant) { @@ -4954,20 +5088,20 @@ char * ini_array_break ( } - /** @utility{ini_array_release} **/ + /** @utility{ini_array_release} **/ /** - @brief Replace the first delimiter found (together with the spaces that - surround it) with `\0`, then shifts the location pointed by - @p ini_strptr to the next member of the INI array, or to `NULL` - if the INI array has no more members - @param ini_strptr The memory location of the stringified array -- - it cannot be `NULL`, but it can point to `NULL` - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @return The array member that has been released + @brief Replace the first delimiter found (together with the spaces that + surround it) with `\0`, then shifts the location pointed by + @p ini_strptr to the next member of the INI array, or to `NULL` + if the INI array has no more members + @param ini_strptr The memory location of the stringified array -- + it cannot be `NULL`, but it can point to `NULL` + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @return The array member that has been released Usually @p ini_strptr comes from an #IniDispatch (but any other string may be used as well). @@ -4975,13 +5109,13 @@ char * ini_array_break ( Similarly to `strtok_r()` this function can be used only once for a given string. - @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is - no-op and will set @p ini_strptr to `NULL`. + @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE this function is + no-op and will set @p ini_strptr to `NULL`. - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and - will contain only one member). + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and + will contain only one member). @include topics/ini_array_release.c @@ -4997,7 +5131,7 @@ char * ini_array_release ( if ( token && !INI_IS_IMPLICIT_SUBSTR(token) && - !_LIBCONFINI_IS_ESC_CHAR_(delimiter, format) + !_CONFINI_IS_ESC_CHAR_(delimiter, format) ) { *ini_strptr += get_metachar_pos(*ini_strptr, delimiter, format); @@ -5005,8 +5139,8 @@ char * ini_array_release ( if (**ini_strptr) { **ini_strptr = '\0'; - rtrim_h(token, *ini_strptr - token, _LIBCONFINI_WITH_EOL_); - *ini_strptr += ltrim_h(*ini_strptr, 1, _LIBCONFINI_WITH_EOL_); + rtrim_h(token, *ini_strptr - token, _CONFINI_WITH_EOL_); + *ini_strptr += ltrim_h(*ini_strptr, 1, _CONFINI_WITH_EOL_); if (delimiter || **ini_strptr) { @@ -5024,21 +5158,21 @@ char * ini_array_release ( } - /** @utility{ini_array_split} **/ + /** @utility{ini_array_split} **/ /** - @brief Split a stringified INI array into NUL-separated members and - call a custom function for each member - @param ini_string The stringified array (it cannot be `NULL`) - @param delimiter The delimiter between the array members -- if - zero (see #INI_ANY_SPACE), any space is - delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) - @param format The format of the INI file - @param f_foreach The function that will be invoked for each array - member - @param user_data A custom argument, or `NULL` - @return Zero for success, otherwise an error code (see `enum` - #ConfiniInterruptNo) + @brief Split a stringified INI array into NUL-separated members and + call a custom function for each member + @param ini_string The stringified array (it cannot be `NULL`) + @param delimiter The delimiter between the array members -- if + zero (see #INI_ANY_SPACE), any space is + delimiter (`/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`) + @param format The format of the INI file + @param f_foreach The function that will be invoked for each array + member + @param user_data A custom argument, or `NULL` + @return Zero for success, otherwise an error code (see `enum` + #ConfiniInterruptNo) Usually @p ini_string comes from an #IniDispatch (but any other string may be used as well). @@ -5053,13 +5187,13 @@ char * ini_array_release ( Similarly to `strtok_r()` this function can be used only once for a given string. - @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE or is `NULL` this - function is no-op and will return an error code. + @note If @p ini_string comes from #INI_GLOBAL_IMPLICIT_VALUE or is `NULL` this + function is no-op and will return an error code. - @note If @p delimiter matches a metacharacter within the format given (`'\\'`, - `'\''` or `'\"'`), its role as metacharacter will have higher priority - than its role as delimiter (i.e., the array will have no delimiters and - will contain only one member). + @note If @p delimiter matches a metacharacter within the format given (`'\\'`, + `'\''` or `'\"'`), its role as metacharacter will have higher priority + than its role as delimiter (i.e., the array will have no delimiters and + will contain only one member). Possible return values are: #CONFINI_SUCCESS, #CONFINI_EROADDR, #CONFINI_FEINTR. @@ -5084,21 +5218,21 @@ int ini_array_split ( Mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Delimiter is not any space (const) - FLAG_8 Unescaped single quotes are odd until now - FLAG_16 Unescaped double quotes are odd until now - FLAG_32 We are in an odd sequence of backslashes - FLAG_64 This is not a delimiter - FLAG_128 Stop the loop + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Delimiter is not any space (const) + FLAG_8 Unescaped single quotes are odd until now + FLAG_16 Unescaped double quotes are odd until now + FLAG_32 We are in an odd sequence of backslashes + FLAG_64 This is not a delimiter + FLAG_128 Stop the loop */ register size_t idx; - size_t offs = ltrim_h(ini_string, 0, _LIBCONFINI_WITH_EOL_); + size_t offs = ltrim_h(ini_string, 0, _CONFINI_WITH_EOL_); - if (_LIBCONFINI_IS_ESC_CHAR_(delimiter, format)) { + if (_CONFINI_IS_ESC_CHAR_(delimiter, format)) { /* We have no delimiters (array has only one member) */ @@ -5108,7 +5242,7 @@ int ini_array_split ( return f_foreach( ini_string + offs, - rtrim_h(ini_string + offs, idx - offs - 1, _LIBCONFINI_WITH_EOL_), + rtrim_h(ini_string + offs, idx - offs - 1, _CONFINI_WITH_EOL_), 0, format, user_data @@ -5117,34 +5251,36 @@ int ini_array_split ( } register uint_least8_t - abcd = (delimiter ? 4 : 0) | - (format.no_double_quotes << 1) | - format.no_single_quotes; + abcd = + (delimiter ? 4 : 0) | + (format.no_double_quotes << 1) | + format.no_single_quotes; size_t memb_num = 0; idx = offs; - do { - abcd = ( - delimiter ? - ini_string[idx] == delimiter - : - is_some_space(ini_string[idx], _LIBCONFINI_WITH_EOL_) - ) ? - abcd & 159 - : ini_string[idx] == _LIBCONFINI_BACKSLASH_ ? - (abcd | 64) ^ 32 - : !(abcd & 42) && ini_string[idx] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ((abcd & 223) | 64) ^ 16 - : !(abcd & 49) && ini_string[idx] == _LIBCONFINI_SINGLE_QUOTES_ ? - ((abcd & 223) | 64) ^ 8 - : ini_string[idx] ? - (abcd & 223) | 64 - : - 128; + abcd = + + ( + delimiter ? + ini_string[idx] == delimiter + : + is_some_space(ini_string[idx], _CONFINI_WITH_EOL_) + ) ? + abcd & 159 + : ini_string[idx] == _CONFINI_BACKSLASH_ ? + (abcd | 64) ^ 32 + : !(abcd & 42) && ini_string[idx] == _CONFINI_D_QUOTES_ ? + ((abcd & 223) | 64) ^ 16 + : !(abcd & 49) && ini_string[idx] == _CONFINI_S_QUOTES_ ? + ((abcd & 223) | 64) ^ 8 + : ini_string[idx] ? + (abcd & 223) | 64 + : + 128; if (!(abcd & 88)) { @@ -5154,7 +5290,7 @@ int ini_array_split ( if ( f_foreach( ini_string + offs, - rtrim_h(ini_string + offs, idx - offs, _LIBCONFINI_WITH_EOL_), + rtrim_h(ini_string + offs, idx - offs, _CONFINI_WITH_EOL_), memb_num++, format, user_data @@ -5165,10 +5301,11 @@ int ini_array_split ( } - offs = abcd & 128 ? - idx + 1 - : - ltrim_h(ini_string, idx + 1, _LIBCONFINI_WITH_EOL_); + offs = + abcd & 128 ? + idx + 1 + : + ltrim_h(ini_string, idx + 1, _CONFINI_WITH_EOL_); } @@ -5187,45 +5324,47 @@ int ini_array_split ( /** - @brief Set the value of the global variable - #INI_GLOBAL_LOWERCASE_MODE - @deprecated Deprecated since version 1.15.0 (it will be removed in version - 2.0.0) - @param lowercase The new value - @return Nothing + @brief Set the value of the global variable + #INI_GLOBAL_LOWERCASE_MODE + @deprecated Deprecated since version 1.15.0 (it will be removed in version + 2.0.0) + @param lowercase The new value + @return Nothing If @p lowercase is `true`, key and section names in case-insensitive INI formats will be dispatched lowercase, verbatim otherwise (default value: `true`). - @warning This function changes the value of one or more global variables. In - order to be thread-safe this function should be used only once at - beginning of execution, or otherwise a mutex logic must be - introduced. + @warning This function changes the value of one or more global variables. In + order to be thread-safe this function should be used only once at + beginning of execution, or otherwise a mutex logic must be + introduced. **/ -void ini_global_set_lowercase_mode (const bool lowercase) { +void ini_global_set_lowercase_mode ( + const bool lowercase +) { INI_GLOBAL_LOWERCASE_MODE = lowercase; } - /** @utility{ini_global_set_implicit_value} **/ + /** @utility{ini_global_set_implicit_value} **/ /** - @brief Set the value to be to be assigned to implicit keys - @param implicit_value The string to be used as implicit value - (usually `"YES"`, `"TRUE"`, or `"ON"`, or - any other string; it can be `NULL`) - @param implicit_v_len The length of @p implicit_value (without - counting the NUL terminator; use `0` for - both an empty string and `NULL`) - @return Nothing + @brief Set the value to be to be assigned to implicit keys + @param implicit_value The string to be used as implicit value + (usually `"YES"`, `"TRUE"`, or `"ON"`, or + any other string; it can be `NULL`) + @param implicit_v_len The length of @p implicit_value (without + counting the NUL terminator; use `0` for + both an empty string and `NULL`) + @return Nothing - @warning This function changes the value of one or more global variables. In - order to be thread-safe this function should be used only once at - beginning of execution, or otherwise a mutex logic must be - introduced. + @warning This function changes the value of one or more global variables. In + order to be thread-safe this function should be used only once at + beginning of execution, or otherwise a mutex logic must be + introduced. @include topics/ini_global_set_implicit_value.c @@ -5241,15 +5380,17 @@ void ini_global_set_implicit_value ( } - /** @utility{ini_fton} **/ + /** @utility{ini_fton} **/ /** - @brief Calculate the #IniFormatNum of an #IniFormat - @param source The #IniFormat to compute - @return The unique unsigned integer that identifies the format given + @brief Calculate the #IniFormatNum of an #IniFormat + @param source The #IniFormat to compute + @return The unique unsigned integer that identifies the format given **/ -IniFormatNum ini_fton (const IniFormat source) { +IniFormatNum ini_fton ( + const IniFormat source +) { #define __INIFORMAT_ID__(NAME, OFFSET, SIZE, DEFVAL) (source.NAME << OFFSET) | @@ -5260,17 +5401,19 @@ IniFormatNum ini_fton (const IniFormat source) { } - /** @utility{ini_ntof} **/ + /** @utility{ini_ntof} **/ /** - @brief Construct a new #IniFormat according to an #IniFormatNum - @param format_num The #IniFormatNum to parse - @return The new #IniFormat constructed + @brief Construct a new #IniFormat according to an #IniFormatNum + @param format_num The #IniFormatNum to parse + @return The new #IniFormat constructed - @note If @p format_num `>` `16777215` it will be truncated to 24 bits. + @note If @p format_num `>` `16777215` it will be truncated to 24 bits. **/ -IniFormat ini_ntof (const IniFormatNum format_num) { +IniFormat ini_ntof ( + const IniFormatNum format_num +) { #define __MAX_1_BITS__ 1 #define __MAX_2_BITS__ 3 @@ -5298,21 +5441,24 @@ IniFormat ini_ntof (const IniFormatNum format_num) { } - /** @utility{ini_get_bool} **/ + /** @utility{ini_get_bool} **/ /** - @brief Check whether a simple string matches one of the booleans listed - in the private constant #INI_BOOLEANS (case-insensitive) - @param simple_string A string to check (it can be `NULL`) - @param when_fail A value that is returned if no matching boolean - is found - @return The matching boolean (`0` or `1`) or @p when_fail if - @p simple_string does not contain a valid INI boolean + @brief Check whether a simple string matches one of the booleans listed + in the private constant #INI_BOOLEANS (case-insensitive) + @param simple_string A string to check (it can be `NULL`) + @param when_fail The value that is returned if no matching + boolean is found + @return The matching boolean (`0` or `1`) or @p when_fail if + @p simple_string does not contain a valid INI boolean @include miscellanea/typed_ini.c **/ -int ini_get_bool (const char * const simple_string, const int when_fail) { +int ini_get_bool ( + const char * const simple_string, + const int when_fail +) { if (!simple_string) { @@ -5320,10 +5466,10 @@ int ini_get_bool (const char * const simple_string, const int when_fail) { } - register _LIBCONFINI_CHARBOOL_ bool_idx; + register _CONFINI_CHARBOOL_ bool_idx; register size_t pair_idx, chr_idx; - for (pair_idx = 0; pair_idx < _LIBCONFINI_BOOLLEN_; pair_idx++) { + for (pair_idx = 0; pair_idx < _CONFINI_BOOLLEN_; pair_idx++) { bool_idx = 0; @@ -5332,7 +5478,7 @@ int ini_get_bool (const char * const simple_string, const int when_fail) { chr_idx = 0; while ( - _LIBCONFINI_CHR_CASEFOLD_(simple_string[chr_idx]) == + _CONFINI_CHR_CASEFOLD_(simple_string[chr_idx]) == INI_BOOLEANS[pair_idx][bool_idx][chr_idx] ) { @@ -5355,17 +5501,17 @@ int ini_get_bool (const char * const simple_string, const int when_fail) { } - /** @utility{ini_get_bool_i} **/ + /** @utility{ini_get_bool_i} **/ /** - @brief Check whether an INI string matches one of the booleans listed - in the private constant #INI_BOOLEANS (case-insensitive) - @param ini_string A string to check (it can be `NULL`) - @param when_fail A value that is returned if no matching boolean - is found - @param format The format of the INI file - @return The matching boolean (`0` or `1`) or @p when_fail if - @p ini_string does not contain a valid INI boolean + @brief Check whether an INI string matches one of the booleans listed + in the private constant #INI_BOOLEANS (case-insensitive) + @param ini_string A string to check (it can be `NULL`) + @param when_fail The value that is returned if no matching + boolean is found + @param format The format of the INI file + @return The matching boolean (`0` or `1`) or @p when_fail if + @p ini_string does not contain a valid INI boolean Usually @p ini_string comes from an #IniDispatch (but any other string may be used as well). @@ -5396,30 +5542,30 @@ int ini_get_bool_i ( Mask `abcd` (8 bits used): - FLAG_1 Single quotes are not metacharacters (const) - FLAG_2 Double quotes are not metacharacters (const) - FLAG_4 Format supports escape sequences (const) - FLAG_8 Unescaped single quotes are odd right now - FLAG_16 Unescaped double quotes are odd right now - FLAG_32 This is an escaped single/double quote in a format that supports - single/double quotes - FLAG_64 This is a space - FLAG_128 Skip this character + FLAG_1 Single quotes are not metacharacters (const) + FLAG_2 Double quotes are not metacharacters (const) + FLAG_4 Format supports escape sequences (const) + FLAG_8 Unescaped single quotes are odd right now + FLAG_16 Unescaped double quotes are odd right now + FLAG_32 This is an escaped single/double quote in a format that supports + single/double quotes + FLAG_64 This is a space + FLAG_128 Skip this character */ - register uint_least8_t - abcd = INIFORMAT_HAS_NO_ESC(format) ? - 67 - : - 68 | - (format.no_double_quotes << 1) | - format.no_single_quotes; + register uint_least8_t abcd = + INIFORMAT_HAS_NO_ESC(format) ? + 67 + : + 68 | + (format.no_double_quotes << 1) | + format.no_single_quotes; - register _LIBCONFINI_CHARBOOL_ bool_idx; + register _CONFINI_CHARBOOL_ bool_idx; size_t pair_idx, chr_idx_s, nbacksl; - for (pair_idx = 0; pair_idx < _LIBCONFINI_BOOLLEN_; pair_idx++) { + for (pair_idx = 0; pair_idx < _CONFINI_BOOLLEN_; pair_idx++) { bool_idx = 0; @@ -5434,11 +5580,11 @@ int ini_get_bool_i ( do { - if ((abcd & 4) && ini_string[chr_idx_i] == _LIBCONFINI_BACKSLASH_) { + if ((abcd & 4) && ini_string[chr_idx_i] == _CONFINI_BACKSLASH_) { for ( abcd &= 63, nbacksl++; - ini_string[++chr_idx_i] == _LIBCONFINI_BACKSLASH_; + ini_string[++chr_idx_i] == _CONFINI_BACKSLASH_; nbacksl++ ); @@ -5446,26 +5592,31 @@ int ini_get_bool_i ( /* Keep this algorithm identical to #ini_string_match_si() */ - abcd = !(abcd & 10) && ini_string[chr_idx_i] == _LIBCONFINI_DOUBLE_QUOTES_ ? - ( - nbacksl & 1 ? - (abcd & 63) | 32 - : - ((abcd & 223) | 128) ^ 16 - ) - : !(abcd & 17) && ini_string[chr_idx_i] == _LIBCONFINI_SINGLE_QUOTES_ ? - ( - nbacksl & 1 ? - (abcd & 63) | 32 - : - ((abcd & 223) | 128) ^ 8 - ) - : (abcd & 24) || !is_some_space(ini_string[chr_idx_i], _LIBCONFINI_WITH_EOL_) ? - abcd & 31 - : abcd & 64 ? - (abcd & 223) | 128 + abcd = + + !(abcd & 10) && ini_string[chr_idx_i] == _CONFINI_D_QUOTES_ ? + ( + nbacksl & 1 ? + (abcd & 63) | 32 + : + ((abcd & 223) | 128) ^ 16 + ) + : !(abcd & 17) && ini_string[chr_idx_i] == _CONFINI_S_QUOTES_ ? + ( + nbacksl & 1 ? + (abcd & 63) | 32 : - (abcd & 95) | 64; + ((abcd & 223) | 128) ^ 8 + ) + : (abcd & 24) || !is_some_space( + ini_string[chr_idx_i], + _CONFINI_WITH_EOL_ + ) ? + abcd & 31 + : abcd & 64 ? + (abcd & 223) | 128 + : + (abcd & 95) | 64; if (nbacksl) { @@ -5476,7 +5627,7 @@ int ini_get_bool_i ( if ( INI_BOOLEANS[pair_idx][bool_idx][chr_idx_s++] != - _LIBCONFINI_BACKSLASH_ + _CONFINI_BACKSLASH_ ) { goto next_bool; @@ -5499,11 +5650,11 @@ int ini_get_bool_i ( if ( abcd & 64 ? - INI_BOOLEANS[pair_idx][bool_idx][chr_idx_s] != _LIBCONFINI_COLLAPSED_ || + INI_BOOLEANS[pair_idx][bool_idx][chr_idx_s] != _CONFINI_COLLAPSED_ || !INI_BOOLEANS[pair_idx][bool_idx][chr_idx_s + 1] : - _LIBCONFINI_CHR_CASEFOLD_(ini_string[chr_idx_i]) != - _LIBCONFINI_CHR_CASEFOLD_(INI_BOOLEANS[pair_idx][bool_idx][chr_idx_s]) + _CONFINI_CHR_CASEFOLD_(ini_string[chr_idx_i]) != + _CONFINI_CHR_CASEFOLD_(INI_BOOLEANS[pair_idx][bool_idx][chr_idx_s]) ) { goto next_bool; @@ -5535,7 +5686,7 @@ int ini_get_bool_i ( } -/*@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(LIBC_STR2NUM)! @@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@ !START_EXCEPTION(LIBC_STR2NUM)! @@@@@@@@@@@@@@@@@@@@@@@@*/ /* LINKS - In case you don't have `#include ` in your source */ @@ -5543,17 +5694,17 @@ int ini_get_bool_i ( /** @alias{ini_get_int} - Pointer to - [`atoi()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atoi) + Pointer to + [`atoi()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atoi) @alias{ini_get_lint} - Pointer to - [`atol()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atol) + Pointer to + [`atol()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atol) @alias{ini_get_llint} - Pointer to - [`atoll()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atoll) + Pointer to + [`atoll()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atoll) @alias{ini_get_double} - Pointer to - [`atof()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atof) + Pointer to + [`atof()`](http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html#index-atof) **/ @@ -5572,22 +5723,22 @@ double (* const ini_get_double) (const char * ini_string) = atof; /** - @brief Legacy support for parsing a `double` data type -- please _do - not use this function_: use `ini_get_double()` instead - @deprecated Deprecated since version 1.12.0 (it will be removed in version - 2.0.0) -- please use #ini_get_double() instead - @param ini_string + @brief Legacy support for parsing a `double` data type -- please _do + not use this function_: use `ini_get_double()` instead + @deprecated Deprecated since version 1.12.0 (it will be removed in version + 2.0.0) -- please use #ini_get_double() instead + @param ini_string The string to parse as a `double` **/ double (* const ini_get_float) (const char * ini_string) = atof; -/*@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(LIBC_STR2NUM)! @@@@@@@@@@@@@@@@@@@@@@@@*/ +/*@@@@@@@@@@@@@@@@@@@@@@@@ !END_EXCEPTION(LIBC_STR2NUM)! @@@@@@@@@@@@@@@@@@@@@@@@@*/ /* GLOBAL VARIABLES */ -bool INI_GLOBAL_LOWERCASE_MODE = _LIBCONFINI_FALSE_; +bool INI_GLOBAL_LOWERCASE_MODE = _CONFINI_FALSE_; char * INI_GLOBAL_IMPLICIT_VALUE = (char *) 0; diff --git a/dev/marked-sources/confini-marked.h b/dev/marked-sources/confini-marked.h index e9ed8db..e06ff87 100644 --- a/dev/marked-sources/confini-marked.h +++ b/dev/marked-sources/confini-marked.h @@ -4,7 +4,7 @@ This is a marked **exact copy** of `src/confini.h`, in which replaceable sections have been wrapped within special tags that can be parsed and amended -by GNU Make during the build process in order to create custom forks of the +by GNU Make during the build process, in order to create custom forks of the library. If you want to contribute to the development of this project, please **use this @@ -20,8 +20,8 @@ any later version. /*@@@@@@@@@@@@@@@@@@@@ !ENTRY_POINT(CONFINI_H_METADATA)! @@@@@@@@@@@@@@@@@@@@*/ -#ifndef _LIBCONFINI_HEADER_ -#define _LIBCONFINI_HEADER_ +#ifndef __CONFINI_H__ +#define __CONFINI_H__ @@ -109,7 +109,6 @@ extern "C" { FORMAT.no_double_quotes && FORMAT.no_single_quotes) - /** @brief Check whether a given `char *` data type points to the global variable #INI_GLOBAL_IMPLICIT_VALUE or to any fragment of it @@ -588,7 +587,7 @@ extern size_t INI_GLOBAL_IMPLICIT_V_LEN; -/* END OF `_LIBCONFINI_HEADER_` */ +/* END OF `__CONFINI_H__` */ #ifdef __cplusplus diff --git a/dev/tests/null-byte_injection/null-byte_injection.c b/dev/tests/null-byte_injection/null-byte_injection.c index 1e1ccd9..7894d65 100644 --- a/dev/tests/null-byte_injection/null-byte_injection.c +++ b/dev/tests/null-byte_injection/null-byte_injection.c @@ -1,4 +1,4 @@ -/* dev/tests/null-byte_injected.c */ +/* dev/tests/null-byte_injection.c */ #include #include diff --git a/dev/tests/null-byte_injection/null-byte_injection.sh b/dev/tests/null-byte_injection/null-byte_injection.sh index fd100e0..aa2c650 100755 --- a/dev/tests/null-byte_injection/null-byte_injection.sh +++ b/dev/tests/null-byte_injection/null-byte_injection.sh @@ -1,10 +1,10 @@ #!/bin/sh # -# myscript.sh +# libconfini/dev/tests/null-byte_injection/null-byte_injection.sh # printf '[my_section]\r\n\r\nfoo = bar\r\nh\000\000e\000llo = wo\000\000\000\000\000rld' > null-byte_injected.conf -gcc -Wall -pedantic -std=c99 -lconfini null-byte_injection.c -O3 -o /tmp/null-byte_injection && { \ +gcc -Wall -pedantic -std=c99 -lconfini null-byte_injection.c -O2 -o /tmp/null-byte_injection && { \ /tmp/null-byte_injection rm /tmp/null-byte_injection } diff --git a/dev/tests/performance/prepare.sh b/dev/tests/performance/prepare.sh index 629923e..55ece1f 100755 --- a/dev/tests/performance/prepare.sh +++ b/dev/tests/performance/prepare.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# prepare.sh +# libconfini/dev/tests/performance/prepare.sh # _SCRIPTPATH="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" diff --git a/dev/tests/performance/sprepare.sh_ b/dev/tests/performance/sprepare.sh_ index 5c68829..9024c6b 100644 --- a/dev/tests/performance/sprepare.sh_ +++ b/dev/tests/performance/sprepare.sh_ @@ -1,6 +1,6 @@ #!/bin/sh # -# sprepare.sh +# libconfini/dev/tests/performance/sprepare.sh # # Unattended mode # diff --git a/dev/tests/performance/unprepare.sh b/dev/tests/performance/unprepare.sh index a0517d0..5abedfc 100755 --- a/dev/tests/performance/unprepare.sh +++ b/dev/tests/performance/unprepare.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# unprepare.sh +# libconfini/dev/tests/performance/unprepare.sh # rm -f big_file.ini speedtest diff --git a/dev/tests/playground/extreme_ini.conf b/dev/tests/playground/extreme_ini.conf new file mode 120000 index 0000000..5a3d108 --- /dev/null +++ b/dev/tests/playground/extreme_ini.conf @@ -0,0 +1 @@ +../../../examples/ini_files/extreme_ini.conf \ No newline at end of file diff --git a/dev/tests/playground/playground.c b/dev/tests/playground/playground.c new file mode 100644 index 0000000..bc6982f --- /dev/null +++ b/dev/tests/playground/playground.c @@ -0,0 +1,96 @@ +/* dev/tests/extreme_ini/extreme_ini.c */ + +#include +#include + + +static int print_ini_stats (IniStatistics * stats, void * v_null) { + + printf( + + "The file is %zu bytes large and contains %zu members.\n" + "Please find below the output of each dispatch.\n", + + stats->bytes, + stats->members + + ); + + return 0; + +} + + +static int ini_listener (IniDispatch * dispatch, void * v_null) { + + printf( + + "\ndispatch_id: %zu\n" + "format: {IniFormat}\n" + "type: %u\n" + "data: `%s`\n" + "value%s: `%s`\n" + "append_to: `%s`\n" + "d_len: %zu\n" + "v_len: %zu\n" + "at_len: %zu\n", + + dispatch->dispatch_id, + dispatch->type, + dispatch->data, + dispatch->value == INI_GLOBAL_IMPLICIT_VALUE ? " (implicit)" : "", + dispatch->value, + *dispatch->append_to ? dispatch->append_to : "{top level}", + dispatch->d_len, + dispatch->v_len, + dispatch->at_len + + ); + + return 0; + +} + + +int main () { + + /* Hackable format */ + #define HACK_ME \ + ((IniFormat) { \ + .delimiter_symbol = INI_EQUALS, \ + .case_sensitive = false, \ + .semicolon_marker = INI_DISABLED_OR_COMMENT, \ + .hash_marker = INI_DISABLED_OR_COMMENT, \ + .section_paths = INI_ABSOLUTE_AND_RELATIVE, \ + .multiline_nodes = INI_MULTILINE_EVERYWHERE, \ + .no_single_quotes = false, \ + .no_double_quotes = false, \ + .no_spaces_in_names = false, \ + .implicit_is_not_empty = true, \ + .do_not_collapse_values = false, \ + .preserve_empty_quotes = false, \ + .disabled_after_space = false, \ + .disabled_can_be_implicit = false \ + }) + + ini_global_set_implicit_value("YES", 3); + + if ( + load_ini_path( + "extreme_ini.conf", + HACK_ME, + print_ini_stats, + ini_listener, + NULL + ) + ) { + + fprintf(stderr, "Sorry, something went wrong :-(\n"); + return 1; + + } + + return 0; + +} + diff --git a/dev/tests/playground/playground.sh b/dev/tests/playground/playground.sh new file mode 100755 index 0000000..a97698f --- /dev/null +++ b/dev/tests/playground/playground.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# +# libconfini/dev/tests/playground/playground.sh +# + +gcc -Wall -pedantic -std=c99 -lconfini playground.c -O2 -o /tmp/playground && { \ + /tmp/playground + rm /tmp/playground +} diff --git a/docs/html/baremetal.html b/docs/html/baremetal.html index 664a76d..a93e908 100644 --- a/docs/html/baremetal.html +++ b/docs/html/baremetal.html @@ -68,7 +68,7 @@

What ./configure --without-io-api does

-

Almost everything in libconfini is implemented from scratch, with the only notable exception of the I/O functions load_ini_file() and load_ini_path(), which rely on standard libraries (either the C Standard or the POSIX Standard, depending on the build settings). On some platforms, however, only a rather exotic I/O API is available, while for some other platforms the C Standard Library is simply too heavy or just not implementable.

+

In libconfini almost everything is implemented from scratch, with the only notable exception of the I/O functions load_ini_file() and load_ini_path(), which rely on standard libraries – either the C Standard or the POSIX Standard, depending on the build settings. On some platforms, however, only a rather exotic I/O API is available, while for some other platforms the C Standard Library is simply too heavy or just not implementable.

In the past, the build environment of libconfini did not offer shortcuts for facing this kind of situations – although, thanks to the modularity of the source code, it was still relatively simple to get rid of every tie with the C Standard Library and compile libconfini as “bare metal”, with strip_ini_cache() as the only parsing function (as this relies only on a buffer for its input), i.e. without load_ini_file() and load_ini_path(), and possibly even without any header at all.

Starting from version 1.13.0 a “bare metal” version of libconfini has been made available simply by passing a --without-io-api option to the configure script. This modified version presents the following characteristics:

    @@ -77,11 +77,11 @@
  • Everything else is inherited verbatim from the official version

The dev/hackings/baremetal/ subdirectory

-

When the configure script is launched with the --without-io-api option (or, equivalently, with --with-io-api=baremetal), it assumes that no standard library at all could be present in the system. Hence it runs a series of tests and creates an inventory of what is present and what is not, in order to amend the source code accordingly – to ignore all the tests and assume that literally nothing from the C Standard Library is supported use --without-libc. The amendments are necessary (instead of just relying on the C preprocessor) because it is required to change the public header, not just the compiled code.

+

When the configure script is launched with the --without-io-api option (or, equivalently, with --with-io-api=baremetal), it assumes that no standard library at all could be present in the system. Hence it runs a series of tests and creates an inventory of what is present and what is not, in order to amend the source code accordingly – to ignore all the tests and assume that literally nothing from the C Standard Library is supported, use --without-libc. The amendments are necessary (instead of just relying on the C preprocessor) because it is required to change the public header, not just the compiled code.

Only a very small amount of code in libconfini depends on the C Standard Library besides the I/O functions, so it is relatively easy to produce a “bare metal” fork with or without the latter. The dev/hackings/baremetal subdirectory contains all the necessary amendments. These are automatically applied when launching make all or make baremetal-source-code after having launched ./configure --without-io-api (the original source code will be preserved).

-

The file str2num.c constitutes a re-implementation of the functions ini_get_int(), ini_get_lint(), ini_get_llint(), ini_get_float() and ini_get_double(), which in the original code are implemented as pointers to standard functions (see below). This file amends src/confini.c.

-

The file str2num.h, which amends src/confini.h (i.e. the public header), exports the function headers of what str2num.c implements.

-

The file confini-header.c contains only a nominal workaround-amendment to src/confini.c (for facilitating the build system) that does not change the final C code compiled.

+

The str2num.c file contains re-implementation of the functions ini_get_int(), ini_get_lint(), ini_get_llint(), ini_get_float() and ini_get_double(), which in the original code are implemented as pointers to standard functions (see below). This file amends src/confini.c.

+

The str2num.h file, which amends src/confini.h (i.e. the public header), exports the function headers of what str2num.c implements.

+

The confini-header.c file contains only a nominal workaround-amendment to src/confini.c (for facilitating the build system) that does not change the final C code compiled.

To create the source code of a “bare metal” version of libconfini a fifth amendment to the public header is also required, containing some common C standard definitions. This amendment is automatically generated for each platform during the build process and will be located under no-dist/hackings/baremetal/c-standard-library.h.

Here follows the summary of what is required by ./configure --without-io-api:

    @@ -90,9 +90,10 @@

    The dev/hackings/baremetal/ subdirectory

  1. dev/hackings/baremetal/str2num.h (pasted to the public header src/confini.h)
  2. no-dist/hackings/baremetal/c-standard-library.h (pasted to the public header src/confini.h after having been automaticaly generated either by the configure script, as an exact copy of dev/hackings/baremetal/c-standard-library.h, or by make approve-revision, in the few cases where manual user's intervention is required during the build process)
-

The first four files (the ones located in the dev/hackings/baremetal subdirectory) are static and do not need any intervention from the user, unless (s)he wants to participate in the development of libconfini. The fifth file might require manual intervention in some situations, depending on the platform or on the user's choice (the build system will emit a warning in such cases).

+

The first four files (the ones located in the dev/hackings/baremetal subdirectory) are static and do not need any intervention from the user, unless (s)he wants to participate in the development of libconfini. The fifth file might require manual intervention in some situations, depending on the platform or the user's will (the build system will emit a warning in such cases).

Re-implementing load_ini_file() and load_ini_path() for your platform

-

Whether you are using the bare-metal version of libconfini for a regular computer, a fridge or a microwave oven, you might have eventually to deal with some kind of filesystem. If the C standard fopen(), fseek(), ftell(), rewind(), fread() and fclose() do not suit your needs, you can re-implement your own version of load_ini_file() and load_ini_path(). The only requirement is that at the end of the day you find a way to pass a disposable buffer containing an entire INI file to strip_ini_cache(). A good way to proceed is to hack the original pair of functions that rely on the C standard I/O API and adapt them to your platform.

+

Whether you are using the bare-metal version of libconfini for a regular computer, a fridge or a microwave oven, you might have eventually to deal with some kind of filesystem. If the C standard fopen(), fseek(), ftell(), rewind(), fread() and fclose() do not suit your needs, you can re-implement your own version of load_ini_file() and load_ini_path(). The only requirement is that at the end of the day you find a way to pass a disposable buffer containing an entire INI file to strip_ini_cache().

+

A good way to proceed is to hack the original pair of functions that rely on the C standard I/O API and adapt them to your platform:

#include <stdio.h>
#include <stdlib.h>
@@ -213,17 +214,17 @@

Re-implementing return return_value;

}
-
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:163
-
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2419
-
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:154
-
@ CONFINI_ENOMEM
Definition: confini.h:413
-
@ CONFINI_EFBIG
Definition: confini.h:419
-
@ CONFINI_EIO
Definition: confini.h:414
-
@ CONFINI_EBADF
Definition: confini.h:417
-
@ CONFINI_ENOENT
Definition: confini.h:412
-
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3083
-
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:2989
-
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:116
+
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:162
+
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2574
+
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:153
+
@ CONFINI_ENOMEM
Definition: confini.h:412
+
@ CONFINI_EFBIG
Definition: confini.h:418
+
@ CONFINI_EIO
Definition: confini.h:413
+
@ CONFINI_EBADF
Definition: confini.h:416
+
@ CONFINI_ENOENT
Definition: confini.h:411
+
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3241
+
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:3147
+
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:115

Going manual

If instead of using the --without-io-api option you prefer to adapt the code manually, follow these simple steps (or adjust them according to your needs), which map verbatim what --without-io-api does:

    @@ -262,11 +263,11 @@

    Parsing numbers without the C Standard Library

    extern double ini_get_double (
    const char * const ini_string
    );
    -
    double(*const ini_get_float)(const char *ini_string)
    Legacy support for parsing a double data type – please do not use this function: use ini_get_double()...
    Definition: confini.c:5509
    -
    long long int(*const ini_get_llint)(const char *ini_string)
    Pointer to atoll()
    Definition: confini.c:5491
    -
    double(*const ini_get_double)(const char *ini_string)
    Pointer to atof()
    Definition: confini.c:5493
    -
    int(*const ini_get_int)(const char *ini_string)
    Pointer to atoi()
    Definition: confini.c:5487
    -
    long int(*const ini_get_lint)(const char *ini_string)
    Pointer to atol()
    Definition: confini.c:5489
    +
    double(*const ini_get_float)(const char *ini_string)
    Legacy support for parsing a double data type – please do not use this function: use ini_get_double()...
    Definition: confini.c:5716
    +
    long long int(*const ini_get_llint)(const char *ini_string)
    Pointer to atoll()
    Definition: confini.c:5698
    +
    double(*const ini_get_double)(const char *ini_string)
    Pointer to atof()
    Definition: confini.c:5700
    +
    int(*const ini_get_int)(const char *ini_string)
    Pointer to atoi()
    Definition: confini.c:5694
    +
    long int(*const ini_get_lint)(const char *ini_string)
    Pointer to atol()
    Definition: confini.c:5696

The same configure option amends in src/confini.c (at the end of the file) the corresponding pointers with the code below. Note that the C language does not possess a templating mechanism, so the following code needs to rely on a macro for not repeating five times the same function body with only minimal variations.

/*
The code below is free software. You can redistribute it and/or modify it
diff --git a/docs/html/confini_8c.html b/docs/html/confini_8c.html index 8f3d0ca..335ae9d 100644 --- a/docs/html/confini_8c.html +++ b/docs/html/confini_8c.html @@ -143,7 +143,7 @@  Remove all comment initializers (# and/or ;) from the beginning of each line of a comment. More...
  static uint_least8_t get_type_as_active (const char *const srcstr, const size_t len, const unsigned char allow_implicit, const IniFormat format) - Try to determine the type of a member "as if it was active". More...
+ Try to determine the type of a member assuming it is active More...
  static size_t further_cuts (char *const srcstr, const IniFormat format)  Examine a (single-/multi-line) segment and check whether it contains more than just one node. More...
@@ -249,7 +249,7 @@

libconfini functions

Author
Stefano Gioffré
-
Version
1.16.1
+
Version
1.16.2
Date
2016-2021
See also
https://madmurphy.github.io/libconfini

Macro Definition Documentation

@@ -607,7 +607,7 @@

-

Try to determine the type of a member "as if it was active".

+

Try to determine the type of a member assuming it is active

Parameters
@@ -617,7 +617,7 @@

Returns
The node type (see header)
+
Returns
The active node type (see confini.h)
@@ -733,13 +733,18 @@

#include <stdio.h>
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -763,13 +768,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -781,15 +788,15 @@

}
libconfini header
-
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3083
-
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3271
-
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:4838
-
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:525
-
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4047
-
Dispatch of a single INI node.
Definition: confini.h:132
-
char * data
Definition: confini.h:135
-
char * value
Definition: confini.h:136
-
const IniFormat format
Definition: confini.h:133
+
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3241
+
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3429
+
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:5028
+
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:524
+
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4217
+
Dispatch of a single INI node.
Definition: confini.h:131
+
char * data
Definition: confini.h:134
+
char * value
Definition: confini.h:135
+
const IniFormat format
Definition: confini.h:132
@@ -869,11 +876,11 @@

#include <confini.h>
static int populate_strarray (
-
char * part,
-
size_t part_len,
-
size_t idx,
-
IniFormat format,
-
void * v_array
+
char * const part,
+
const size_t part_len,
+
const size_t idx,
+
const IniFormat format,
+
void * const v_array
) {
ini_string_parse(part, format);
@@ -883,13 +890,18 @@

}
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -898,17 +910,17 @@

/* Save memory with `ini_array_collapse()` */
-
dispatch->value,
-
DELIMITER,
-
dispatch->format
-
);
+
dispatch->value,
+
DELIMITER,
+
dispatch->format
+
);
/* Allocate a new array of strings with `malloc()` */
my_array_length = ini_array_get_length(
-
dispatch->value,
-
DELIMITER,
-
dispatch->format
-
);
+
dispatch->value,
+
DELIMITER,
+
dispatch->format
+
);
my_array = (char **) malloc(my_array_length * sizeof(char *) +
dispatch->v_len + 1);
@@ -948,13 +960,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -965,11 +979,11 @@

}
-
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:4997
-
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4255
-
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4616
-
size_t v_len
Definition: confini.h:139
-
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:116
+
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:5187
+
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4433
+
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4799
+
size_t v_len
Definition: confini.h:138
+
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:115
Note
The actual space occupied by the array might get reduced further after each member is parsed by ini_string_parse().
@@ -1040,12 +1054,12 @@

#include <confini.h>
static int my_array_fragm_handler (
-
const char * ini_array,
-
size_t fragm_offset,
-
size_t fragm_length,
-
size_t fragm_num,
-
IniFormat format,
-
void * user_data
+
const char * const ini_array,
+
const size_t fragm_offset,
+
const size_t fragm_length,
+
const size_t fragm_num,
+
const IniFormat format,
+
void * const user_data
) {
printf("\"%.*s\"\n", (unsigned int) fragm_length, ini_array + fragm_offset);
@@ -1068,7 +1082,7 @@

}
-
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4374
+
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4554
@@ -1234,13 +1248,18 @@

#include <stdio.h>
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -1265,13 +1284,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -1282,7 +1303,7 @@

}
-
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:4917
+
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:5107
@@ -1335,13 +1356,18 @@

#include <stdio.h>
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -1370,13 +1396,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -1387,7 +1415,7 @@

}
-
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4518
+
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4701
@@ -1460,11 +1488,11 @@

#include <confini.h>
static int my_array_memb_handler (
-
char * arr_member,
-
size_t memb_length,
-
size_t memb_num,
-
IniFormat format,
-
void * foreach_other
+
char * const arr_member,
+
const size_t memb_length,
+
const size_t memb_num,
+
const IniFormat format,
+
void * const foreach_other
) {
printf("\"%s\"\n", arr_member);
@@ -1549,7 +1577,7 @@

Parameters

srcstrString containing an individual node (it may contain multi-line escape sequences)
- +
simple_stringA string to check (it can be NULL)
when_failA value that is returned if no matching boolean is found
when_failThe value that is returned if no matching boolean is found
@@ -1591,7 +1619,7 @@

int my_section_my_number;

bool my_section_my_boolean;
bool my_section_my_implicit_bool;
-
char ** my_section_my_array;
+
char * const * my_section_my_array;
size_t my_section_my_arr_len;
};
@@ -1607,7 +1635,7 @@

return 0;
}
-
static int my_handler (IniDispatch * dsp, void * v_store) {
+
static int my_handler (IniDispatch * const dsp, void * const v_store) {
#define store ((struct ini_store *) v_store)
#define THEYMATCH(SSTR, ISTR) \
ini_string_match_si(SSTR, ISTR, dsp->format)
@@ -1615,9 +1643,7 @@

if (THEYMATCH("my_string", dsp->data)) {
dsp->v_len = ini_string_parse(dsp->value, dsp->format);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_string) {
-
free(store->my_section_my_string);
-
}
+
free(store->my_section_my_string);
/* Allocate the new string */
store->my_section_my_string = strndup(dsp->value, dsp->v_len);
if (!store->my_section_my_string) {
@@ -1645,9 +1671,7 @@

dsp->format
);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_array) {
-
free(store->my_section_my_array);
-
}
+
free((void *) store->my_section_my_array);
/* Allocate a new array of strings */
/* Function in examples/utilities/make_strarray.h */
store->my_section_my_array = make_strarray(
@@ -1706,27 +1730,24 @@

return 1;
}
print_stored_data(&my_store);
-
if (my_store.my_section_my_string) {
-
free(my_store.my_section_my_string);
-
}
-
if (my_store.my_section_my_arr_len) {
-
free(my_store.my_section_my_array);
-
}
+
free(my_store.my_section_my_string);
+
free((void *) my_store.my_section_my_array);
+
return 0;
}
-
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5161
-
@ INI_KEY
Definition: confini.h:443
-
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5309
-
@ INI_IGNORE
Definition: confini.h:477
-
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5487
-
uint_least8_t type
Definition: confini.h:134
-
const char * append_to
Definition: confini.h:137
-
unsigned char hash_marker
Definition: confini.h:116
-
unsigned char semicolon_marker
Definition: confini.h:116
-
unsigned char disabled_can_be_implicit
Definition: confini.h:116
-
unsigned char implicit_is_not_empty
Definition: confini.h:116
-
Global statistics about an INI file.
Definition: confini.h:122
+
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5356
+
@ INI_KEY
Definition: confini.h:442
+
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5511
+
@ INI_IGNORE
Definition: confini.h:476
+
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5694
+
uint_least8_t type
Definition: confini.h:133
+
const char * append_to
Definition: confini.h:136
+
unsigned char hash_marker
Definition: confini.h:115
+
unsigned char semicolon_marker
Definition: confini.h:115
+
unsigned char disabled_can_be_implicit
Definition: confini.h:115
+
unsigned char implicit_is_not_empty
Definition: confini.h:115
+
Global statistics about an INI file.
Definition: confini.h:121
@@ -1766,7 +1787,7 @@

Parameters
- +
ini_stringA string to check (it can be NULL)
when_failA value that is returned if no matching boolean is found
when_failThe value that is returned if no matching boolean is found
formatThe format of the INI file
@@ -1815,7 +1836,7 @@

int my_section_my_number;
bool my_section_my_boolean;
bool my_section_my_implicit_bool;
-
char ** my_section_my_array;
+
char * const * my_section_my_array;
size_t my_section_my_arr_len;
};
@@ -1831,7 +1852,7 @@

return 0;
}
-
static int my_handler (IniDispatch * dsp, void * v_store) {
+
static int my_handler (IniDispatch * const dsp, void * const v_store) {
#define store ((struct ini_store *) v_store)
#define THEYMATCH(SSTR, ISTR) \
ini_string_match_si(SSTR, ISTR, dsp->format)
@@ -1839,9 +1860,7 @@

if (THEYMATCH("my_string", dsp->data)) {
dsp->v_len = ini_string_parse(dsp->value, dsp->format);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_string) {
-
free(store->my_section_my_string);
-
}
+
free(store->my_section_my_string);
/* Allocate the new string */
store->my_section_my_string = strndup(dsp->value, dsp->v_len);
if (!store->my_section_my_string) {
@@ -1869,9 +1888,7 @@

dsp->format
);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_array) {
-
free(store->my_section_my_array);
-
}
+
free((void *) store->my_section_my_array);
/* Allocate a new array of strings */
/* Function in examples/utilities/make_strarray.h */
store->my_section_my_array = make_strarray(
@@ -1930,12 +1947,9 @@

return 1;
}
print_stored_data(&my_store);
-
if (my_store.my_section_my_string) {
-
free(my_store.my_section_my_string);
-
}
-
if (my_store.my_section_my_arr_len) {
-
free(my_store.my_section_my_array);
-
}
+
free(my_store.my_section_my_string);
+
free((void *) my_store.my_section_my_array);
+
return 0;
}
@@ -1983,7 +1997,10 @@

#include <stdio.h>
-
static int ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
if (dispatch->value == INI_GLOBAL_IMPLICIT_VALUE) {
@@ -2022,13 +2039,15 @@

my_format.implicit_is_not_empty = true;
my_format.disabled_can_be_implicit = true;
- -
"../ini_files/unix-like.conf",
-
my_format,
-
NULL,
-
ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/unix-like.conf",
+
my_format,
+
NULL,
+
ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2037,8 +2056,8 @@

}
-
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5518
-
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:533
+
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5725
+
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:532
@@ -2150,7 +2169,7 @@

:
"They don't match"
);
-
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3454
+
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3614

will always match the result of the literal comparison between the same two INI strings after these have been parsed by ini_string_parse() when format.do_not_collapse_values is set to false.

ini_string_parse(my_ini_string_1, format);
ini_string_parse(my_ini_string_2, format);
@@ -2161,7 +2180,7 @@

:

"They don't match"
);
-
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3170
+
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3328

INI strings are the strings typically dispatched by load_ini_file(), load_ini_path() or strip_ini_cache(), which may contain quotes and the three escape sequences \\, \' and \".

In order to be suitable for both names and values, this function always considers sequences of one or more spaces out of quotes in both strings as collapsed, even when format.do_not_collapse_values is set to true.

The format argument is used for the following fields:

@@ -2248,7 +2267,10 @@

#include <stdio.h>
-
static int passfinder (IniDispatch * disp, void * v_membid) {
+
static int passfinder (
+
IniDispatch * const disp,
+
void * const v_membid
+
) {
/* Search for `password = "hello world"` in the INI file */
if (
@@ -2299,9 +2321,9 @@

}
-
#define CONFINI_ERROR
Error mask (flags not present in user-generated interruptions)
Definition: confini.h:399
-
@ CONFINI_FEINTR
Definition: confini.h:410
-
size_t dispatch_id
Definition: confini.h:141
+
#define CONFINI_ERROR
Error mask (flags not present in user-generated interruptions)
Definition: confini.h:398
+
@ CONFINI_FEINTR
Definition: confini.h:409
+
size_t dispatch_id
Definition: confini.h:140
@@ -2405,7 +2427,10 @@

#include <stdio.h>
-
static int ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
if (
dispatch->type == INI_KEY || dispatch->type == INI_DISABLED_KEY
@@ -2429,13 +2454,15 @@

int main () {
-
-
"../ini_files/self_explaining.conf",
- -
NULL,
-
ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/self_explaining.conf",
+ +
NULL,
+
ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2445,8 +2472,8 @@

return 0;
}
-
@ INI_DISABLED_KEY
Definition: confini.h:447
-
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:3906
+
@ INI_DISABLED_KEY
Definition: confini.h:446
+
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4071
@@ -2500,7 +2527,10 @@

#include <stdio.h>
-
static int ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
if (
dispatch->type == INI_KEY || dispatch->type == INI_DISABLED_KEY
@@ -2524,13 +2554,15 @@

int main () {
-
-
"../ini_files/self_explaining.conf",
- -
NULL,
-
ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/self_explaining.conf",
+ +
NULL,
+
ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2581,7 +2613,7 @@

Parameters
- +
chrThe target character
depthWhat is actually considered a space (possible values: _LIBCONFINI_WITH_EOL_, _LIBCONFINI_NO_EOL_, _LIBCONFINI_JUST_S_T_)
depthWhat is actually considered a space (possible values: _CONFINI_WITH_EOL_, _CONFINI_NO_EOL_, _CONFINI_JUST_S_T_)
@@ -2657,7 +2689,10 @@

#include <stdio.h>
-
static int my_callback (IniDispatch * dispatch, void * v_null) {
+
static int my_callback (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n",
@@ -2670,6 +2705,7 @@

int main () {
+
/* Use always `"rb"` with `load_ini_file()`! */
FILE * const ini_file = fopen("../ini_files/delivery.conf", "rb");
if (ini_file == NULL) {
@@ -2679,13 +2715,15 @@

}
-
-
ini_file,
- -
NULL,
-
my_callback,
-
NULL
-
)) {
+
if (
+ +
ini_file,
+ +
NULL,
+
my_callback,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2698,7 +2736,7 @@

}
-
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:2989
+
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:3147
@@ -2768,7 +2806,10 @@

#include <stdio.h>
-
static int my_callback (IniDispatch * dispatch, void * v_null) {
+
static int my_callback (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n",
@@ -2781,13 +2822,15 @@

int main () {
-
-
"../ini_files/delivery.conf",
- -
NULL,
-
my_callback,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/delivery.conf",
+ +
NULL,
+
my_callback,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2846,7 +2889,7 @@

strThe target string offsThe offset where to start the left trim - depthWhat is actually considered a space (possible values: _LIBCONFINI_WITH_EOL_, _LIBCONFINI_NO_EOL_, _LIBCONFINI_JUST_S_T_) + depthWhat is actually considered a space (possible values: _CONFINI_WITH_EOL_, _CONFINI_NO_EOL_, _CONFINI_JUST_S_T_) @@ -2899,7 +2942,7 @@

strThe target string offsThe offset where to start the left trim - depthWhat is actually considered a space (possible values: _LIBCONFINI_WITH_EOL_, _LIBCONFINI_NO_EOL_, _LIBCONFINI_JUST_S_T_) + depthWhat is actually considered a space (possible values: _CONFINI_WITH_EOL_, _CONFINI_NO_EOL_, _CONFINI_JUST_S_T_) @@ -2952,7 +2995,7 @@

strThe target string offsThe offset where to start the left trim - depthWhat is actually considered a space (possible values: _LIBCONFINI_WITH_EOL_, _LIBCONFINI_NO_EOL_, _LIBCONFINI_JUST_S_T_) + depthWhat is actually considered a space (possible values: _CONFINI_WITH_EOL_, _CONFINI_NO_EOL_, _CONFINI_JUST_S_T_) @@ -3058,7 +3101,7 @@

strThe target string lenThe length of the string - depthWhat is actually considered a space (possible values: _LIBCONFINI_WITH_EOL_, _LIBCONFINI_NO_EOL_, _LIBCONFINI_JUST_S_T_) + depthWhat is actually considered a space (possible values: _CONFINI_WITH_EOL_, _CONFINI_NO_EOL_, _CONFINI_JUST_S_T_) @@ -3111,7 +3154,7 @@

strThe target string lenThe length of the string - depthWhat is actually considered a space (possible values: _LIBCONFINI_WITH_EOL_, _LIBCONFINI_NO_EOL_, _LIBCONFINI_JUST_S_T_) + depthWhat is actually considered a space (possible values: _CONFINI_WITH_EOL_, _CONFINI_NO_EOL_, _CONFINI_JUST_S_T_) @@ -3272,7 +3315,7 @@

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

After invoking strip_ini_cache(), the buffer pointed by the ini_source parameter must be considered as a corrupted buffer and should be freed or overwritten. For more information about this function, please refer to the Library Functions Manual.

The parsing algorithms used by libconfini are able to parse any type of file encoded in 8-bit code units, as long as the characters that match the regular expression /[\s\[\]\.\\;#"']/ refer to the same code points they refer to in ASCII (as they do, for example, in UTF-8 and ISO-8859-1), independently of platform-specific conventions.

-
Note
In order to be null-byte-injection-safe, before dispatching the parsed content this function will strip all NUL characters possibly present in the buffer (with the exception of the last one).
+
Note
In order to be null-byte-injection-safe, before dispatching the parsed content this function strips all NUL characters possibly present in the buffer (with the exception of the last one).

Possible return values are: CONFINI_SUCCESS, CONFINI_IINTR, CONFINI_FEINTR, CONFINI_EOOR.

/* examples/topics/strip_ini_cache.c */
@@ -3281,7 +3324,10 @@

#include <string.h>

-
static int my_callback (IniDispatch * dispatch, void * v_null) {
+
static int my_callback (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n",
@@ -3307,14 +3353,16 @@

size_t ini_length = strlen(original_ini_buffer);
char * const ini_cache = strndup(original_ini_buffer, ini_length);
-
-
ini_cache,
-
ini_length,
- -
NULL,
-
my_callback,
-
NULL
-
)) {
+
if (
+
!ini_cache || strip_ini_cache(
+
ini_cache,
+
ini_length,
+ +
NULL,
+
my_callback,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -3359,7 +3407,7 @@

}
-
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2419
+
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2574
@@ -3414,8 +3462,8 @@

Returns
The new length of the string
    -
  • In multi-line comments: srcstr.replace(/^[#;]+|(\n\r?|\r\n?)[\t \v\f]*[#;]+/g, "$1")
  • -
  • In single-line comments: srcstr.replace(/^[#;]+/, "")
  • +
  • Multi-line comments: srcstr.replace(/^[#;]+|(\n\r?|\r\n?)[\t \v\f]*[#;]+/g, "$1")
  • +
  • Single-line comments: srcstr.replace(/^[#;]+/, "")

The argument srcstr may begin with a comment initializer (# or ; depending on the format), or with the character that immediately follows it.

@@ -3603,7 +3651,7 @@

Deprecated:
Deprecated since version 1.12.0 (it will be removed in version 2.0.0) – please use ini_get_double() instead
Parameters
- +
ini_string
ini_stringThe string to parse as a double
diff --git a/docs/html/confini_8h.html b/docs/html/confini_8h.html index ae183e3..38e22b8 100644 --- a/docs/html/confini_8h.html +++ b/docs/html/confini_8h.html @@ -295,10 +295,10 @@ double(*const ini_get_float )(const char *ini_string)  Legacy support for parsing a double data type – please do not use this function: use ini_get_double() instead. More...
  -static const IniFormat INI_DEFAULT_FORMAT = { INI_EQUALS , false , INI_DISABLED_OR_COMMENT , INI_DISABLED_OR_COMMENT , INI_ABSOLUTE_AND_RELATIVE , INI_MULTILINE_EVERYWHERE , false , false , false , false , false , false , false , false , } +static const IniFormat INI_DEFAULT_FORMAT = { INI_EQUALS, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false }  A model format for standard INI files. More...
  -static const IniFormat INI_UNIXLIKE_FORMAT = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } +static const IniFormat INI_UNIXLIKE_FORMAT = { INI_ANY_SPACE, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false }  A model format for Unix-like .conf files (where space characters are delimiters between keys and values) More...
  bool INI_GLOBAL_LOWERCASE_MODE @@ -315,7 +315,7 @@

libconfini header

Author
Stefano Gioffré
-
Version
1.16.1
+
Version
1.16.2
Date
2016-2021
See also
https://madmurphy.github.io/libconfini

Macro Definition Documentation

@@ -357,7 +357,7 @@

printf("Hey! This is either an INI_KEY or an INI_DISABLED_KEY!\n");
}
-
@ INI_DISABLED_KEY
Definition: confini.h:447
+
@ INI_DISABLED_KEY
Definition: confini.h:446

See also IniNodeType.

@@ -379,8 +379,8 @@

Value:
INI_GLOBAL_IMPLICIT_VALUE + INI_GLOBAL_IMPLICIT_V_LEN)
-
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5518
-
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys (default value: 0)
Definition: confini.c:5520
+
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5725
+
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys (default value: 0)
Definition: confini.c:5727

Check whether a given char * data type points to the global variable INI_GLOBAL_IMPLICIT_VALUE or to any fragment of it.

@@ -403,7 +403,7 @@

Value:
FORMAT.no_double_quotes && FORMAT.no_single_quotes)
-
@ INI_NO_MULTILINE
Definition: confini.h:517
+
@ INI_NO_MULTILINE
Definition: confini.h:516

Check whether a format does not support escape sequences.

@@ -444,10 +444,10 @@

_____( preserve_empty_quotes, 21, 1, false ) \
_____( disabled_after_space, 22, 1, false ) \
_____( disabled_can_be_implicit, 23, 1, false )
-
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:489
-
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:474
-
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:508
-
@ INI_EQUALS
Definition: confini.h:461
+
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:488
+
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:473
+
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:507
+
@ INI_EQUALS
Definition: confini.h:460

Call a user-given macro (that accepts four arguments) for each row of the table.

Content of the table:

@@ -856,13 +856,18 @@

#include <stdio.h>
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -886,13 +891,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -904,15 +911,15 @@

}
libconfini header
-
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3083
-
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3271
-
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:4838
-
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:525
-
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4047
-
Dispatch of a single INI node.
Definition: confini.h:132
-
char * data
Definition: confini.h:135
-
char * value
Definition: confini.h:136
-
const IniFormat format
Definition: confini.h:133
+
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3241
+
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3429
+
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:5028
+
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:524
+
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4217
+
Dispatch of a single INI node.
Definition: confini.h:131
+
char * data
Definition: confini.h:134
+
char * value
Definition: confini.h:135
+
const IniFormat format
Definition: confini.h:132
@@ -992,11 +999,11 @@

#include <confini.h>
static int populate_strarray (
-
char * part,
-
size_t part_len,
-
size_t idx,
-
IniFormat format,
-
void * v_array
+
char * const part,
+
const size_t part_len,
+
const size_t idx,
+
const IniFormat format,
+
void * const v_array
) {
ini_string_parse(part, format);
@@ -1006,13 +1013,18 @@

}
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -1021,17 +1033,17 @@

/* Save memory with `ini_array_collapse()` */
-
dispatch->value,
-
DELIMITER,
-
dispatch->format
-
);
+
dispatch->value,
+
DELIMITER,
+
dispatch->format
+
);
/* Allocate a new array of strings with `malloc()` */
my_array_length = ini_array_get_length(
-
dispatch->value,
-
DELIMITER,
-
dispatch->format
-
);
+
dispatch->value,
+
DELIMITER,
+
dispatch->format
+
);
my_array = (char **) malloc(my_array_length * sizeof(char *) +
dispatch->v_len + 1);
@@ -1071,13 +1083,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -1088,11 +1102,11 @@

}
-
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:4997
-
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4255
-
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4616
-
size_t v_len
Definition: confini.h:139
-
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:116
+
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:5187
+
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4433
+
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4799
+
size_t v_len
Definition: confini.h:138
+
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:115
Note
The actual space occupied by the array might get reduced further after each member is parsed by ini_string_parse().
@@ -1163,12 +1177,12 @@

#include <confini.h>
static int my_array_fragm_handler (
-
const char * ini_array,
-
size_t fragm_offset,
-
size_t fragm_length,
-
size_t fragm_num,
-
IniFormat format,
-
void * user_data
+
const char * const ini_array,
+
const size_t fragm_offset,
+
const size_t fragm_length,
+
const size_t fragm_num,
+
const IniFormat format,
+
void * const user_data
) {
printf("\"%.*s\"\n", (unsigned int) fragm_length, ini_array + fragm_offset);
@@ -1191,7 +1205,7 @@

}
-
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4374
+
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4554
@@ -1357,13 +1371,18 @@

#include <stdio.h>
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -1388,13 +1407,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -1405,7 +1426,7 @@

}
-
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:4917
+
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:5107
@@ -1458,13 +1479,18 @@

#include <stdio.h>
-
static int my_ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int my_ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
- -
"my_array",
-
dispatch->data,
-
dispatch->format
-
)) {
+
if (
+ +
"my_array",
+
dispatch->data,
+
dispatch->format
+
)
+
) {
#define DELIMITER ','
@@ -1493,13 +1519,15 @@

int main () {
-
-
"../ini_files/typed_ini.conf",
- -
NULL,
-
my_ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/typed_ini.conf",
+ +
NULL,
+
my_ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -1510,7 +1538,7 @@

}
-
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4518
+
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4701
@@ -1583,11 +1611,11 @@

#include <confini.h>
static int my_array_memb_handler (
-
char * arr_member,
-
size_t memb_length,
-
size_t memb_num,
-
IniFormat format,
-
void * foreach_other
+
char * const arr_member,
+
const size_t memb_length,
+
const size_t memb_num,
+
const IniFormat format,
+
void * const foreach_other
) {
printf("\"%s\"\n", arr_member);
@@ -1672,7 +1700,7 @@

Parameters
- +
simple_stringA string to check (it can be NULL)
when_failA value that is returned if no matching boolean is found
when_failThe value that is returned if no matching boolean is found
@@ -1714,7 +1742,7 @@

int my_section_my_number;
bool my_section_my_boolean;
bool my_section_my_implicit_bool;
-
char ** my_section_my_array;
+
char * const * my_section_my_array;
size_t my_section_my_arr_len;
};
@@ -1730,7 +1758,7 @@

return 0;
}
-
static int my_handler (IniDispatch * dsp, void * v_store) {
+
static int my_handler (IniDispatch * const dsp, void * const v_store) {
#define store ((struct ini_store *) v_store)
#define THEYMATCH(SSTR, ISTR) \
ini_string_match_si(SSTR, ISTR, dsp->format)
@@ -1738,9 +1766,7 @@

if (THEYMATCH("my_string", dsp->data)) {
dsp->v_len = ini_string_parse(dsp->value, dsp->format);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_string) {
-
free(store->my_section_my_string);
-
}
+
free(store->my_section_my_string);
/* Allocate the new string */
store->my_section_my_string = strndup(dsp->value, dsp->v_len);
if (!store->my_section_my_string) {
@@ -1768,9 +1794,7 @@

dsp->format
);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_array) {
-
free(store->my_section_my_array);
-
}
+
free((void *) store->my_section_my_array);
/* Allocate a new array of strings */
/* Function in examples/utilities/make_strarray.h */
store->my_section_my_array = make_strarray(
@@ -1829,27 +1853,24 @@

return 1;
}
print_stored_data(&my_store);
-
if (my_store.my_section_my_string) {
-
free(my_store.my_section_my_string);
-
}
-
if (my_store.my_section_my_arr_len) {
-
free(my_store.my_section_my_array);
-
}
+
free(my_store.my_section_my_string);
+
free((void *) my_store.my_section_my_array);
+
return 0;
}
-
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5161
-
@ INI_KEY
Definition: confini.h:443
-
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5309
-
@ INI_IGNORE
Definition: confini.h:477
-
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5487
-
uint_least8_t type
Definition: confini.h:134
-
const char * append_to
Definition: confini.h:137
-
unsigned char hash_marker
Definition: confini.h:116
-
unsigned char semicolon_marker
Definition: confini.h:116
-
unsigned char disabled_can_be_implicit
Definition: confini.h:116
-
unsigned char implicit_is_not_empty
Definition: confini.h:116
-
Global statistics about an INI file.
Definition: confini.h:122
+
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5356
+
@ INI_KEY
Definition: confini.h:442
+
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5511
+
@ INI_IGNORE
Definition: confini.h:476
+
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5694
+
uint_least8_t type
Definition: confini.h:133
+
const char * append_to
Definition: confini.h:136
+
unsigned char hash_marker
Definition: confini.h:115
+
unsigned char semicolon_marker
Definition: confini.h:115
+
unsigned char disabled_can_be_implicit
Definition: confini.h:115
+
unsigned char implicit_is_not_empty
Definition: confini.h:115
+
Global statistics about an INI file.
Definition: confini.h:121
@@ -1889,7 +1910,7 @@

Parameters
- +
ini_stringA string to check (it can be NULL)
when_failA value that is returned if no matching boolean is found
when_failThe value that is returned if no matching boolean is found
formatThe format of the INI file
@@ -1938,7 +1959,7 @@

int my_section_my_number;
bool my_section_my_boolean;
bool my_section_my_implicit_bool;
-
char ** my_section_my_array;
+
char * const * my_section_my_array;
size_t my_section_my_arr_len;
};
@@ -1954,7 +1975,7 @@

return 0;
}
-
static int my_handler (IniDispatch * dsp, void * v_store) {
+
static int my_handler (IniDispatch * const dsp, void * const v_store) {
#define store ((struct ini_store *) v_store)
#define THEYMATCH(SSTR, ISTR) \
ini_string_match_si(SSTR, ISTR, dsp->format)
@@ -1962,9 +1983,7 @@

if (THEYMATCH("my_string", dsp->data)) {
dsp->v_len = ini_string_parse(dsp->value, dsp->format);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_string) {
-
free(store->my_section_my_string);
-
}
+
free(store->my_section_my_string);
/* Allocate the new string */
store->my_section_my_string = strndup(dsp->value, dsp->v_len);
if (!store->my_section_my_string) {
@@ -1992,9 +2011,7 @@

dsp->format
);
/* Free previous duplicate key (if any) */
-
if (store->my_section_my_array) {
-
free(store->my_section_my_array);
-
}
+
free((void *) store->my_section_my_array);
/* Allocate a new array of strings */
/* Function in examples/utilities/make_strarray.h */
store->my_section_my_array = make_strarray(
@@ -2053,12 +2070,9 @@

return 1;
}
print_stored_data(&my_store);
-
if (my_store.my_section_my_string) {
-
free(my_store.my_section_my_string);
-
}
-
if (my_store.my_section_my_arr_len) {
-
free(my_store.my_section_my_array);
-
}
+
free(my_store.my_section_my_string);
+
free((void *) my_store.my_section_my_array);
+
return 0;
}
@@ -2106,7 +2120,10 @@

#include <stdio.h>
-
static int ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
if (dispatch->value == INI_GLOBAL_IMPLICIT_VALUE) {
@@ -2145,13 +2162,15 @@

my_format.implicit_is_not_empty = true;
my_format.disabled_can_be_implicit = true;
- -
"../ini_files/unix-like.conf",
-
my_format,
-
NULL,
-
ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/unix-like.conf",
+
my_format,
+
NULL,
+
ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2160,7 +2179,7 @@

}
-
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:533
+
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:532
@@ -2272,7 +2291,7 @@

:
"They don't match"
);
-
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3454
+
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3614

will always match the result of the literal comparison between the same two INI strings after these have been parsed by ini_string_parse() when format.do_not_collapse_values is set to false.

ini_string_parse(my_ini_string_1, format);
ini_string_parse(my_ini_string_2, format);
@@ -2283,7 +2302,7 @@

:

"They don't match"
);
-
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3170
+
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3328

INI strings are the strings typically dispatched by load_ini_file(), load_ini_path() or strip_ini_cache(), which may contain quotes and the three escape sequences \\, \' and \".

In order to be suitable for both names and values, this function always considers sequences of one or more spaces out of quotes in both strings as collapsed, even when format.do_not_collapse_values is set to true.

The format argument is used for the following fields:

@@ -2370,7 +2389,10 @@

#include <stdio.h>
-
static int passfinder (IniDispatch * disp, void * v_membid) {
+
static int passfinder (
+
IniDispatch * const disp,
+
void * const v_membid
+
) {
/* Search for `password = "hello world"` in the INI file */
if (
@@ -2421,9 +2443,9 @@

}
-
#define CONFINI_ERROR
Error mask (flags not present in user-generated interruptions)
Definition: confini.h:399
-
@ CONFINI_FEINTR
Definition: confini.h:410
-
size_t dispatch_id
Definition: confini.h:141
+
#define CONFINI_ERROR
Error mask (flags not present in user-generated interruptions)
Definition: confini.h:398
+
@ CONFINI_FEINTR
Definition: confini.h:409
+
size_t dispatch_id
Definition: confini.h:140
@@ -2527,7 +2549,10 @@

#include <stdio.h>
-
static int ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
if (
dispatch->type == INI_KEY || dispatch->type == INI_DISABLED_KEY
@@ -2551,13 +2576,15 @@

int main () {
-
-
"../ini_files/self_explaining.conf",
- -
NULL,
-
ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/self_explaining.conf",
+ +
NULL,
+
ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2567,7 +2594,7 @@

return 0;
}
-
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:3906
+
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4071
@@ -2621,7 +2648,10 @@

#include <stdio.h>
-
static int ini_listener (IniDispatch * dispatch, void * v_null) {
+
static int ini_listener (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
if (
dispatch->type == INI_KEY || dispatch->type == INI_DISABLED_KEY
@@ -2645,13 +2675,15 @@

int main () {
-
-
"../ini_files/self_explaining.conf",
- -
NULL,
-
ini_listener,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/self_explaining.conf",
+ +
NULL,
+
ini_listener,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2732,7 +2764,10 @@

#include <stdio.h>
-
static int my_callback (IniDispatch * dispatch, void * v_null) {
+
static int my_callback (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n",
@@ -2745,6 +2780,7 @@

int main () {
+
/* Use always `"rb"` with `load_ini_file()`! */
FILE * const ini_file = fopen("../ini_files/delivery.conf", "rb");
if (ini_file == NULL) {
@@ -2754,13 +2790,15 @@

}
-
-
ini_file,
- -
NULL,
-
my_callback,
-
NULL
-
)) {
+
if (
+ +
ini_file,
+ +
NULL,
+
my_callback,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2773,7 +2811,7 @@

}
-
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:2989
+
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:3147
@@ -2843,7 +2881,10 @@

#include <stdio.h>
-
static int my_callback (IniDispatch * dispatch, void * v_null) {
+
static int my_callback (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n",
@@ -2856,13 +2897,15 @@

int main () {
-
-
"../ini_files/delivery.conf",
- -
NULL,
-
my_callback,
-
NULL
-
)) {
+
if (
+ +
"../ini_files/delivery.conf",
+ +
NULL,
+
my_callback,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -2946,7 +2989,7 @@

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

After invoking strip_ini_cache(), the buffer pointed by the ini_source parameter must be considered as a corrupted buffer and should be freed or overwritten. For more information about this function, please refer to the Library Functions Manual.

The parsing algorithms used by libconfini are able to parse any type of file encoded in 8-bit code units, as long as the characters that match the regular expression /[\s\[\]\.\\;#"']/ refer to the same code points they refer to in ASCII (as they do, for example, in UTF-8 and ISO-8859-1), independently of platform-specific conventions.

-
Note
In order to be null-byte-injection-safe, before dispatching the parsed content this function will strip all NUL characters possibly present in the buffer (with the exception of the last one).
+
Note
In order to be null-byte-injection-safe, before dispatching the parsed content this function strips all NUL characters possibly present in the buffer (with the exception of the last one).

Possible return values are: CONFINI_SUCCESS, CONFINI_IINTR, CONFINI_FEINTR, CONFINI_EOOR.

/* examples/topics/strip_ini_cache.c */
@@ -2955,7 +2998,10 @@

#include <string.h>

-
static int my_callback (IniDispatch * dispatch, void * v_null) {
+
static int my_callback (
+
IniDispatch * const dispatch,
+
void * const v_null
+
) {
printf(
"DATA: %s\nVALUE: %s\nNODE TYPE: %u\n\n",
@@ -2981,14 +3027,16 @@

size_t ini_length = strlen(original_ini_buffer);
char * const ini_cache = strndup(original_ini_buffer, ini_length);
-
-
ini_cache,
-
ini_length,
- -
NULL,
-
my_callback,
-
NULL
-
)) {
+
if (
+
!ini_cache || strip_ini_cache(
+
ini_cache,
+
ini_length,
+ +
NULL,
+
my_callback,
+
NULL
+
)
+
) {
fprintf(stderr, "Sorry, something went wrong :-(\n");
return 1;
@@ -3033,7 +3081,7 @@

}
-
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2419
+
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2574
@@ -3048,7 +3096,7 @@

- +
const IniFormat INI_DEFAULT_FORMAT = { INI_EQUALS , false , INI_DISABLED_OR_COMMENT , INI_DISABLED_OR_COMMENT , INI_ABSOLUTE_AND_RELATIVE , INI_MULTILINE_EVERYWHERE , false , false , false , false , false , false , false , false , }const IniFormat INI_DEFAULT_FORMAT = { INI_EQUALS, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false }
@@ -3118,7 +3166,7 @@

Deprecated:
Deprecated since version 1.12.0 (it will be removed in version 2.0.0) – please use ini_get_double() instead
Parameters
- +
ini_string
ini_stringThe string to parse as a double
@@ -3292,7 +3340,7 @@

- +
const IniFormat INI_UNIXLIKE_FORMAT = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }const IniFormat INI_UNIXLIKE_FORMAT = { INI_ANY_SPACE, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false }
diff --git a/docs/html/confini_8h_source.html b/docs/html/confini_8h_source.html index d7473ae..4057170 100644 --- a/docs/html/confini_8h_source.html +++ b/docs/html/confini_8h_source.html @@ -72,8 +72,8 @@
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
2 
-
16 #ifndef _LIBCONFINI_HEADER_
-
17 #define _LIBCONFINI_HEADER_
+
16 #ifndef __CONFINI_H__
+
17 #define __CONFINI_H__
18 
19 
20 
@@ -151,480 +151,479 @@
99  (FORMAT.multiline_nodes == INI_NO_MULTILINE && \
100  FORMAT.no_double_quotes && FORMAT.no_single_quotes)
101 
-
102 
-
103 
-
108 #define INI_IS_IMPLICIT_SUBSTR(CHAR_PTR) \
-
109  (CHAR_PTR >= INI_GLOBAL_IMPLICIT_VALUE && CHAR_PTR <= \
-
110  INI_GLOBAL_IMPLICIT_VALUE + INI_GLOBAL_IMPLICIT_V_LEN)
+
102 
+
107 #define INI_IS_IMPLICIT_SUBSTR(CHAR_PTR) \
+
108  (CHAR_PTR >= INI_GLOBAL_IMPLICIT_VALUE && CHAR_PTR <= \
+
109  INI_GLOBAL_IMPLICIT_VALUE + INI_GLOBAL_IMPLICIT_V_LEN)
+
110 
111 
112 
-
113 
-
114 /* PUBLIC TYPEDEFS */
-
115 
-
116 
-
121 typedef _LIBCONFINI_INIFORMAT_TYPE_ IniFormat;
-
122 
-
123 
-
127 typedef struct IniStatistics {
-
128  const IniFormat format;
-
129  const size_t bytes;
-
130  const size_t members;
-
131 } IniStatistics;
-
132 
-
133 
-
137 typedef struct IniDispatch {
- -
139  uint_least8_t type;
-
140  char * data;
-
141  char * value;
-
142  const char * append_to;
-
143  size_t d_len;
-
144  size_t v_len;
-
145  size_t at_len;
-
146  size_t dispatch_id;
-
147 } IniDispatch;
-
148 
-
149 
-
153 typedef uint_least32_t IniFormatNum;
-
154 
-
155 
-
159 typedef int (* IniStatsHandler) (
-
160  IniStatistics * statistics,
-
161  void * user_data
-
162 );
-
163 
-
164 
-
168 typedef int (* IniDispHandler) (
-
169  IniDispatch * dispatch,
-
170  void * user_data
-
171 );
-
172 
-
173 
-
178 typedef int (* IniStrHandler) (
-
179  char * ini_string,
-
180  size_t string_length,
-
181  size_t string_num,
-
182  IniFormat format,
-
183  void * user_data
-
184 );
-
185 
-
186 
-
190 typedef int (* IniSubstrHandler) (
-
191  const char * ini_string,
-
192  size_t fragm_offset,
-
193  size_t fragm_length,
-
194  size_t fragm_num,
-
195  IniFormat format,
-
196  void * user_data
-
197 );
+
113 /* PUBLIC TYPEDEFS */
+
114 
+
115 
+
120 typedef _LIBCONFINI_INIFORMAT_TYPE_ IniFormat;
+
121 
+
122 
+
126 typedef struct IniStatistics {
+
127  const IniFormat format;
+
128  const size_t bytes;
+
129  const size_t members;
+
130 } IniStatistics;
+
131 
+
132 
+
136 typedef struct IniDispatch {
+ +
138  uint_least8_t type;
+
139  char * data;
+
140  char * value;
+
141  const char * append_to;
+
142  size_t d_len;
+
143  size_t v_len;
+
144  size_t at_len;
+
145  size_t dispatch_id;
+
146 } IniDispatch;
+
147 
+
148 
+
152 typedef uint_least32_t IniFormatNum;
+
153 
+
154 
+
158 typedef int (* IniStatsHandler) (
+
159  IniStatistics * statistics,
+
160  void * user_data
+
161 );
+
162 
+
163 
+
167 typedef int (* IniDispHandler) (
+
168  IniDispatch * dispatch,
+
169  void * user_data
+
170 );
+
171 
+
172 
+
177 typedef int (* IniStrHandler) (
+
178  char * ini_string,
+
179  size_t string_length,
+
180  size_t string_num,
+
181  IniFormat format,
+
182  void * user_data
+
183 );
+
184 
+
185 
+
189 typedef int (* IniSubstrHandler) (
+
190  const char * ini_string,
+
191  size_t fragm_offset,
+
192  size_t fragm_length,
+
193  size_t fragm_num,
+
194  IniFormat format,
+
195  void * user_data
+
196 );
+
197 
198 
199 
-
200 
-
201 /* PUBLIC FUNCTIONS */
+
200 /* PUBLIC FUNCTIONS */
+
201 
202 
-
203 
-
204 extern int strip_ini_cache (
-
205  register char * const ini_source,
-
206  const size_t ini_length,
-
207  const IniFormat format,
-
208  const IniStatsHandler f_init,
-
209  const IniDispHandler f_foreach,
-
210  void * const user_data
-
211 );
+
203 extern int strip_ini_cache (
+
204  register char * const ini_source,
+
205  const size_t ini_length,
+
206  const IniFormat format,
+
207  const IniStatsHandler f_init,
+
208  const IniDispHandler f_foreach,
+
209  void * const user_data
+
210 );
+
211 
212 
-
213 
-
214 extern int load_ini_file (
-
215  FILE * const ini_file,
-
216  const IniFormat format,
-
217  const IniStatsHandler f_init,
-
218  const IniDispHandler f_foreach,
-
219  void * const user_data
-
220 );
+
213 extern int load_ini_file (
+
214  FILE * const ini_file,
+
215  const IniFormat format,
+
216  const IniStatsHandler f_init,
+
217  const IniDispHandler f_foreach,
+
218  void * const user_data
+
219 );
+
220 
221 
-
222 
-
223 extern int load_ini_path (
-
224  const char * const path,
-
225  const IniFormat format,
-
226  const IniStatsHandler f_init,
-
227  const IniDispHandler f_foreach,
-
228  void * const user_data
-
229 );
+
222 extern int load_ini_path (
+
223  const char * const path,
+
224  const IniFormat format,
+
225  const IniStatsHandler f_init,
+
226  const IniDispHandler f_foreach,
+
227  void * const user_data
+
228 );
+
229 
230 
-
231 
-
232 extern bool ini_string_match_ss (
-
233  const char * const simple_string_a,
-
234  const char * const simple_string_b,
-
235  const IniFormat format
-
236 );
+
231 extern bool ini_string_match_ss (
+
232  const char * const simple_string_a,
+
233  const char * const simple_string_b,
+
234  const IniFormat format
+
235 );
+
236 
237 
-
238 
-
239 extern bool ini_string_match_si (
-
240  const char * const simple_string,
-
241  const char * const ini_string,
-
242  const IniFormat format
-
243 );
+
238 extern bool ini_string_match_si (
+
239  const char * const simple_string,
+
240  const char * const ini_string,
+
241  const IniFormat format
+
242 );
+
243 
244 
-
245 
-
246 extern bool ini_string_match_ii (
-
247  const char * const ini_string_a,
-
248  const char * const ini_string_b,
-
249  const IniFormat format
-
250 );
+
245 extern bool ini_string_match_ii (
+
246  const char * const ini_string_a,
+
247  const char * const ini_string_b,
+
248  const IniFormat format
+
249 );
+
250 
251 
-
252 
-
253 extern bool ini_array_match (
-
254  const char * const ini_string_a,
-
255  const char * const ini_string_b,
-
256  const char delimiter,
-
257  const IniFormat format
-
258 );
+
252 extern bool ini_array_match (
+
253  const char * const ini_string_a,
+
254  const char * const ini_string_b,
+
255  const char delimiter,
+
256  const IniFormat format
+
257 );
+
258 
259 
-
260 
-
261 extern size_t ini_unquote (
-
262  char * const ini_string,
-
263  const IniFormat format
-
264 );
+
260 extern size_t ini_unquote (
+
261  char * const ini_string,
+
262  const IniFormat format
+
263 );
+
264 
265 
-
266 
-
267 extern size_t ini_string_parse (
-
268  char * const ini_string,
-
269  const IniFormat format
-
270 );
+
266 extern size_t ini_string_parse (
+
267  char * const ini_string,
+
268  const IniFormat format
+
269 );
+
270 
271 
-
272 
-
273 extern size_t ini_array_get_length (
-
274  const char * const ini_string,
-
275  const char delimiter,
-
276  const IniFormat format
-
277 );
+
272 extern size_t ini_array_get_length (
+
273  const char * const ini_string,
+
274  const char delimiter,
+
275  const IniFormat format
+
276 );
+
277 
278 
-
279 
-
280 extern int ini_array_foreach (
-
281  const char * const ini_string,
-
282  const char delimiter,
-
283  const IniFormat format,
-
284  const IniSubstrHandler f_foreach,
-
285  void * const user_data
-
286 );
+
279 extern int ini_array_foreach (
+
280  const char * const ini_string,
+
281  const char delimiter,
+
282  const IniFormat format,
+
283  const IniSubstrHandler f_foreach,
+
284  void * const user_data
+
285 );
+
286 
287 
-
288 
-
289 extern size_t ini_array_shift (
-
290  const char ** const ini_strptr,
-
291  const char delimiter,
-
292  const IniFormat format
-
293 );
+
288 extern size_t ini_array_shift (
+
289  const char ** const ini_strptr,
+
290  const char delimiter,
+
291  const IniFormat format
+
292 );
+
293 
294 
-
295 
-
296 extern size_t ini_array_collapse (
-
297  char * const ini_string,
-
298  const char delimiter,
-
299  const IniFormat format
-
300 );
+
295 extern size_t ini_array_collapse (
+
296  char * const ini_string,
+
297  const char delimiter,
+
298  const IniFormat format
+
299 );
+
300 
301 
-
302 
-
303 extern char * ini_array_break (
-
304  char * const ini_string,
-
305  const char delimiter,
-
306  const IniFormat format
-
307 );
+
302 extern char * ini_array_break (
+
303  char * const ini_string,
+
304  const char delimiter,
+
305  const IniFormat format
+
306 );
+
307 
308 
-
309 
-
310 extern char * ini_array_release (
-
311  char ** const ini_strptr,
-
312  const char delimiter,
-
313  const IniFormat format
-
314 );
+
309 extern char * ini_array_release (
+
310  char ** const ini_strptr,
+
311  const char delimiter,
+
312  const IniFormat format
+
313 );
+
314 
315 
-
316 
-
317 extern int ini_array_split (
-
318  char * const ini_string,
-
319  const char delimiter,
-
320  const IniFormat format,
-
321  const IniStrHandler f_foreach,
-
322  void * const user_data
-
323 );
+
316 extern int ini_array_split (
+
317  char * const ini_string,
+
318  const char delimiter,
+
319  const IniFormat format,
+
320  const IniStrHandler f_foreach,
+
321  void * const user_data
+
322 );
+
323 
324 
-
325 
-
326 extern void ini_global_set_lowercase_mode (
-
327  const bool lowercase
-
328 );
-
329 #define __ini_global_set_lowercase_mode \
-
330  _LIBCONFINI_WARNING_("deprecated function `ini_global_set_lowercase_mode()`") \
-
331  ini_global_set_lowercase_mode
+
325 extern void ini_global_set_lowercase_mode (
+
326  const bool lowercase
+
327 );
+
328 #define __ini_global_set_lowercase_mode \
+
329  _LIBCONFINI_WARNING_("deprecated function `ini_global_set_lowercase_mode()`") \
+
330  ini_global_set_lowercase_mode
+
331 
332 
-
333 
-
334 extern void ini_global_set_implicit_value (
-
335  char * const implicit_value,
-
336  const size_t implicit_v_len
-
337 );
+
333 extern void ini_global_set_implicit_value (
+
334  char * const implicit_value,
+
335  const size_t implicit_v_len
+
336 );
+
337 
338 
-
339 
-
340 extern IniFormatNum ini_fton (
-
341  const IniFormat format
-
342 );
+
339 extern IniFormatNum ini_fton (
+
340  const IniFormat format
+
341 );
+
342 
343 
-
344 
-
345 extern IniFormat ini_ntof (
-
346  const IniFormatNum format_id
-
347 );
+
344 extern IniFormat ini_ntof (
+
345  const IniFormatNum format_id
+
346 );
+
347 
348 
-
349 
-
350 extern int ini_get_bool (
-
351  const char * const simple_string,
-
352  const int when_fail
-
353 );
+
349 extern int ini_get_bool (
+
350  const char * const simple_string,
+
351  const int when_fail
+
352 );
+
353 
354 
-
355 
-
356 extern int ini_get_bool_i (
-
357  const char * const ini_string,
-
358  const int when_fail,
-
359  const IniFormat format
-
360 );
+
355 extern int ini_get_bool_i (
+
356  const char * const ini_string,
+
357  const int when_fail,
+
358  const IniFormat format
+
359 );
+
360 
361 
362 
-
363 
-
364 /* PUBLIC LINKS */
+
363 /* PUBLIC LINKS */
+
364 
365 
-
366 
-
367 extern int (* const ini_get_int) (
-
368  const char * ini_string
-
369 );
+
366 extern int (* const ini_get_int) (
+
367  const char * ini_string
+
368 );
+
369 
370 
-
371 
-
372 extern long int (* const ini_get_lint) (
-
373  const char * ini_string
-
374 );
+
371 extern long int (* const ini_get_lint) (
+
372  const char * ini_string
+
373 );
+
374 
375 
-
376 
-
377 extern long long int (* const ini_get_llint) (
-
378  const char * ini_string
-
379 );
+
376 extern long long int (* const ini_get_llint) (
+
377  const char * ini_string
+
378 );
+
379 
380 
-
381 
-
382 extern double (* const ini_get_double) (
-
383  const char * ini_string
-
384 );
+
381 extern double (* const ini_get_double) (
+
382  const char * ini_string
+
383 );
+
384 
385 
-
386 
-
387 /*
-
388  Legacy support -- please **do not use these functions**!
-
389 */
-
390 extern double (* const ini_get_float) (const char * ini_string);
-
391 
-
392 #define __ini_get_float \
-
393  _LIBCONFINI_WARNING_("function `ini_get_float()` is deprecated for parsing a `double` data type; use `ini_get_double()` instead") \
-
394  ini_get_double
+
386 /*
+
387  Legacy support -- please **do not use these functions**!
+
388 */
+
389 extern double (* const ini_get_float) (const char * ini_string);
+
390 
+
391 #define __ini_get_float \
+
392  _LIBCONFINI_WARNING_("function `ini_get_float()` is deprecated for parsing a `double` data type; use `ini_get_double()` instead") \
+
393  ini_get_double
+
394 
395 
396 
-
397 
-
398 /* PUBLIC CONSTANTS AND VARIABLES */
-
399 
-
400 
-
404 #define CONFINI_ERROR 252
-
405 
-
406 
-
410 enum ConfiniInterruptNo {
- - -
415  CONFINI_FEINTR = 2,
-
417  CONFINI_ENOENT = 4,
- - -
420  CONFINI_EOOR = 7,
-
422  CONFINI_EBADF = 8,
-
424  CONFINI_EFBIG = 9,
-
425  CONFINI_EROADDR = 10
-
426 };
+
397 /* PUBLIC CONSTANTS AND VARIABLES */
+
398 
+
399 
+
403 #define CONFINI_ERROR 252
+
404 
+
405 
+
409 enum ConfiniInterruptNo {
+ + +
414  CONFINI_FEINTR = 2,
+
416  CONFINI_ENOENT = 4,
+ + +
419  CONFINI_EOOR = 7,
+
421  CONFINI_EBADF = 8,
+
423  CONFINI_EFBIG = 9,
+
424  CONFINI_EROADDR = 10
+
425 };
+
426 
427 
-
428 
-
433 #define INI_DISABLED_FLAG 4
+
432 #define INI_DISABLED_FLAG 4
+
433 
434 
-
435 
-
441 enum IniNodeType {
- -
444  INI_VALUE = 1,
-
448  INI_KEY = 2,
-
449  INI_SECTION = 3,
- -
451  INI_INLINE_COMMENT = 5,
-
452  INI_DISABLED_KEY = 6,
- -
455 };
-
456 
-
457 
- - -
466  INI_EQUALS = '=',
-
467  INI_COLON = ':',
-
468  INI_DOT = '.',
-
469  INI_COMMA = ','
-
470 };
+
440 enum IniNodeType {
+ +
443  INI_VALUE = 1,
+
447  INI_KEY = 2,
+
448  INI_SECTION = 3,
+ +
450  INI_INLINE_COMMENT = 5,
+
451  INI_DISABLED_KEY = 6,
+ +
454 };
+
455 
+
456 
+ + +
465  INI_EQUALS = '=',
+
466  INI_COLON = ':',
+
467  INI_DOT = '.',
+
468  INI_COMMA = ','
+
469 };
+
470 
471 
-
472 
-
478 enum IniCommentMarker {
- -
481  INI_ONLY_COMMENT = 1,
- - -
487 };
-
488 
-
489 
-
493 enum IniSectionPaths {
- - -
500  INI_ONE_LEVEL_ONLY = 2,
-
503  INI_NO_SECTIONS = 3
-
506 };
-
507 
-
508 
-
512 enum IniMultiline {
- - - -
522  INI_NO_MULTILINE = 3
-
524 };
-
525 
-
526 
-
530 static const IniFormat INI_DEFAULT_FORMAT = _LIBCONFINI_DEFAULT_FORMAT_;
+
477 enum IniCommentMarker {
+ +
480  INI_ONLY_COMMENT = 1,
+ + +
486 };
+
487 
+
488 
+
492 enum IniSectionPaths {
+ + +
499  INI_ONE_LEVEL_ONLY = 2,
+
502  INI_NO_SECTIONS = 3
+
505 };
+
506 
+
507 
+
511 enum IniMultiline {
+ + + +
521  INI_NO_MULTILINE = 3
+
523 };
+
524 
+
525 
+
529 static const IniFormat INI_DEFAULT_FORMAT = { INI_EQUALS, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false };
+
530 
531 
-
532 
-
537 /* All fields are set to `0` here. */
-
538 static const IniFormat INI_UNIXLIKE_FORMAT = _LIBCONFINI_UNIXLIKE_FORMAT_;
+
536 /* All fields are set to `0` here. */
+
537 static const IniFormat INI_UNIXLIKE_FORMAT = { INI_ANY_SPACE, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false };
+
538 
539 
-
540 
-
549 extern bool INI_GLOBAL_LOWERCASE_MODE;
-
550 #define __INI_GLOBAL_LOWERCASE_MODE \
-
551  _LIBCONFINI_WARNING_("global variable `INI_GLOBAL_LOWERCASE_MODE` is deprecated") \
-
552  INI_GLOBAL_LOWERCASE_MODE
+
548 extern bool INI_GLOBAL_LOWERCASE_MODE;
+
549 #define __INI_GLOBAL_LOWERCASE_MODE \
+
550  _LIBCONFINI_WARNING_("global variable `INI_GLOBAL_LOWERCASE_MODE` is deprecated") \
+
551  INI_GLOBAL_LOWERCASE_MODE
+
552 
553 
-
554 
-
558 extern char * INI_GLOBAL_IMPLICIT_VALUE;
+
557 extern char * INI_GLOBAL_IMPLICIT_VALUE;
+
558 
559 
-
560 
-
564 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
+
563 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
+
564 
565 
566 
-
567 
-
568 /* CLEAN THE PRIVATE ENVIRONMENT */
+
567 /* CLEAN THE PRIVATE ENVIRONMENT */
+
568 
569 
-
570 
-
571 #undef _LIBCONFINI_UNIXLIKE_FORMAT_
-
572 #undef _LIBCONFINI_DEFAULT_FORMAT_
-
573 #undef _LIBCONFINI_INIFORMAT_TYPE_
-
574 #undef __INIFORMAT_TABLE_CB_ZERO__
-
575 #undef __INIFORMAT_TABLE_CB_DEFAULT__
-
576 #undef __INIFORMAT_TABLE_CB_FIELDS__
+
570 #undef _LIBCONFINI_UNIXLIKE_FORMAT_
+
571 #undef _LIBCONFINI_DEFAULT_FORMAT_
+
572 #undef _LIBCONFINI_INIFORMAT_TYPE_
+
573 #undef __INIFORMAT_TABLE_CB_ZERO__
+
574 #undef __INIFORMAT_TABLE_CB_DEFAULT__
+
575 #undef __INIFORMAT_TABLE_CB_FIELDS__
+
576 
577 
578 
-
579 
-
580 /* END OF `_LIBCONFINI_HEADER_` */
+
579 /* END OF `__CONFINI_H__` */
+
580 
581 
-
582 
-
583 #ifdef __cplusplus
-
584 }
-
585 #endif
+
582 #ifdef __cplusplus
+
583 }
+
584 #endif
+
585 
586 
-
587 
-
588 #endif
+
587 #endif
+
588 
589 
-
590 
-
591 /* EOF */
-
592 
-
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:4997
-
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:163
-
double(*const ini_get_float)(const char *ini_string)
Legacy support for parsing a double data type – please do not use this function: use ini_get_double()...
Definition: confini.c:5509
-
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5518
-
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2419
-
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:4917
-
void ini_global_set_lowercase_mode(const bool lowercase)
Set the value of the global variable INI_GLOBAL_LOWERCASE_MODE.
Definition: confini.c:5134
-
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4255
-
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:154
-
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5161
-
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4374
-
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:5516
-
uint_least32_t IniFormatNum
The unique ID of an INI format (24-bit maximum)
Definition: confini.h:148
-
IniSectionPaths
Possible values of IniFormat::section_paths.
Definition: confini.h:488
-
@ INI_ABSOLUTE_ONLY
Definition: confini.h:492
-
@ INI_ONE_LEVEL_ONLY
Definition: confini.h:495
-
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:489
-
@ INI_NO_SECTIONS
Definition: confini.h:498
-
ConfiniInterruptNo
Error codes.
Definition: confini.h:405
-
@ CONFINI_ENOMEM
Definition: confini.h:413
-
@ CONFINI_FEINTR
Definition: confini.h:410
-
@ CONFINI_IINTR
Definition: confini.h:408
-
@ CONFINI_EFBIG
Definition: confini.h:419
-
@ CONFINI_EROADDR
Definition: confini.h:420
-
@ CONFINI_EOOR
Definition: confini.h:415
-
@ CONFINI_EIO
Definition: confini.h:414
-
@ CONFINI_SUCCESS
Definition: confini.h:406
-
@ CONFINI_EBADF
Definition: confini.h:417
-
@ CONFINI_ENOENT
Definition: confini.h:412
-
IniNodeType
INI node types and possible values of IniDispatch::type.
Definition: confini.h:436
-
@ INI_DISABLED_SECTION
Definition: confini.h:448
-
@ INI_COMMENT
Definition: confini.h:445
-
@ INI_SECTION
Definition: confini.h:444
-
@ INI_VALUE
Definition: confini.h:439
-
@ INI_INLINE_COMMENT
Definition: confini.h:446
-
@ INI_KEY
Definition: confini.h:443
-
@ INI_DISABLED_KEY
Definition: confini.h:447
-
@ INI_UNKNOWN
Definition: confini.h:437
+
590 /* EOF */
+
591 
+
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:5187
+
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:162
+
double(*const ini_get_float)(const char *ini_string)
Legacy support for parsing a double data type – please do not use this function: use ini_get_double()...
Definition: confini.c:5716
+
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5725
+
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2574
+
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:5107
+
void ini_global_set_lowercase_mode(const bool lowercase)
Set the value of the global variable INI_GLOBAL_LOWERCASE_MODE.
Definition: confini.c:5327
+
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4433
+
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:153
+
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5356
+
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4554
+
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:5723
+
uint_least32_t IniFormatNum
The unique ID of an INI format (24-bit maximum)
Definition: confini.h:147
+
IniSectionPaths
Possible values of IniFormat::section_paths.
Definition: confini.h:487
+
@ INI_ABSOLUTE_ONLY
Definition: confini.h:491
+
@ INI_ONE_LEVEL_ONLY
Definition: confini.h:494
+
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:488
+
@ INI_NO_SECTIONS
Definition: confini.h:497
+
ConfiniInterruptNo
Error codes.
Definition: confini.h:404
+
@ CONFINI_ENOMEM
Definition: confini.h:412
+
@ CONFINI_FEINTR
Definition: confini.h:409
+
@ CONFINI_IINTR
Definition: confini.h:407
+
@ CONFINI_EFBIG
Definition: confini.h:418
+
@ CONFINI_EROADDR
Definition: confini.h:419
+
@ CONFINI_EOOR
Definition: confini.h:414
+
@ CONFINI_EIO
Definition: confini.h:413
+
@ CONFINI_SUCCESS
Definition: confini.h:405
+
@ CONFINI_EBADF
Definition: confini.h:416
+
@ CONFINI_ENOENT
Definition: confini.h:411
+
IniNodeType
INI node types and possible values of IniDispatch::type.
Definition: confini.h:435
+
@ INI_DISABLED_SECTION
Definition: confini.h:447
+
@ INI_COMMENT
Definition: confini.h:444
+
@ INI_SECTION
Definition: confini.h:443
+
@ INI_VALUE
Definition: confini.h:438
+
@ INI_INLINE_COMMENT
Definition: confini.h:445
+
@ INI_KEY
Definition: confini.h:442
+
@ INI_DISABLED_KEY
Definition: confini.h:446
+
@ INI_UNKNOWN
Definition: confini.h:436
struct IniDispatch IniDispatch
Dispatch of a single INI node.
-
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3083
-
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3271
-
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5309
-
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4518
-
IniCommentMarker
Possible values of IniFormat::semicolon_marker and IniFormat::hash_marker (i.e., meaning of /\s+;/ an...
Definition: confini.h:473
-
@ INI_IGNORE
Definition: confini.h:477
-
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:474
-
@ INI_ONLY_COMMENT
Definition: confini.h:476
-
@ INI_IS_NOT_A_MARKER
Definition: confini.h:480
-
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:533
-
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3454
-
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:4838
-
bool ini_array_match(const char *const ini_string_a, const char *const ini_string_b, const char delimiter, const IniFormat format)
Compare two INI arrays and check whether they match.
Definition: confini.c:3662
-
IniFormat ini_ntof(const IniFormatNum format_id)
Construct a new IniFormat according to an IniFormatNum.
Definition: confini.c:5201
-
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:2989
-
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3170
-
long long int(*const ini_get_llint)(const char *ini_string)
Pointer to atoll()
Definition: confini.c:5491
-
int(* IniSubstrHandler)(const char *ini_string, size_t fragm_offset, size_t fragm_length, size_t fragm_num, IniFormat format, void *user_data)
Callback function for handling a selected fragment of an INI string.
Definition: confini.h:185
-
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4616
-
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:525
-
double(*const ini_get_double)(const char *ini_string)
Pointer to atof()
Definition: confini.c:5493
-
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4047
+
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3241
+
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3429
+
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5511
+
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4701
+
IniCommentMarker
Possible values of IniFormat::semicolon_marker and IniFormat::hash_marker (i.e., meaning of /\s+;/ an...
Definition: confini.h:472
+
@ INI_IGNORE
Definition: confini.h:476
+
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:473
+
@ INI_ONLY_COMMENT
Definition: confini.h:475
+
@ INI_IS_NOT_A_MARKER
Definition: confini.h:479
+
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:532
+
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3614
+
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:5028
+
bool ini_array_match(const char *const ini_string_a, const char *const ini_string_b, const char delimiter, const IniFormat format)
Compare two INI arrays and check whether they match.
Definition: confini.c:3825
+
IniFormat ini_ntof(const IniFormatNum format_id)
Construct a new IniFormat according to an IniFormatNum.
Definition: confini.c:5398
+
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:3147
+
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3328
+
long long int(*const ini_get_llint)(const char *ini_string)
Pointer to atoll()
Definition: confini.c:5698
+
int(* IniSubstrHandler)(const char *ini_string, size_t fragm_offset, size_t fragm_length, size_t fragm_num, IniFormat format, void *user_data)
Callback function for handling a selected fragment of an INI string.
Definition: confini.h:184
+
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4799
+
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:524
+
double(*const ini_get_double)(const char *ini_string)
Pointer to atof()
Definition: confini.c:5700
+
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4217
struct IniStatistics IniStatistics
Global statistics about an INI file.
-
int ini_get_bool(const char *const simple_string, const int when_fail)
Check whether a simple string matches one of the booleans listed in the private constant INI_BOOLEANS...
Definition: confini.c:5243
-
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:3906
-
IniMultiline
Possible values of IniFormat::multiline_nodes.
Definition: confini.h:507
-
@ INI_NO_MULTILINE
Definition: confini.h:517
-
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:508
-
@ INI_BUT_COMMENTS
Definition: confini.h:511
-
@ INI_BUT_DISABLED_AND_COMMENTS
Definition: confini.h:514
-
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys (default value: 0)
Definition: confini.c:5520
-
IniDelimiters
Common array and key-value delimiters (but a delimiter may also be any other ASCII character not pres...
Definition: confini.h:457
-
@ INI_COLON
Definition: confini.h:462
-
@ INI_EQUALS
Definition: confini.h:461
-
@ INI_ANY_SPACE
Definition: confini.h:458
-
@ INI_COMMA
Definition: confini.h:464
-
@ INI_DOT
Definition: confini.h:463
-
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5487
-
long int(*const ini_get_lint)(const char *ini_string)
Pointer to atol()
Definition: confini.c:5489
-
int(* IniStrHandler)(char *ini_string, size_t string_length, size_t string_num, IniFormat format, void *user_data)
Callback function for handling an INI string belonging to a sequence of INI strings.
Definition: confini.h:173
-
IniFormatNum ini_fton(const IniFormat format)
Calculate the IniFormatNum of an IniFormat.
Definition: confini.c:5180
-
Dispatch of a single INI node.
Definition: confini.h:132
-
size_t at_len
Definition: confini.h:140
-
size_t d_len
Definition: confini.h:138
-
char * data
Definition: confini.h:135
-
size_t v_len
Definition: confini.h:139
-
size_t dispatch_id
Definition: confini.h:141
-
uint_least8_t type
Definition: confini.h:134
-
char * value
Definition: confini.h:136
-
const IniFormat format
Definition: confini.h:133
-
const char * append_to
Definition: confini.h:137
-
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:116
-
Global statistics about an INI file.
Definition: confini.h:122
-
const IniFormat format
Definition: confini.h:123
-
const size_t members
Definition: confini.h:125
-
const size_t bytes
Definition: confini.h:124
+
int ini_get_bool(const char *const simple_string, const int when_fail)
Check whether a simple string matches one of the booleans listed in the private constant INI_BOOLEANS...
Definition: confini.c:5442
+
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4071
+
IniMultiline
Possible values of IniFormat::multiline_nodes.
Definition: confini.h:506
+
@ INI_NO_MULTILINE
Definition: confini.h:516
+
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:507
+
@ INI_BUT_COMMENTS
Definition: confini.h:510
+
@ INI_BUT_DISABLED_AND_COMMENTS
Definition: confini.h:513
+
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys (default value: 0)
Definition: confini.c:5727
+
IniDelimiters
Common array and key-value delimiters (but a delimiter may also be any other ASCII character not pres...
Definition: confini.h:456
+
@ INI_COLON
Definition: confini.h:461
+
@ INI_EQUALS
Definition: confini.h:460
+
@ INI_ANY_SPACE
Definition: confini.h:457
+
@ INI_COMMA
Definition: confini.h:463
+
@ INI_DOT
Definition: confini.h:462
+
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5694
+
long int(*const ini_get_lint)(const char *ini_string)
Pointer to atol()
Definition: confini.c:5696
+
int(* IniStrHandler)(char *ini_string, size_t string_length, size_t string_num, IniFormat format, void *user_data)
Callback function for handling an INI string belonging to a sequence of INI strings.
Definition: confini.h:172
+
IniFormatNum ini_fton(const IniFormat format)
Calculate the IniFormatNum of an IniFormat.
Definition: confini.c:5375
+
Dispatch of a single INI node.
Definition: confini.h:131
+
size_t at_len
Definition: confini.h:139
+
size_t d_len
Definition: confini.h:137
+
char * data
Definition: confini.h:134
+
size_t v_len
Definition: confini.h:138
+
size_t dispatch_id
Definition: confini.h:140
+
uint_least8_t type
Definition: confini.h:133
+
char * value
Definition: confini.h:135
+
const IniFormat format
Definition: confini.h:132
+
const char * append_to
Definition: confini.h:136
+
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:115
+
Global statistics about an INI file.
Definition: confini.h:121
+
const IniFormat format
Definition: confini.h:122
+
const size_t members
Definition: confini.h:124
+
const size_t bytes
Definition: confini.h:123