Skip to content
/ INIreader Public
forked from benhoyt/inih

Simple .INI file reader in C++ ready to be embedded into any project.

License

Notifications You must be signed in to change notification settings

wme7/INIreader

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

INIreader

INIreader is a simple .INI file parser written in C++. It's two pages of code, and it was designed to be minimalistic and simple, so that is easy to make it part of any other C++ project. 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, ini_parse_string() to parse data from a string, or ini_parse_stream() to parse using a custom fgets-style reader function for custom I/O.

Compile-time options

You can control various aspects of inih using preprocessor defines:

Syntax options

  • Multi-line entries: By default, inih supports multi-line entries in the style of Python's ConfigParser. To disable, add -DINI_ALLOW_MULTILINE=0.
  • UTF-8 BOM: By default, inih allows a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of INI files. To disable, add -DINI_ALLOW_BOM=0.
  • Inline comments: By default, inih allows inline comments with the ; 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.
  • Start-of-line comments: By default, inih allows both ; and # to start a comment at the beginning of a line. You can override this by changing INI_START_COMMENT_PREFIXES.
  • Allow no value: By default, inih treats a name with no value (no = or : on the line) as an error. To allow names with no values, add -DINI_ALLOW_NO_VALUE=1, and inih will call your handler function with value set to NULL.

Parsing options

  • Stop on first error: By default, inih keeps parsing the rest of the file after an error. To stop parsing on the first error, add -DINI_STOP_ON_FIRST_ERROR=1.
  • Report line numbers: By default, the ini_handler callback doesn't receive the line number as a parameter. If you need that, add -DINI_HANDLER_LINENO=1.
  • Call handler on new section: By default, inih only calls the handler on each name=value pair. To detect new sections (e.g., the INI file has multiple sections with the same name), add -DINI_CALL_HANDLER_ON_NEW_SECTION=1. Your handler function will then be called each time a new section is encountered, with section set to the new section name but name and value set to NULL.

Memory options

  • Stack vs heap: By default, inih creates a fixed-sized line buffer on the stack. To allocate on the heap using malloc instead, specify -DINI_USE_STACK=0.
  • Maximum line length: The default maximum line length (for stack or heap) is 200 bytes. To override this, add something like -DINI_MAX_LINE=1000. Note that INI_MAX_LINE must be 3 more than the longest line (due to \r, \n, and the NUL).
  • Initial malloc size: INI_INITIAL_ALLOC specifies the initial malloc size when using the heap. It defaults to 200 bytes.
  • Allow realloc: By default when using the heap (-DINI_USE_STACK=0), inih allocates a fixed-sized buffer of INI_INITIAL_ALLOC bytes. To allow this to grow to INI_MAX_LINE bytes, doubling if needed, set -DINI_ALLOW_REALLOC=1.

Simple C++ example

#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";
              
    std::cout<<"Found sections and fields:"<<std::endl;
    std::set<std::string> sections = reader.GetSections();
    for(std::set<std::string>::iterator sectionsIt = sections.begin();
        sectionsIt!=sections.end();
        sectionsIt++)
    {
        std::cout << "  [" << *sectionsIt << "]: ";
        std::set<std::string> fields = reader.GetFields(*sectionsIt);
        for(std::set<std::string>::iterator fieldsIt = fields.begin();
            fieldsIt!=fields.end();
            fieldsIt++)
        {
            if(fieldsIt!=fields.begin())
                std::cout << ", ";
            std::cout << *fieldsIt;
        }
        std::cout << std::endl;
    }
    
    return 0;
}

Differences from ConfigParser

Some differences between inih and Python's ConfigParser standard library module:

  • INI name=value pairs given above any section headers are treated as valid items with no section (section name is an empty string). In ConfigParser having no section is an error.
  • Line continuations are handled with leading whitespace on continued lines (like ConfigParser). However, instead of concatenating continued lines together, they are treated as separate values for the same key (unlike ConfigParser).

Platform-specific notes

  • Windows/Win32 uses UTF-16 filenames natively, so to handle Unicode paths you need to call _wfopen() to open a file and then ini_parse_file() to parse it; inih does not include wchar_t or Unicode handling.

About

Simple .INI file reader in C++ ready to be embedded into any project.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages

  • C++ 100.0%