All I was after was a simple .INI file reader in C or C++. You know, to parse
name=value lines for config files. We needed it for an embedded Linux project, so it had to be small, portable and only dependent on the C and C++ standard libraries.
Maybe it’s my embedded background that makes me defensive about my mild case of Not-Invented-Here syndrome. Then again, perhaps I’m in good company.
But surely there are tons of INI parsing libraries around, right? Well, kind of.
I found no fewer than 15 in under an hour. But why is it that things like this are either way off the mark (bloated or non-portable) or they’re very close, but just not quite what you want?
Below is the list of INI file readers that I found, from bad to better. Some of the ones that weren’t for me might well suit your application, so treat this as something of a non-exhaustive list of INI file readers:
Not for me
- SDL_Config: Rather bloated … somehow 246KB of source code just to read an INI file doesn’t do it for me. I also admit to being a bit icked out by five levels of pointer indirection, for example:
file->internal_file-> global_group.multi_value_iterator = ...
- ini.c by Carey Bloodworth: Small and in C, but has a funny API and is ripe with buffer overrun goodness.
- GetPrivateProfileString API: Fine API, but of course Win32 only.
- CIniReader by Xiangxiong Jian: C++ class, nice and simple, but Win32 only (uses
- CIniFile by Ludvik Jerabek: C++ class, but uses loads of non-portable MFC helper classes. Update: Ludvik’s now added a portable version to this page.
Half way there
- SimpleIni by Brodie Thiesfield: C++, cross platform, and not really bad, but it just shows that “simple” is in the eye of the beholder. Does one really want 110KB of heavy duty, template-driven C++ code just to read an INI file?
- Config by freejack: Tantalising … a C++ class with a nice API, only 5KB of code (as it should be), and optional environment variable expansion. The problem? What it parses are not quite INI files, but his own special “structured config files”. Which is all very nice, but not exactly INI-compatible. (Admittedly this could easily be hacked into an INI reader.)
- Boost.Program_options: C++, and not bad code, but it’s more of a fully-fledged “program configuration library” than just an INI file reader. Plus, we weren’t yet sure we wanted a dependency on Boost.
- CIniFile by Silviu Simen: C++ class, a little better, but relies on the Boost.Spirit parsing library.
- M’s INI parser: C++, not bad, small, portable and uses the STL, but relies on the re2c scanner generator, giving it another dependency and making the code harder to read (and modify).
So very close
- minIni by CompuPhase: So very close, does just what you want (also writes INI files), and in only 17KB of portable C source, great for embedded systems … but re-reading the INI file for every
name=valuepair you need somehow just doesn’t sit right.
- CDataFile by Gary McNickle: This one looks decent — small, C++, uses the STL instead of MFC or its own fancy dictionary type … I probably would have used this had I seen it sooner.
- libinifile by Anders Lövgren: This one’s quite good too. Minimal, portable, low memory footprint, but a slightly unusual API (partly to give it the low memory footprint). I might well have used this one too, had I found it sooner.
- libini by Simon White: Plain C, SWIGgable, fairly small, though has a bit of an odd API (and I’m struggling to see why a simple INI file reader needs a 665KB configuration script :-).
- iniParser by Nicolas Devillard: This is the one we ended up using. Small (about 32KB of source) and fast. The only minor drawback is that it implements its own dictionary type in C, and we’re using the STL which already has one. (Still, in C, what else can you do?) Also, it looks like it’s been around forever and is well tested.
INI Not Invented Here (INIH)
Of course, in the time it took to investigate all these, I could have easily written my own. And, being unable to help myself, I did. :-) So I present you with my own offering: INI Not Invented Here, a.k.a. INIH or simply
It contains a small C function,
ini_parse(), that parses an INI file and executes the given callback function for each
name=value pair parsed (think SAX).
The reason I used the callback style is so you don’t have to load the whole file into memory if you don’t need to — good for embedded systems. Plus, I wanted to be able to use the parser easily in C, but not implement a dictionary-like structure in C.
For a more user-friendly, lookup style API if you’re using C++, I’ve wrapped
ini_parse() in a class called
INIReader, which has
GetInteger() methods (all I needed). And it’s easy to sub-class
INIReader if you need fancier
Show us the code
UPDATE: I’ve moved the code from here to its own Google Code project at http://code.google.com/p/inih/ — enjoy!
26 February 2009 by Ben 44 comments