libconfini
Yet another INI parser
confini.h
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
2 
16 #ifndef _LIBCONFINI_HEADER_
17 #define _LIBCONFINI_HEADER_
18 
19 
20 
21 #include <stdio.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 
25 
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 
32 
33 /* PRIVATE (HEADER-SCOPED) MACROS */
34 
35 
36 #define __INIFORMAT_TABLE_CB_FIELDS__(NAME, OFFSET, SIZE, DEFVAL) \
37  unsigned char NAME:SIZE;
38 #define __INIFORMAT_TABLE_CB_DEFAULT__(NAME, OFFSET, SIZE, DEFVAL) DEFVAL,
39 #define __INIFORMAT_TABLE_CB_ZERO__(NAME, OFFSET, SIZE, DEFVAL) 0,
40 #define _LIBCONFINI_INIFORMAT_TYPE_ \
41  struct IniFormat { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_FIELDS__) }
42 #define _LIBCONFINI_DEFAULT_FORMAT_ \
43  { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_DEFAULT__) }
44 #define _LIBCONFINI_UNIXLIKE_FORMAT_ \
45  { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_ZERO__) }
46 
47 
48 
49 /* PUBLIC MACROS */
50 
51 
56 /*
57  NOTE: The following table and the order of its rows **define** (and link
58  together) both the #IniFormat and #IniFormatNum data types declared in this
59  header
60 */
61 #define INIFORMAT_TABLE_AS(_____) /* IniFormat table *\
62 
63  NAME BIT SIZE DEFAULT
64  */\
65 _____( delimiter_symbol, 0, 7, INI_EQUALS ) \
66 _____( case_sensitive, 7, 1, false )/*
67  */\
68 _____( semicolon_marker, 8, 2, INI_DISABLED_OR_COMMENT ) \
69 _____( hash_marker, 10, 2, INI_DISABLED_OR_COMMENT ) \
70 _____( section_paths, 12, 2, INI_ABSOLUTE_AND_RELATIVE ) \
71 _____( multiline_nodes, 14, 2, INI_MULTILINE_EVERYWHERE )/*
72  */\
73 _____( no_single_quotes, 16, 1, false ) \
74 _____( no_double_quotes, 17, 1, false ) \
75 _____( no_spaces_in_names, 18, 1, false ) \
76 _____( implicit_is_not_empty, 19, 1, false ) \
77 _____( do_not_collapse_values, 20, 1, false ) \
78 _____( preserve_empty_quotes, 21, 1, false ) \
79 _____( disabled_after_space, 22, 1, false ) \
80 _____( disabled_can_be_implicit, 23, 1, false )
81 
82 
83 
87 #define INIFORMAT_HAS_NO_ESC(FORMAT) \
88  (FORMAT.multiline_nodes == INI_NO_MULTILINE && \
89  FORMAT.no_double_quotes && FORMAT.no_single_quotes)
90 
91 
92 
93 /* PUBLIC TYPEDEFS */
94 
95 
100 typedef _LIBCONFINI_INIFORMAT_TYPE_ IniFormat;
101 
102 
106 typedef struct IniStatistics {
107  const IniFormat format;
108  const size_t bytes;
109  const size_t members;
110 } IniStatistics;
111 
112 
116 typedef struct IniDispatch {
118  uint8_t type;
119  char * data;
120  char * value;
121  const char * append_to;
122  size_t d_len;
123  size_t v_len;
124  size_t at_len;
125  size_t dispatch_id;
126 } IniDispatch;
127 
128 
132 typedef uint32_t IniFormatNum;
133 
134 
138 typedef int (* IniStatsHandler) (
139  IniStatistics * statistics,
140  void * user_data
141 );
142 
143 
147 typedef int (* IniDispHandler) (
148  IniDispatch * dispatch,
149  void * user_data
150 );
151 
152 
157 typedef int (* IniStrHandler) (
158  char * ini_string,
159  size_t string_length,
160  size_t string_num,
161  IniFormat format,
162  void * user_data
163 );
164 
165 
169 typedef int (* IniSubstrHandler) (
170  const char * ini_string,
171  size_t fragm_offset,
172  size_t fragm_length,
173  size_t fragm_num,
174  IniFormat format,
175  void * user_data
176 );
177 
178 
179 
180 /* PUBLIC FUNCTIONS */
181 
182 
183 extern int strip_ini_cache (
184  register char * const ini_source,
185  const size_t ini_length,
186  const IniFormat format,
187  const IniStatsHandler f_init,
188  const IniDispHandler f_foreach,
189  void * const user_data
190 );
191 
192 
193 extern int load_ini_file (
194  FILE * const ini_file,
195  const IniFormat format,
196  const IniStatsHandler f_init,
197  const IniDispHandler f_foreach,
198  void * const user_data
199 );
200 
201 
202 extern int load_ini_path (
203  const char * const path,
204  const IniFormat format,
205  const IniStatsHandler f_init,
206  const IniDispHandler f_foreach,
207  void * const user_data
208 );
209 
210 
211 extern bool ini_string_match_ss (
212  const char * const simple_string_a,
213  const char * const simple_string_b,
214  const IniFormat format
215 );
216 
217 
218 extern bool ini_string_match_si (
219  const char * const simple_string,
220  const char * const ini_string,
221  const IniFormat format
222 );
223 
224 
225 extern bool ini_string_match_ii (
226  const char * const ini_string_a,
227  const char * const ini_string_b,
228  const IniFormat format
229 );
230 
231 
232 extern bool ini_array_match (
233  const char * const ini_string_a,
234  const char * const ini_string_b,
235  const char delimiter,
236  const IniFormat format
237 );
238 
239 
240 extern size_t ini_unquote (
241  char * const ini_string,
242  const IniFormat format
243 );
244 
245 
246 extern size_t ini_string_parse (
247  char * const ini_string,
248  const IniFormat format
249 );
250 
251 
252 extern size_t ini_array_get_length (
253  const char * const ini_string,
254  const char delimiter,
255  const IniFormat format
256 );
257 
258 
259 extern int ini_array_foreach (
260  const char * const ini_string,
261  const char delimiter,
262  const IniFormat format,
263  const IniSubstrHandler f_foreach,
264  void * const user_data
265 );
266 
267 
268 extern size_t ini_array_shift (
269  const char ** const ini_strptr,
270  const char delimiter,
271  const IniFormat format
272 );
273 
274 
275 extern size_t ini_array_collapse (
276  char * const ini_string,
277  const char delimiter,
278  const IniFormat format
279 );
280 
281 
282 extern char * ini_array_break (
283  char * const ini_string,
284  const char delimiter,
285  const IniFormat format
286 );
287 
288 
289 extern char * ini_array_release (
290  char ** const ini_strptr,
291  const char delimiter,
292  const IniFormat format
293 );
294 
295 
296 extern int ini_array_split (
297  char * const ini_string,
298  const char delimiter,
299  const IniFormat format,
300  const IniStrHandler f_foreach,
301  void * const user_data
302 );
303 
304 
305 extern void ini_global_set_lowercase_mode (
306  const bool lowercase
307 );
308 
309 
310 extern void ini_global_set_implicit_value (
311  char * const implicit_value,
312  const size_t implicit_v_len
313 );
314 
315 
316 extern IniFormatNum ini_fton (
317  const IniFormat format
318 );
319 
320 
321 extern IniFormat ini_ntof (
322  const IniFormatNum format_id
323 );
324 
325 
326 extern int ini_get_bool (
327  const char * const ini_string,
328  const int when_fail
329 );
330 
331 
332 
333 /* PUBLIC LINKS */
334 
335 
336 extern int (* const ini_get_int) (
337  const char * ini_string
338 );
339 
340 
341 extern long int (* const ini_get_lint) (
342  const char * ini_string
343 );
344 
345 
346 extern long long int (* const ini_get_llint) (
347  const char * ini_string
348 );
349 
350 
351 extern double (* const ini_get_double) (
352  const char * ini_string
353 );
354 
355 
360 #define ini_get_float \
361  _Pragma("GCC warning \"function `ini_get_float()` is deprecated for parsing a `double` data type; use `ini_get_double()` instead\"") \
362  ini_get_double
363 
364 
365 
366 /* PUBLIC CONSTANTS AND VARIABLES */
367 
368 
372 #define CONFINI_ERROR 252
373 
374 
379  CONFINI_SUCCESS = 0,
386  CONFINI_ENOMEM = 5,
390  CONFINI_EBADF = 8,
392  CONFINI_EFBIG = 9,
393  CONFINI_EROADDR = 10
394 };
395 
396 
400 enum IniNodeType {
401  INI_UNKNOWN = 0,
403  INI_VALUE = 1,
407  INI_KEY = 2,
410  INI_COMMENT = 4,
411  INI_INLINE_COMMENT = 5,
412  INI_DISABLED_KEY = 6,
415 };
416 
417 
426  INI_EQUALS = '=',
427  INI_COLON = ':',
428  INI_DOT = '.',
429  INI_COMMA = ','
430 };
431 
432 
438 enum IniCommentMarker {
441  INI_ONLY_COMMENT = 1,
442  INI_IGNORE = 2,
447 };
448 
449 
453 enum IniSectionPaths {
457  INI_ABSOLUTE_ONLY = 1,
460  INI_ONE_LEVEL_ONLY = 2,
463  INI_NO_SECTIONS = 3
466 };
467 
468 
472 enum IniMultiline {
476  INI_BUT_COMMENTS = 1,
482  INI_NO_MULTILINE = 3
484 };
485 
486 
491 
492 
497 /* All fields are set to `0` here. */
498 static const IniFormat INI_UNIXLIKE_FORMAT = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
499 
500 
506 extern bool INI_GLOBAL_LOWERCASE_MODE;
507 
508 
512 extern char * INI_GLOBAL_IMPLICIT_VALUE;
513 
514 
518 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
519 
520 
521 
522 /* CLEAN THE PRIVATE ENVIRONMENT */
523 
524 
525 #undef _LIBCONFINI_UNIXLIKE_FORMAT_
526 #undef _LIBCONFINI_DEFAULT_FORMAT_
527 #undef _LIBCONFINI_INIFORMAT_TYPE_
528 #undef __INIFORMAT_TABLE_CB_ZERO__
529 #undef __INIFORMAT_TABLE_CB_DEFAULT__
530 #undef __INIFORMAT_TABLE_CB_FIELDS__
531 
532 
533 
534 /* END OF `_LIBCONFINI_HEADER_` */
535 
536 
537 #ifdef __cplusplus
538 }
539 #endif
540 
541 
542 #endif
543 
544 
545 
546 /* EOF */
547 
INI_NO_SECTIONS
@ INI_NO_SECTIONS
Definition: confini.h:458
ini_array_split
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Splits a stringified INI array into NUL-separated members and calls a custom function for each member...
Definition: confini.c:4697
INI_DOT
@ INI_DOT
Definition: confini.h:423
INI_MULTILINE_EVERYWHERE
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:468
ini_string_match_ss
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compares two simple strings and checks whether they match.
Definition: confini.c:2968
INI_UNKNOWN
@ INI_UNKNOWN
Definition: confini.h:396
INI_BUT_DISABLED_AND_COMMENTS
@ INI_BUT_DISABLED_AND_COMMENTS
Definition: confini.h:474
ini_get_lint
long int(*const ini_get_lint)(const char *ini_string)
Pointer to atol()
Definition: confini.c:4989
CONFINI_EOOR
@ CONFINI_EOOR
Definition: confini.h:383
INI_DISABLED_SECTION
@ INI_DISABLED_SECTION
Definition: confini.h:408
IniDispatch::format
const IniFormat format
Definition: confini.h:112
IniFormatNum
uint32_t IniFormatNum
The unique ID of an INI format (24-bit maximum)
Definition: confini.h:127
IniDispatch::v_len
size_t v_len
Definition: confini.h:118
IniDispatch::data
char * data
Definition: confini.h:114
INI_COMMA
@ INI_COMMA
Definition: confini.h:424
ConfiniInterruptNo
ConfiniInterruptNo
Error codes.
Definition: confini.h:373
IniFormat
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:95
ini_unquote
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescapes \', \", and \\ and removes all unescaped quotes (if single/double quotes are considered met...
Definition: confini.c:3663
ini_string_match_ii
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compares two INI strings and checks whether they match.
Definition: confini.c:3234
IniSubstrHandler
int(* IniSubstrHandler)(const char *ini_string, size_t fragm_offset, size_t fragm_length, size_t fragm_num, IniFormat format, void *user_data)
Callback function for handling a selected fragment of an INI string.
Definition: confini.h:164
CONFINI_EROADDR
@ CONFINI_EROADDR
Definition: confini.h:388
INI_ABSOLUTE_AND_RELATIVE
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:449
INI_ANY_SPACE
@ INI_ANY_SPACE
Definition: confini.h:418
ini_array_break
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replaces the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:4546
ini_fton
IniFormatNum ini_fton(const IniFormat format)
Calculates the IniFormatNum of an IniFormat.
Definition: confini.c:4864
CONFINI_ENOENT
@ CONFINI_ENOENT
Definition: confini.h:380
IniStatistics
Global statistics about an INI file.
Definition: confini.h:101
CONFINI_FEINTR
@ CONFINI_FEINTR
Definition: confini.h:378
ini_array_shift
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shifts the location pointed by ini_strptr to the next member of the INI array (without modifying the ...
Definition: confini.c:4246
CONFINI_EIO
@ CONFINI_EIO
Definition: confini.h:382
CONFINI_EBADF
@ CONFINI_EBADF
Definition: confini.h:385
IniDelimiters
IniDelimiters
Common array and key-value delimiters (but a delimiter may also be any other ASCII character not pres...
Definition: confini.h:417
CONFINI_ENOMEM
@ CONFINI_ENOMEM
Definition: confini.h:381
ini_get_llint
long long int(*const ini_get_llint)(const char *ini_string)
Pointer to atoll()
Definition: confini.c:4991
IniDispatch
struct IniDispatch IniDispatch
Dispatch of a single INI node.
INI_ABSOLUTE_ONLY
@ INI_ABSOLUTE_ONLY
Definition: confini.h:452
INI_BUT_COMMENTS
@ INI_BUT_COMMENTS
Definition: confini.h:471
ini_global_set_lowercase_mode
void ini_global_set_lowercase_mode(const bool lowercase)
Sets the value of the global variable INI_GLOBAL_LOWERCASE_MODE.
Definition: confini.c:4821
load_ini_file
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parses an INI file and dispatches its content to a custom callback using a FILE structure as argument...
Definition: confini.c:2807
ini_array_collapse
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compresses the distribution of the data in a stringified INI array by removing all the white spaces t...
Definition: confini.c:4340
IniDispatch
Dispatch of a single INI node.
Definition: confini.h:111
IniStatistics::members
const size_t members
Definition: confini.h:104
INI_IGNORE
@ INI_IGNORE
Definition: confini.h:437
INI_SECTION
@ INI_SECTION
Definition: confini.h:403
IniDispatch::dispatch_id
size_t dispatch_id
Definition: confini.h:120
INI_GLOBAL_IMPLICIT_V_LEN
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys (default value: 0)
Definition: confini.c:5010
strip_ini_cache
int strip_ini_cache(register char *const ini_source, const size_t ini_length, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parses and tokenizes a buffer containing an INI file, then dispatches its content to a custom callbac...
Definition: confini.c:2297
ini_string_parse
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescapes \', \", and \\ and removes all unescaped quotes (if single/double quotes are considered met...
Definition: confini.c:3801
ini_get_double
double(*const ini_get_double)(const char *ini_string)
Pointer to atof()
Definition: confini.c:4993
ini_get_int
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:4987
INI_ONE_LEVEL_ONLY
@ INI_ONE_LEVEL_ONLY
Definition: confini.h:455
IniStatistics::format
const IniFormat format
Definition: confini.h:102
IniDispatch::value
char * value
Definition: confini.h:115
CONFINI_EFBIG
@ CONFINI_EFBIG
Definition: confini.h:387
CONFINI_SUCCESS
@ CONFINI_SUCCESS
Definition: confini.h:374
INI_INLINE_COMMENT
@ INI_INLINE_COMMENT
Definition: confini.h:406
INI_DISABLED_OR_COMMENT
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:434
ini_array_get_length
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Gets the length of a stringified INI array in number of members.
Definition: confini.c:3993
ini_array_match
bool ini_array_match(const char *const ini_string_a, const char *const ini_string_b, const char delimiter, const IniFormat format)
Compares two INI arrays and checks whether they match.
Definition: confini.c:3428
ini_string_match_si
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compares a simple string and an INI string and and checks whether they match.
Definition: confini.c:3066
IniStatistics
struct IniStatistics IniStatistics
Global statistics about an INI file.
IniDispatch::append_to
const char * append_to
Definition: confini.h:116
INI_IS_NOT_A_MARKER
@ INI_IS_NOT_A_MARKER
Definition: confini.h:440
INI_NO_MULTILINE
@ INI_NO_MULTILINE
Definition: confini.h:477
IniDispHandler
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:142
IniSectionPaths
IniSectionPaths
Possible values of IniFormat::section_paths.
Definition: confini.h:448
INI_ONLY_COMMENT
@ INI_ONLY_COMMENT
Definition: confini.h:436
INI_UNIXLIKE_FORMAT
static const IniFormat INI_UNIXLIKE_FORMAT
A model format for Unix-like .conf files (where space characters are delimiters between keys and valu...
Definition: confini.h:493
IniNodeType
IniNodeType
INI node types.
Definition: confini.h:395
INI_GLOBAL_LOWERCASE_MODE
bool INI_GLOBAL_LOWERCASE_MODE
If set to true, key and section names in case-insensitive INI formats will be dispatched lowercase,...
Definition: confini.c:5006
INI_KEY
@ INI_KEY
Definition: confini.h:402
INI_COMMENT
@ INI_COMMENT
Definition: confini.h:405
IniStrHandler
int(* IniStrHandler)(char *ini_string, size_t string_length, size_t string_num, IniFormat format, void *user_data)
Callback function for handling an INI string belonging to a sequence of INI strings.
Definition: confini.h:152
IniMultiline
IniMultiline
Possible values of IniFormat::multiline_nodes.
Definition: confini.h:467
ini_ntof
IniFormat ini_ntof(const IniFormatNum format_id)
Constructs a new IniFormat according to an IniFormatNum.
Definition: confini.c:4885
IniStatistics::bytes
const size_t bytes
Definition: confini.h:103
CONFINI_IINTR
@ CONFINI_IINTR
Definition: confini.h:376
IniDispatch::type
uint8_t type
Definition: confini.h:113
INI_COLON
@ INI_COLON
Definition: confini.h:422
INI_DISABLED_KEY
@ INI_DISABLED_KEY
Definition: confini.h:407
INI_GLOBAL_IMPLICIT_VALUE
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5008
INI_EQUALS
@ INI_EQUALS
Definition: confini.h:421
IniDispatch::at_len
size_t at_len
Definition: confini.h:119
IniDispatch::d_len
size_t d_len
Definition: confini.h:117
load_ini_path
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parses an INI file and dispatches its content to a custom callback using a path as argument.
Definition: confini.c:2891
ini_global_set_implicit_value
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Sets the value to be to be assigned to implicit keys.
Definition: confini.c:4848
ini_get_bool
int ini_get_bool(const char *const ini_string, const int when_fail)
Checks whether a string matches one of the booleans listed in the private constant INI_BOOLEANS (case...
Definition: confini.c:4930
INI_DEFAULT_FORMAT
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:485
ini_array_foreach
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Calls a custom function for each member of a stringified INI array, without modifying the content of ...
Definition: confini.c:4115
ini_array_release
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replaces the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:4625
IniStatsHandler
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:133
INI_VALUE
@ INI_VALUE
Definition: confini.h:398
IniCommentMarker
IniCommentMarker
Possible values of IniFormat::semicolon_marker and IniFormat::hash_marker (i.e., meaning of /\s+;/ an...
Definition: confini.h:433