minIni - a minimal INI file parser
minIni is a programmer's library to read and write "INI" files in embedded systems. minIni takes little resources and can be configured for various kinds of file I/O libraries. minIni provides functionality for reading, writing and deleting keys from an INI file, all in less than 500 lines of (commented) source code.
The principal purpose for minIni is to be used on embedded systems that run on an RTOS (or even without any operating system). minIni requires that such a system provides a kind of storeage and file I/O system, but it does not require that this file I/O system is compatible with the standard C/C++ library --indeed, the standard library is often too big and resource-hungry for embedded systems.
If you wish to know more about minIni, please see the manual that is in the source code archive.
Downloads & license
- minIni 0.3 source archive (includes manual).
- Access to the most recent source code is available via Google project hosting
The minIni library is distributed under the zlib/libpng license, a liberal license that permits use in commercial projects.
INI file syntax
INI files have a simple syntax with name/value pairs in a plain text
file. The name must be unique (per section) and the value must fit on a single line.
INI files are commonly separated into sections --in minIni, this is
optional. A section is a name between square brackets, like "[Network]" in
the example below.
[Network] hostname=My Computer address=dhcp dns = 192.168.1.1
In the API and in this documentation, the "name" for a setting is denoted as the
key for the setting. The key and the value are separated by an equal
sign ("="). minIni supports the colon (":") as an alternative to the
equal sign for the key/value delimiter.
Leading a trailing spaces around values or key names are removed. If you need
to include leading and/or trailing spaces in a value, put the value between
double quotes. The ini_gets function (from the minIni library, see
the minIni manual) strips off the double quotes from the returned value.
minIni ignores spaces around the "=" or ":" delimiters, but it does not
ignore spaces between the brackets in a section name. In other words, it is best
not to put spaces behind the opening bracket "[" or before the closing bracket
"]" of a section name.
It is commonly advised to start comments with a semicolon (";") and to put
any comments on a line by their own. minIni does not treat lines that start
with a semicolon in a special way. That said, names of keys should not contain
start a semicolon and a line that starts with a semicolon will thereby not match
any valid key. Using a semicolon to add comments is therefore more a convention
than part of the INI file format.
Adapting minIni to a file system
The minIni library must be configured for a platform with the help of a so-
called "glue file". This glue file contains macros (and possibly functions) that
map file reading and writing functions used by the minIni library to those
provided by the operating system. The glue file must be called
"minGlue.h".
To get you started, the minIni distribution comes with the following example glue files:
-
a glue file that maps to the standard C/C++ library (specifically
the file I/O functions from the "
stdio" package), - a glue file for the EFS Library (EFSL),
- and a glue file for the FatFs and Tiny-FatFs libraries.
Multi-tasking
The minIni library does not have any global variables and it does not use any dynamically allocated memory. Yet, the library should not be considered "thread-safe" or re-entrant, because it implicitly uses a particular shared resource: the file system.
Multiple tasks reading from an INI file do not pose a problem. However, when one task is writing to an INI file, no other tasks should access this INI file --neither for reading, nor for writing. It might be easier, in the implementation, to serialize all accesses of the INI file.
The first advise in protecting resources from concurrent access in a multi-tasking environment is to avoid sharing resources between tasks. If only a single task uses a resource, no semaphore protection is necessary and no priority inversion or deadlock problems can occur. This advise also applies to the minIni library. If possible, make a single task the "owner" of the INI file and create a client/server architecture for other tasks to query and adjust settings.
If the INI file must be shared between tasks (and at least one of the tasks writes to the INI file), you need to write wrappers around the functions of the minIni library that block on a mutex or binary semaphore.
Acknowledgement
Back in 2003 I was maintaining an IDE (for the authoring language EGO), which stores project information in INI files. Some projects grew large and crossed the 32 kiB limit that Microsoft Windows 95 and Windows 98 (and Windows ME) imposed on INI files (and back then, we were not prepared to drop support for Windows 98 yet). So I picked up the source code from the article "Multiplatform .INI Files" by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal.
The comment at the start of my implementation of the code from Joseph Graf's article contains the note "This release comes close to a complete re-write". There were quite a few bugs in the original code. We also needed extensions such as deleting keys, and enumerating keys and sections, that the original code lacked.
In turn, minIni is derived from my re-write of the Joseph Graf's code --this time reducing of the interface (key and section enumeration was removed again), plus changes to increase the portability.
