commit | 65a38ce34abe8f5835efe1e2aecfad77e97ac28e | [log] [tgz] |
---|---|---|
author | Jan Tilly <jantilly@gmail.com> | Mon Jan 18 13:32:22 2016 -0500 |
committer | Jan Tilly <jantilly@gmail.com> | Mon Jan 18 13:32:22 2016 -0500 |
tree | 7f428c35a45838cdc9b9f56298fc67d7dbf3a67d | |
parent | 4b10c654051a86556dfdb634c891b6c3224c4109 [diff] |
Simple C++ example without linking against library.
inih (INI Not Invented Here) is a simple .INI file parser written in C. It‘s only a couple of pages of code, and it was designed to be small and simple, so it’s good for embedded systems. It‘s also more or less compatible with Python’s ConfigParser style of .INI files, including RFC 822-style multi-line syntax and name: value
entries.
To use it, just give ini_parse()
an INI file, and it will call a callback for every name=value
pair parsed, giving you strings for the section, name, and value. It's done this way (“SAX style”) because it works well on low-memory embedded systems, but also because it makes for a KISS implementation.
You can also call ini_parse_file()
to parse directly from a FILE*
object, or ini_parse_stream()
to parse using a custom reader to implement string-based or other custom I/O (see example code).
Download a release, browse the source, or read about how to use inih in a DRY style with X-Macros.
-DINI_ALLOW_MULTILINE=0
.-DINI_ALLOW_BOM=0
.;
character. To disable, add -DINI_ALLOW_INLINE_COMMENTS=0
. You can also specify which character(s) start an inline comment using INI_INLINE_COMMENT_PREFIXES
.malloc
instead, specify -DINI_USE_STACK=0
.-DINI_STOP_ON_FIRST_ERROR=1
.-DINI_MAX_LINE=1000
.#include <stdio.h> #include <stdlib.h> #include <string.h> #include "../ini.h" typedef struct { int version; const char* name; const char* email; } configuration; static int handler(void* user, const char* section, const char* name, const char* value) { configuration* pconfig = (configuration*)user; #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 if (MATCH("protocol", "version")) { pconfig->version = atoi(value); } else if (MATCH("user", "name")) { pconfig->name = strdup(value); } else if (MATCH("user", "email")) { pconfig->email = strdup(value); } else { return 0; /* unknown section/name, error */ } return 1; } int main(int argc, char* argv[]) { configuration config; if (ini_parse("test.ini", handler, &config) < 0) { printf("Can't load 'test.ini'\n"); return 1; } printf("Config loaded from 'test.ini': version=%d, name=%s, email=%s\n", config.version, config.name, config.email); return 0; }
If you're into C++ and the STL, there is also an easy-to-use INIReader class that stores values in a map
and lets you Get()
them:
#include <iostream> #include "INIReader.h" int main() { INIReader reader("../examples/test.ini"); if (reader.ParseError() < 0) { std::cout << "Can't load 'test.ini'\n"; return 1; } std::cout << "Config loaded from 'test.ini': version=" << reader.GetInteger("protocol", "version", -1) << ", name=" << reader.Get("user", "name", "UNKNOWN") << ", email=" << reader.Get("user", "email", "UNKNOWN") << ", pi=" << reader.GetReal("user", "pi", -1) << ", active=" << reader.GetBoolean("user", "active", true) << "\n"; return 0; }
This simple C++ API works fine, but it‘s not very fully-fledged. I’m not planning to work more on the C++ API at the moment, so if you want a bit more power (for example GetSections()
and GetFields()
functions), see these forks:
Some differences between inih and Python's ConfigParser standard library module: