libconfini {#readme}
====================

**libconfini** is the ultimate and most consistent INI file parser library
written in C. It focuses on standardization and parsing exactness and is at ease
with almost every type of file containing key/value pairs.

The library is fast and suitable for embedded systems. Its algorithms are
written from scratch and do not depend on any external library, except for the C
standard headers **stdio.h**, **stdlib.h** and **stdint.h**.

Rather than storing the parsed data, **libconfini** gives the developer the
freedom to choose what to do with them through a custom callback invoked for
each INI node read. The API has been designed to be powerful, flexible and
simple to use.

With **libconfini** you will find in INI files the same serialization power you
would normally find in other heavily structured formats (such as JXON, YAML,
TOML), but with the advantage of using the most human-readable configuration
format ever invented (thanks to their informal status, INI files are indeed more
fluid and human-readable than formats explicitly designed with this purpose,
such as YAML and TOML).


Features
--------

* Typed data support (each value can be parsed as a boolean, a number, a string,
  an array)
* Single/double quotes support in _Bash single quotes style_
* Multi-line support
* Comment support
* Disabled entry support
* INI sectioning support (single-level sectioning, as in `[foo]`; absolute
  nesting, as in `[foo.bar]`; relative nesting, as in `[.bar]`)
* Automatic sanitization of values, key names and section paths
* Comparison functions designed just for INI source code (capable, for example,
  to recognize the equality between <code>"Hello world"</code> and
  <code>"He"l'lo' world</code>, or between <code>foo bar</code> and
  <code>foo&nbsp;&nbsp;&nbsp;&nbsp;bar</code>)
* Callback pattern
* Thread-safety (each parsing process is fully reentrant)
* Highly optimized code (single memory allocation for each parsing, heuristic
  programming, optimization flags)
* Function modularity (each public function is independent from all other public
  functions)
* K.I.S.S. (no public functions are automatically invoked during the parsing --
  for example, not even single/double quotes are automatically removed from
  values unless the developer explicitly decides to use the formatting functions
  provided by the API)


Sample usage
------------

log.ini:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.ini}
[users]
have_visited = ronnie, lilly82, robrob

[last_update]
date = 12.03.2017
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

example.c:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
#include <confini.h>

static int callback (IniDispatch * disp, void * v_other) {

  #define IS_KEY(SECTION,KEY) \
    (ini_array_match(SECTION, disp->append_to, '.', disp->format) && \
    ini_string_match_ii(KEY, disp->data, disp->format))

  if (disp->type == INI_KEY) {

    if (IS_KEY("users", "have_visited")) {

      /* No need to parse this field as an array right now */
      printf("People who have visited: %s\n", disp->value);

    } else if (IS_KEY("last_update", "date")) {

      printf("Last update: %s\n", disp->value);

    }
  }

  #undef IS_KEY

  return 0;

}

int main () {

  if (load_ini_path("log.ini", INI_DEFAULT_FORMAT, NULL, callback, NULL)) {

    fprintf(stderr, "Sorry, something went wrong :-(\n");
    return 1;

  }

  return 0;

}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Output:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
People who have visited: ronnie, lilly82, robrob
Last update: 12.03.2017
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For more details, please read the [Library Functions Manual][1]
(`man libconfini` -- a standalone HTML version is available [here][2]) and the
manual of the header file (`man confini.h`). The code is available on
[GitHub][3] under [madmurphy/libconfini][4]).


Installation
------------

Despite the small footprint, **libconfini** has been conceived as a shared
library (but it may be used as a static library as well).

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

~~~~~~~~~~~~
./configure
make
make install
~~~~~~~~~~~~

For a minimum installation without man pages and examples, use `./configure
--disable-man --disable-examples`.

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

If you are using Microsoft Windows, a batch script for compiling **libconfini**
under [MinGW][5] without Autotools is available (`mgwmake.bat`). If you are
interested in using Autotools for compiling **libconfini** under Microsoft
Windows, you can integrate MinGW with [MSYS][6]. Alternatively, [an unofficial
port][7] of **libconfini** for [Cygwin][8] is available as well.

For further information, see [INSTALL][9].


Free software
-------------

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


[1]: https://madmurphy.github.io/libconfini/html/libconfini.html
[2]: https://madmurphy.github.io/libconfini/manual.html
[3]: https://github.com/
[4]: https://github.com/madmurphy/libconfini
[5]: http://www.mingw.org/
[6]: http://www.mingw.org/wiki/MSYS
[7]: https://github.com/fd00/yacp/tree/master/libconfini
[8]: https://www.cygwin.com/
[9]: https://github.com/madmurphy/libconfini/blob/master/INSTALL
[10]: https://github.com/madmurphy/libconfini/blob/master/COPYING

