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 __CONFINI_H__
17 #define __CONFINI_H__
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 #ifdef _LIBCONFINI_NOCCWARN_
37 #define _LIBCONFINI_DO_PRAGMA_(PBODY)
38 #define _LIBCONFINI_WARNING_(MSG)
39 #elif defined(_MSC_VER)
40 #define _LIBCONFINI_DO_PRAGMA_(PBODY) __pragma(PBODY)
41 #define _LIBCONFINI_WARNING_(MSG) _LIBCONFINI_DO_PRAGMA_(message("*WARNING*: " MSG))
42 #else
43 #define _LIBCONFINI_DO_PRAGMA_(PBODY) _Pragma(#PBODY)
44 #define _LIBCONFINI_WARNING_(MSG) _LIBCONFINI_DO_PRAGMA_(GCC warning #MSG)
45 #endif
46 
47 #define __INIFORMAT_TABLE_CB_FIELDS__(NAME, OFFSET, SIZE, DEFVAL) \
48  unsigned char NAME:SIZE;
49 #define __INIFORMAT_TABLE_CB_DEFAULT__(NAME, OFFSET, SIZE, DEFVAL) DEFVAL,
50 #define __INIFORMAT_TABLE_CB_ZERO__(NAME, OFFSET, SIZE, DEFVAL) 0,
51 #define _LIBCONFINI_INIFORMAT_TYPE_ \
52  struct IniFormat { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_FIELDS__) }
53 #define _LIBCONFINI_DEFAULT_FORMAT_ \
54  { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_DEFAULT__) }
55 #define _LIBCONFINI_UNIXLIKE_FORMAT_ \
56  { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_ZERO__) }
57 
58 
59 
60 /* PUBLIC MACROS */
61 
62 
67 /*
68  NOTE: The following table and the order of its rows **define** (and link
69  together) both the #IniFormat and #IniFormatNum data types declared in this
70  header
71 */
72 #define INIFORMAT_TABLE_AS(_____) /* IniFormat table *\
73 
74  NAME BIT SIZE DEFAULT
75  */\
76 _____( delimiter_symbol, 0, 7, INI_EQUALS ) \
77 _____( case_sensitive, 7, 1, false )/*
78  */\
79 _____( semicolon_marker, 8, 2, INI_DISABLED_OR_COMMENT ) \
80 _____( hash_marker, 10, 2, INI_DISABLED_OR_COMMENT ) \
81 _____( section_paths, 12, 2, INI_ABSOLUTE_AND_RELATIVE ) \
82 _____( multiline_nodes, 14, 2, INI_MULTILINE_EVERYWHERE )/*
83  */\
84 _____( no_single_quotes, 16, 1, false ) \
85 _____( no_double_quotes, 17, 1, false ) \
86 _____( no_spaces_in_names, 18, 1, false ) \
87 _____( implicit_is_not_empty, 19, 1, false ) \
88 _____( do_not_collapse_values, 20, 1, false ) \
89 _____( preserve_empty_quotes, 21, 1, false ) \
90 _____( disabled_after_space, 22, 1, false ) \
91 _____( disabled_can_be_implicit, 23, 1, false )
92 
93 
94 
98 #define INIFORMAT_HAS_NO_ESC(FORMAT) \
99  (FORMAT.multiline_nodes == INI_NO_MULTILINE && \
100  FORMAT.no_double_quotes && FORMAT.no_single_quotes)
101 
102 
107 #define INI_IS_IMPLICIT_SUBSTR(CHAR_PTR) \
108  (CHAR_PTR >= INI_GLOBAL_IMPLICIT_VALUE && CHAR_PTR <= \
109  INI_GLOBAL_IMPLICIT_VALUE + INI_GLOBAL_IMPLICIT_V_LEN)
110 
111 
112 
113 /* PUBLIC TYPEDEFS */
114 
115 
120 typedef _LIBCONFINI_INIFORMAT_TYPE_ IniFormat;
121 
122 
126 typedef struct IniStatistics {
127  const IniFormat format;
128  const size_t bytes;
129  const size_t members;
130 } IniStatistics;
131 
132 
136 typedef struct IniDispatch {
138  uint_least8_t type;
139  char * data;
140  char * value;
141  const char * append_to;
142  size_t d_len;
143  size_t v_len;
144  size_t at_len;
145  size_t dispatch_id;
146 } IniDispatch;
147 
148 
152 typedef uint_least32_t IniFormatNum;
153 
154 
158 typedef int (* IniStatsHandler) (
159  IniStatistics * statistics,
160  void * user_data
161 );
162 
163 
167 typedef int (* IniDispHandler) (
168  IniDispatch * dispatch,
169  void * user_data
170 );
171 
172 
177 typedef int (* IniStrHandler) (
178  char * ini_string,
179  size_t string_length,
180  size_t string_num,
181  IniFormat format,
182  void * user_data
183 );
184 
185 
189 typedef int (* IniSubstrHandler) (
190  const char * ini_string,
191  size_t fragm_offset,
192  size_t fragm_length,
193  size_t fragm_num,
194  IniFormat format,
195  void * user_data
196 );
197 
198 
199 
200 /* PUBLIC FUNCTIONS */
201 
202 
203 extern int strip_ini_cache (
204  register char * const ini_source,
205  const size_t ini_length,
206  const IniFormat format,
207  const IniStatsHandler f_init,
208  const IniDispHandler f_foreach,
209  void * const user_data
210 );
211 
212 
213 extern int load_ini_file (
214  FILE * const ini_file,
215  const IniFormat format,
216  const IniStatsHandler f_init,
217  const IniDispHandler f_foreach,
218  void * const user_data
219 );
220 
221 
222 extern int load_ini_path (
223  const char * const path,
224  const IniFormat format,
225  const IniStatsHandler f_init,
226  const IniDispHandler f_foreach,
227  void * const user_data
228 );
229 
230 
231 extern bool ini_string_match_ss (
232  const char * const simple_string_a,
233  const char * const simple_string_b,
234  const IniFormat format
235 );
236 
237 
238 extern bool ini_string_match_si (
239  const char * const simple_string,
240  const char * const ini_string,
241  const IniFormat format
242 );
243 
244 
245 extern bool ini_string_match_ii (
246  const char * const ini_string_a,
247  const char * const ini_string_b,
248  const IniFormat format
249 );
250 
251 
252 extern bool ini_array_match (
253  const char * const ini_string_a,
254  const char * const ini_string_b,
255  const char delimiter,
256  const IniFormat format
257 );
258 
259 
260 extern size_t ini_unquote (
261  char * const ini_string,
262  const IniFormat format
263 );
264 
265 
266 extern size_t ini_string_parse (
267  char * const ini_string,
268  const IniFormat format
269 );
270 
271 
272 extern size_t ini_array_get_length (
273  const char * const ini_string,
274  const char delimiter,
275  const IniFormat format
276 );
277 
278 
279 extern int ini_array_foreach (
280  const char * const ini_string,
281  const char delimiter,
282  const IniFormat format,
283  const IniSubstrHandler f_foreach,
284  void * const user_data
285 );
286 
287 
288 extern size_t ini_array_shift (
289  const char ** const ini_strptr,
290  const char delimiter,
291  const IniFormat format
292 );
293 
294 
295 extern size_t ini_array_collapse (
296  char * const ini_string,
297  const char delimiter,
298  const IniFormat format
299 );
300 
301 
302 extern char * ini_array_break (
303  char * const ini_string,
304  const char delimiter,
305  const IniFormat format
306 );
307 
308 
309 extern char * ini_array_release (
310  char ** const ini_strptr,
311  const char delimiter,
312  const IniFormat format
313 );
314 
315 
316 extern int ini_array_split (
317  char * const ini_string,
318  const char delimiter,
319  const IniFormat format,
320  const IniStrHandler f_foreach,
321  void * const user_data
322 );
323 
324 
325 extern void ini_global_set_lowercase_mode (
326  const bool lowercase
327 );
328 #define __ini_global_set_lowercase_mode \
329  _LIBCONFINI_WARNING_("deprecated function `ini_global_set_lowercase_mode()`") \
330  ini_global_set_lowercase_mode
331 
332 
333 extern void ini_global_set_implicit_value (
334  char * const implicit_value,
335  const size_t implicit_v_len
336 );
337 
338 
339 extern IniFormatNum ini_fton (
340  const IniFormat format
341 );
342 
343 
344 extern IniFormat ini_ntof (
345  const IniFormatNum format_id
346 );
347 
348 
349 extern int ini_get_bool (
350  const char * const simple_string,
351  const int when_fail
352 );
353 
354 
355 extern int ini_get_bool_i (
356  const char * const ini_string,
357  const int when_fail,
358  const IniFormat format
359 );
360 
361 
362 
363 /* PUBLIC LINKS */
364 
365 
366 extern int (* const ini_get_int) (
367  const char * ini_string
368 );
369 
370 
371 extern long int (* const ini_get_lint) (
372  const char * ini_string
373 );
374 
375 
376 extern long long int (* const ini_get_llint) (
377  const char * ini_string
378 );
379 
380 
381 extern double (* const ini_get_double) (
382  const char * ini_string
383 );
384 
385 
386 /*
387  Legacy support -- please **do not use these functions**!
388 */
389 extern double (* const ini_get_float) (const char * ini_string);
390 
391 #define __ini_get_float \
392  _LIBCONFINI_WARNING_("function `ini_get_float()` is deprecated for parsing a `double` data type; use `ini_get_double()` instead") \
393  ini_get_double
394 
395 
396 
397 /* PUBLIC CONSTANTS AND VARIABLES */
398 
399 
403 #define CONFINI_ERROR 252
404 
405 
409 enum ConfiniInterruptNo {
414  CONFINI_FEINTR = 2,
416  CONFINI_ENOENT = 4,
419  CONFINI_EOOR = 7,
421  CONFINI_EBADF = 8,
423  CONFINI_EFBIG = 9,
424  CONFINI_EROADDR = 10
425 };
426 
427 
432 #define INI_DISABLED_FLAG 4
433 
434 
440 enum IniNodeType {
443  INI_VALUE = 1,
447  INI_KEY = 2,
448  INI_SECTION = 3,
450  INI_INLINE_COMMENT = 5,
451  INI_DISABLED_KEY = 6,
454 };
455 
456 
465  INI_EQUALS = '=',
466  INI_COLON = ':',
467  INI_DOT = '.',
468  INI_COMMA = ','
469 };
470 
471 
477 enum IniCommentMarker {
480  INI_ONLY_COMMENT = 1,
486 };
487 
488 
492 enum IniSectionPaths {
499  INI_ONE_LEVEL_ONLY = 2,
502  INI_NO_SECTIONS = 3
505 };
506 
507 
511 enum IniMultiline {
521  INI_NO_MULTILINE = 3
523 };
524 
525 
529 static const IniFormat INI_DEFAULT_FORMAT = { INI_EQUALS, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false };
530 
531 
536 /* All fields are set to `0` here. */
537 static const IniFormat INI_UNIXLIKE_FORMAT = { INI_ANY_SPACE, false, INI_DISABLED_OR_COMMENT, INI_DISABLED_OR_COMMENT, INI_ABSOLUTE_AND_RELATIVE, INI_MULTILINE_EVERYWHERE, false, false, false, false, false, false, false, false };
538 
539 
548 extern bool INI_GLOBAL_LOWERCASE_MODE;
549 #define __INI_GLOBAL_LOWERCASE_MODE \
550  _LIBCONFINI_WARNING_("global variable `INI_GLOBAL_LOWERCASE_MODE` is deprecated") \
551  INI_GLOBAL_LOWERCASE_MODE
552 
553 
557 extern char * INI_GLOBAL_IMPLICIT_VALUE;
558 
559 
563 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
564 
565 
566 
567 /* CLEAN THE PRIVATE ENVIRONMENT */
568 
569 
570 #undef _LIBCONFINI_UNIXLIKE_FORMAT_
571 #undef _LIBCONFINI_DEFAULT_FORMAT_
572 #undef _LIBCONFINI_INIFORMAT_TYPE_
573 #undef __INIFORMAT_TABLE_CB_ZERO__
574 #undef __INIFORMAT_TABLE_CB_DEFAULT__
575 #undef __INIFORMAT_TABLE_CB_FIELDS__
576 
577 
578 
579 /* END OF `__CONFINI_H__` */
580 
581 
582 #ifdef __cplusplus
583 }
584 #endif
585 
586 
587 #endif
588 
589 
590 /* EOF */
591 
int ini_array_split(char *const ini_string, const char delimiter, const IniFormat format, const IniStrHandler f_foreach, void *const user_data)
Split a stringified INI array into NUL-separated members and call a custom function for each member.
Definition: confini.c:5226
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:162
double(*const ini_get_float)(const char *ini_string)
Legacy support for parsing a double data type – please do not use this function: use ini_get_double()...
Definition: confini.c:5755
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:5764
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)
Parse and tokenize a buffer containing an INI file, then dispatch its content to a custom callback.
Definition: confini.c:2605
char * ini_array_release(char **const ini_strptr, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0,...
Definition: confini.c:5146
void ini_global_set_lowercase_mode(const bool lowercase)
Set the value of the global variable INI_GLOBAL_LOWERCASE_MODE.
Definition: confini.c:5366
size_t ini_array_get_length(const char *const ini_string, const char delimiter, const IniFormat format)
Get the length of a stringified INI array in number of members.
Definition: confini.c:4472
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:153
void ini_global_set_implicit_value(char *const implicit_value, const size_t implicit_v_len)
Set the value to be to be assigned to implicit keys.
Definition: confini.c:5395
int ini_array_foreach(const char *const ini_string, const char delimiter, const IniFormat format, const IniSubstrHandler f_foreach, void *const user_data)
Call a custom function for each member of a stringified INI array, without modifying the content of t...
Definition: confini.c:4593
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:5762
uint_least32_t IniFormatNum
The unique ID of an INI format (24-bit maximum)
Definition: confini.h:147
IniSectionPaths
Possible values of IniFormat::section_paths.
Definition: confini.h:487
@ INI_ABSOLUTE_ONLY
Definition: confini.h:491
@ INI_ONE_LEVEL_ONLY
Definition: confini.h:494
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:488
@ INI_NO_SECTIONS
Definition: confini.h:497
ConfiniInterruptNo
Error codes.
Definition: confini.h:404
@ CONFINI_ENOMEM
Definition: confini.h:412
@ CONFINI_FEINTR
Definition: confini.h:409
@ CONFINI_IINTR
Definition: confini.h:407
@ CONFINI_EFBIG
Definition: confini.h:418
@ CONFINI_EROADDR
Definition: confini.h:419
@ CONFINI_EOOR
Definition: confini.h:414
@ CONFINI_EIO
Definition: confini.h:413
@ CONFINI_SUCCESS
Definition: confini.h:405
@ CONFINI_EBADF
Definition: confini.h:416
@ CONFINI_ENOENT
Definition: confini.h:411
IniNodeType
INI node types and possible values of IniDispatch::type.
Definition: confini.h:435
@ INI_DISABLED_SECTION
Definition: confini.h:447
@ INI_COMMENT
Definition: confini.h:444
@ INI_SECTION
Definition: confini.h:443
@ INI_VALUE
Definition: confini.h:438
@ INI_INLINE_COMMENT
Definition: confini.h:445
@ INI_KEY
Definition: confini.h:442
@ INI_DISABLED_KEY
Definition: confini.h:446
@ INI_UNKNOWN
Definition: confini.h:436
struct IniDispatch IniDispatch
Dispatch of a single INI node.
int load_ini_path(const char *const path, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a path as argument.
Definition: confini.c:3274
bool ini_string_match_si(const char *const simple_string, const char *const ini_string, const IniFormat format)
Compare a simple string and an INI string and and check whether they match.
Definition: confini.c:3470
int ini_get_bool_i(const char *const ini_string, const int when_fail, const IniFormat format)
Check whether an INI string matches one of the booleans listed in the private constant INI_BOOLEANS (...
Definition: confini.c:5550
size_t ini_array_shift(const char **const ini_strptr, const char delimiter, const IniFormat format)
Shift the location pointed by ini_strptr to the next member of the INI array (without modifying the c...
Definition: confini.c:4740
IniCommentMarker
Possible values of IniFormat::semicolon_marker and IniFormat::hash_marker (i.e., meaning of /\s+;/ an...
Definition: confini.h:472
@ INI_IGNORE
Definition: confini.h:476
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:473
@ INI_ONLY_COMMENT
Definition: confini.h:475
@ INI_IS_NOT_A_MARKER
Definition: confini.h:479
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:532
bool ini_string_match_ii(const char *const ini_string_a, const char *const ini_string_b, const IniFormat format)
Compare two INI strings and check whether they match.
Definition: confini.c:3653
char * ini_array_break(char *const ini_string, const char delimiter, const IniFormat format)
Replace the first delimiter found (together with the spaces that surround it) with \0
Definition: confini.c:5067
bool ini_array_match(const char *const ini_string_a, const char *const ini_string_b, const char delimiter, const IniFormat format)
Compare two INI arrays and check whether they match.
Definition: confini.c:3864
IniFormat ini_ntof(const IniFormatNum format_id)
Construct a new IniFormat according to an IniFormatNum.
Definition: confini.c:5437
int load_ini_file(FILE *const ini_file, const IniFormat format, const IniStatsHandler f_init, const IniDispHandler f_foreach, void *const user_data)
Parse an INI file and dispatch its content to a custom callback using a FILE structure as argument.
Definition: confini.c:3180
bool ini_string_match_ss(const char *const simple_string_a, const char *const simple_string_b, const IniFormat format)
Compare two simple strings and check whether they match.
Definition: confini.c:3369
long long int(*const ini_get_llint)(const char *ini_string)
Pointer to atoll()
Definition: confini.c:5737
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:184
size_t ini_array_collapse(char *const ini_string, const char delimiter, const IniFormat format)
Compress the distribution of the data in a stringified INI array by removing all the white spaces tha...
Definition: confini.c:4838
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:524
double(*const ini_get_double)(const char *ini_string)
Pointer to atof()
Definition: confini.c:5739
size_t ini_string_parse(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4256
struct IniStatistics IniStatistics
Global statistics about an INI file.
int ini_get_bool(const char *const simple_string, const int when_fail)
Check whether a simple string matches one of the booleans listed in the private constant INI_BOOLEANS...
Definition: confini.c:5481
size_t ini_unquote(char *const ini_string, const IniFormat format)
Unescape \', \", and \\ and remove all unescaped quotes (when single/double quotes are considered met...
Definition: confini.c:4110
IniMultiline
Possible values of IniFormat::multiline_nodes.
Definition: confini.h:506
@ INI_NO_MULTILINE
Definition: confini.h:516
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:507
@ INI_BUT_COMMENTS
Definition: confini.h:510
@ INI_BUT_DISABLED_AND_COMMENTS
Definition: confini.h:513
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys (default value: 0)
Definition: confini.c:5766
IniDelimiters
Common array and key-value delimiters (but a delimiter may also be any other ASCII character not pres...
Definition: confini.h:456
@ INI_COLON
Definition: confini.h:461
@ INI_EQUALS
Definition: confini.h:460
@ INI_ANY_SPACE
Definition: confini.h:457
@ INI_COMMA
Definition: confini.h:463
@ INI_DOT
Definition: confini.h:462
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:5733
long int(*const ini_get_lint)(const char *ini_string)
Pointer to atol()
Definition: confini.c:5735
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:172
IniFormatNum ini_fton(const IniFormat format)
Calculate the IniFormatNum of an IniFormat.
Definition: confini.c:5414
Dispatch of a single INI node.
Definition: confini.h:131
size_t at_len
Definition: confini.h:139
size_t d_len
Definition: confini.h:137
char * data
Definition: confini.h:134
size_t v_len
Definition: confini.h:138
size_t dispatch_id
Definition: confini.h:140
uint_least8_t type
Definition: confini.h:133
char * value
Definition: confini.h:135
const IniFormat format
Definition: confini.h:132
const char * append_to
Definition: confini.h:136
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:115
Global statistics about an INI file.
Definition: confini.h:121
const IniFormat format
Definition: confini.h:122
const size_t members
Definition: confini.h:124
const size_t bytes
Definition: confini.h:123