1+ /* *
2+ @brief INI Parser Library
3+
4+ A lightweight, single-header, speed and safety focused INI file parsing library written in C with C++ compatibility. Designed for simplicity and portability, this parser provides a low-footprint solution to decode INI format.
5+
6+ @date 2025-05-12
7+ @version 1.0
8+ @author Eray Ozturk | erayozturk1@gmail.com
9+ @url github.com/diffstorm
10+ @license MIT License
11+ */
12+ #include " ini_parser.h"
13+ #include < iostream>
14+ #include < map>
15+ #include < vector>
16+ #include < cstring>
17+
18+ // Structure to collect parsing results
19+ typedef struct
20+ {
21+ std::map<std::string, std::map<std::string, std::string>> sections;
22+ std::vector<std::string> comments;
23+ std::vector<std::string> errors;
24+ std::string current_section;
25+ } ParserState;
26+
27+ // Handler function prototype
28+ bool parsing_handler (ini_eventtype_t type,
29+ const char *section,
30+ const char *key,
31+ const char *value,
32+ void *userdata);
33+
34+ int main ()
35+ {
36+ const char *ini_content =
37+ " ; Main configuration file\n "
38+ " [network]\n "
39+ " host = 127.0.0.1\n "
40+ " port = 8080\n "
41+ " [database]\n "
42+ " user = admin\n "
43+ " pass = secret\n "
44+ " [invalid_section\n " // Missing closing bracket
45+ " key = value\n " ;
46+ ParserState state;
47+ state.current_section = INI_LINE_SECTION;
48+ size_t length = strlen (ini_content);
49+ bool success = ini_parse_stream (ini_content, length, parsing_handler, &state);
50+ // Display results
51+ std::cout << " Parsing " << (success ? " completed" : " aborted" ) << " \n\n " ;
52+ std::cout << " Comments (" << state.comments .size () << " ):\n " ;
53+
54+ for (const auto &comment : state.comments )
55+ {
56+ std::cout << " " << comment << " \n " ;
57+ }
58+
59+ std::cout << " \n Errors (" << state.errors .size () << " ):\n " ;
60+
61+ for (const auto &error : state.errors )
62+ {
63+ std::cout << " " << error << " \n " ;
64+ }
65+
66+ std::cout << " \n Parsed data:\n " ;
67+
68+ for (const auto & [section, values] : state.sections )
69+ {
70+ std::cout << " [" << section << " ]\n " ;
71+
72+ for (const auto & [key, val] : values)
73+ {
74+ std::cout << " " << key << " = " << val << " \n " ;
75+ }
76+ }
77+
78+ return 0 ;
79+ }
80+
81+ bool parsing_handler (ini_eventtype_t type,
82+ const char *section,
83+ const char *key,
84+ const char *value,
85+ void *userdata)
86+ {
87+ ParserState *state = static_cast <ParserState *>(userdata);
88+
89+ switch (type)
90+ {
91+ case INI_EVENT_SECTION:
92+ state->current_section = section;
93+ state->sections [section]; // Create empty section
94+ break ;
95+
96+ case INI_EVENT_KEY_VALUE:
97+ {
98+ const char *actual_section = state->current_section .c_str ();
99+ state->sections [actual_section][key] = value;
100+ break ;
101+ }
102+
103+ case INI_EVENT_COMMENT:
104+ state->comments .push_back (value);
105+ break ;
106+
107+ case INI_EVENT_ERROR:
108+ state->errors .push_back (value);
109+ return false ; // Abort parsing on first error
110+
111+ default :
112+ break ;
113+ }
114+
115+ return true ;
116+ }
0 commit comments