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 _LIBCONFINI_INIFORMAT_DESCR_(NAME, OFFSET, SIZE, DEFVAL) \
37  unsigned char NAME:SIZE;
38 #define _LIBCONFINI_DEFAULT_FMT_DESCR_(NAME, OFFSET, SIZE, DEFVAL) DEFVAL,
39 #define _LIBCONFINI_UNIXLIKE_FMT_DESCR_(NAME, OFFSET, SIZE, DEFVAL) 0,
40 #define _LIBCONFINI_INIFORMAT_TYPE_ \
41  struct IniFormat { INIFORMAT_TABLE_AS(_LIBCONFINI_INIFORMAT_DESCR_) }
42 #define _LIBCONFINI_DEFAULT_FORMAT_ \
43  { INIFORMAT_TABLE_AS(_LIBCONFINI_DEFAULT_FMT_DESCR_) }
44 #define _LIBCONFINI_UNIXLIKE_FORMAT_ \
45  { INIFORMAT_TABLE_AS(_LIBCONFINI_UNIXLIKE_FMT_DESCR_) }
46 
47 
48 
49 /* PUBLIC MACROS */
50 
51 
55 /*
56  NOTE: The following table and the order of its rows **define** (and link
57  together) both the #IniFormat and #IniFormatNum data types declared in this
58  header
59 */
60 #define INIFORMAT_TABLE_AS(_____) /* IniFormat table *\
61 
62  NAME BIT SIZE DEFAULT
63  */\
64 _____( delimiter_symbol, 0, 7, INI_EQUALS ) \
65 _____( case_sensitive, 7, 1, 0 )/*
66  */\
67 _____( semicolon_marker, 8, 2, INI_DISABLED_OR_COMMENT ) \
68 _____( hash_marker, 10, 2, INI_DISABLED_OR_COMMENT ) \
69 _____( section_paths, 12, 2, INI_ABSOLUTE_AND_RELATIVE ) \
70 _____( multiline_nodes, 14, 2, INI_MULTILINE_EVERYWHERE )/*
71  */\
72 _____( no_single_quotes, 16, 1, 0 ) \
73 _____( no_double_quotes, 17, 1, 0 ) \
74 _____( no_spaces_in_names, 18, 1, 0 ) \
75 _____( implicit_is_not_empty, 19, 1, 0 ) \
76 _____( do_not_collapse_values, 20, 1, 0 ) \
77 _____( preserve_empty_quotes, 21, 1, 0 ) \
78 _____( disabled_after_space, 22, 1, 0 ) \
79 _____( disabled_can_be_implicit, 23, 1, 0 )
80 
81 
82 
86 #define INIFORMAT_HAS_NO_ESC(FORMAT) \
87  (FORMAT.multiline_nodes == INI_NO_MULTILINE && \
88  FORMAT.no_double_quotes && FORMAT.no_single_quotes)
89 
90 
91 
92 /* PUBLIC TYPEDEFS */
93 
94 
99 typedef _LIBCONFINI_INIFORMAT_TYPE_ IniFormat;
100 
101 
105 typedef struct IniStatistics {
106  const IniFormat format;
107  const size_t bytes;
108  const size_t members;
109 } IniStatistics;
110 
111 
115 typedef struct IniDispatch {
117  uint8_t type;
118  char * data;
119  char * value;
120  const char * append_to;
121  size_t d_len;
122  size_t v_len;
123  size_t at_len;
124  size_t dispatch_id;
125 } IniDispatch;
126 
127 
131 typedef uint32_t IniFormatNum;
132 
133 
137 typedef int (* IniStatsHandler) (
138  IniStatistics * statistics,
139  void * user_data
140 );
141 
142 
146 typedef int (* IniDispHandler) (
147  IniDispatch * dispatch,
148  void * user_data
149 );
150 
151 
156 typedef int (* IniStrHandler) (
157  char * ini_string,
158  size_t string_length,
159  size_t string_num,
160  IniFormat format,
161  void * user_data
162 );
163 
164 
168 typedef int (* IniSubstrHandler) (
169  const char * ini_string,
170  size_t fragm_offset,
171  size_t fragm_length,
172  size_t fragm_num,
173  IniFormat format,
174  void * user_data
175 );
176 
177 
178 
179 /* PUBLIC FUNCTIONS */
180 
181 
182 extern int strip_ini_cache (
183  register char * const ini_source,
184  const size_t ini_length,
185  const IniFormat format,
186  const IniStatsHandler f_init,
187  const IniDispHandler f_foreach,
188  void * const user_data
189 );
190 
191 
192 extern int load_ini_file (
193  FILE * const ini_file,
194  const IniFormat format,
195  const IniStatsHandler f_init,
196  const IniDispHandler f_foreach,
197  void * const user_data
198 );
199 
200 
201 extern int load_ini_path (
202  const char * const path,
203  const IniFormat format,
204  const IniStatsHandler f_init,
205  const IniDispHandler f_foreach,
206  void * const user_data
207 );
208 
209 
210 extern bool ini_string_match_ss (
211  const char * const simple_string_a,
212  const char * const simple_string_b,
213  const IniFormat format
214 );
215 
216 
217 extern bool ini_string_match_si (
218  const char * const simple_string,
219  const char * const ini_string,
220  const IniFormat format
221 );
222 
223 
224 extern bool ini_string_match_ii (
225  const char * const ini_string_a,
226  const char * const ini_string_b,
227  const IniFormat format
228 );
229 
230 
231 extern bool ini_array_match (
232  const char * const ini_string_a,
233  const char * const ini_string_b,
234  const char delimiter,
235  const IniFormat format
236 );
237 
238 
239 extern size_t ini_unquote (
240  char * const ini_string,
241  const IniFormat format
242 );
243 
244 
245 extern size_t ini_string_parse (
246  char * const ini_string,
247  const IniFormat format
248 );
249 
250 
251 extern size_t ini_array_get_length (
252  const char * const ini_string,
253  const char delimiter,
254  const IniFormat format
255 );
256 
257 
258 extern int ini_array_foreach (
259  const char * const ini_string,
260  const char delimiter,
261  const IniFormat format,
262  const IniSubstrHandler f_foreach,
263  void * const user_data
264 );
265 
266 
267 extern size_t ini_array_shift (
268  const char ** const ini_strptr,
269  const char delimiter,
270  const IniFormat format
271 );
272 
273 
274 extern size_t ini_array_collapse (
275  char * const ini_string,
276  const char delimiter,
277  const IniFormat format
278 );
279 
280 
281 extern char * ini_array_break (
282  char * const ini_string,
283  const char delimiter,
284  const IniFormat format
285 );
286 
287 
288 extern char * ini_array_release (
289  char ** const ini_strptr,
290  const char delimiter,
291  const IniFormat format
292 );
293 
294 
295 extern int ini_array_split (
296  char * const ini_string,
297  const char delimiter,
298  const IniFormat format,
299  const IniStrHandler f_foreach,
300  void * const user_data
301 );
302 
303 
304 extern void ini_global_set_lowercase_mode (
305  const bool lowercase
306 );
307 
308 
309 extern void ini_global_set_implicit_value (
310  char * const implicit_value,
311  const size_t implicit_v_len
312 );
313 
314 
315 extern IniFormatNum ini_fton (
316  const IniFormat format
317 );
318 
319 
320 extern IniFormat ini_ntof (
321  const IniFormatNum format_id
322 );
323 
324 
325 extern int ini_get_bool (
326  const char * const ini_string,
327  const int return_value
328 );
329 
330 
331 
332 /* PUBLIC LINKS */
333 
334 
335 extern int (* const ini_get_int) (
336  const char * ini_string
337 );
338 
339 
340 extern long int (* const ini_get_lint) (
341  const char * ini_string
342 );
343 
344 
345 extern long long int (* const ini_get_llint) (
346  const char * ini_string
347 );
348 
349 
350 extern double (* const ini_get_double) (
351  const char * ini_string
352 );
353 
354 
359 #define ini_get_float \
360  _Pragma("GCC warning \"function `ini_get_float()` is deprecated for parsing a `double` data type; use `ini_get_double()` instead\"") \
361  ini_get_double
362 
363 
364 
365 /* PUBLIC CONSTANTS AND VARIABLES */
366 
367 
371 #define CONFINI_ERROR 252
372 
373 
378  CONFINI_SUCCESS = 0,
385  CONFINI_ENOMEM = 5,
387  CONFINI_EOOR = 7,
389  CONFINI_EBADF = 8,
391  CONFINI_EFBIG = 9
392 };
393 
394 
398 enum IniNodeType {
399  INI_UNKNOWN = 0,
401  INI_VALUE = 1,
405  INI_KEY = 2,
408  INI_COMMENT = 4,
409  INI_INLINE_COMMENT = 5,
410  INI_DISABLED_KEY = 6,
413 };
414 
415 
424  INI_EQUALS = '=',
425  INI_COLON = ':',
426  INI_DOT = '.',
427  INI_COMMA = ','
428 };
429 
430 
436 enum IniCommentMarker {
439  INI_ONLY_COMMENT = 1,
440  INI_IGNORE = 2,
444 };
445 
446 
450 enum IniSectionPaths {
454  INI_ABSOLUTE_ONLY = 1,
457  INI_ONE_LEVEL_ONLY = 2,
460  INI_NO_SECTIONS = 3
463 };
464 
465 
469 enum IniMultiline {
473  INI_BUT_COMMENTS = 1,
479  INI_NO_MULTILINE = 3
481 };
482 
483 
488 
489 
494 /* All fields are set to `0` here. */
495 static const IniFormat INI_UNIXLIKE_FORMAT = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
496 
497 
503 extern bool INI_GLOBAL_LOWERCASE_MODE;
504 
505 
509 extern char * INI_GLOBAL_IMPLICIT_VALUE;
510 
511 
517 extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
518 
519 
520 
521 /* CLEAN THE PRIVATE ENVIRONMENT */
522 
523 
524 #undef _LIBCONFINI_UNIXLIKE_FORMAT_
525 #undef _LIBCONFINI_DEFAULT_FORMAT_
526 #undef _LIBCONFINI_INIFORMAT_TYPE_
527 #undef _LIBCONFINI_UNIXLIKE_FMT_DESCR_
528 #undef _LIBCONFINI_DEFAULT_FMT_DESCR_
529 #undef _LIBCONFINI_INIFORMAT_DESCR_
530 
531 
532 
533 /* END OF `_LIBCONFINI_HEADER_` */
534 
535 
536 #ifdef __cplusplus
537 }
538 #endif
539 
540 
541 #endif
542 
543 
544 
545 /* EOF */
546 
INI_NO_SECTIONS
@ INI_NO_SECTIONS
Definition: confini.h:455
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:4608
INI_DOT
@ INI_DOT
Definition: confini.h:421
INI_MULTILINE_EVERYWHERE
@ INI_MULTILINE_EVERYWHERE
Definition: confini.h:465
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 if they match.
Definition: confini.c:2932
INI_UNKNOWN
@ INI_UNKNOWN
Definition: confini.h:394
INI_BUT_DISABLED_AND_COMMENTS
@ INI_BUT_DISABLED_AND_COMMENTS
Definition: confini.h:471
ini_get_lint
long int(*const ini_get_lint)(const char *ini_string)
Pointer to atol()
Definition: confini.c:4886
CONFINI_EOOR
@ CONFINI_EOOR
Definition: confini.h:382
INI_DISABLED_SECTION
@ INI_DISABLED_SECTION
Definition: confini.h:406
IniDispatch::format
const IniFormat format
Definition: confini.h:111
IniFormatNum
uint32_t IniFormatNum
The unique ID of an INI format (24-bit maximum)
Definition: confini.h:126
IniDispatch::v_len
size_t v_len
Definition: confini.h:117
IniDispatch::data
char * data
Definition: confini.h:113
INI_COMMA
@ INI_COMMA
Definition: confini.h:422
ConfiniInterruptNo
ConfiniInterruptNo
Error codes.
Definition: confini.h:372
IniFormat
24-bit bitfield representing the format of an INI file (INI dialect)
Definition: confini.h:94
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:3623
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 if they match.
Definition: confini.c:3198
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:163
INI_ABSOLUTE_AND_RELATIVE
@ INI_ABSOLUTE_AND_RELATIVE
Definition: confini.h:446
INI_ANY_SPACE
@ INI_ANY_SPACE
Definition: confini.h:416
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:4465
ini_fton
IniFormatNum ini_fton(const IniFormat format)
Calculates the IniFormatNum of an IniFormat.
Definition: confini.c:4767
CONFINI_ENOENT
@ CONFINI_ENOENT
Definition: confini.h:379
IniStatistics
Global statistics about an INI file.
Definition: confini.h:100
CONFINI_FEINTR
@ CONFINI_FEINTR
Definition: confini.h:377
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:4178
CONFINI_EIO
@ CONFINI_EIO
Definition: confini.h:381
CONFINI_EBADF
@ CONFINI_EBADF
Definition: confini.h:384
IniDelimiters
IniDelimiters
Most used array and key-value delimiters (but a delimiter may also be any other ASCII character not p...
Definition: confini.h:415
CONFINI_ENOMEM
@ CONFINI_ENOMEM
Definition: confini.h:380
ini_get_llint
long long int(*const ini_get_llint)(const char *ini_string)
Pointer to atoll()
Definition: confini.c:4888
IniDispatch
struct IniDispatch IniDispatch
Dispatch of a single INI node.
INI_ABSOLUTE_ONLY
@ INI_ABSOLUTE_ONLY
Definition: confini.h:449
INI_BUT_COMMENTS
@ INI_BUT_COMMENTS
Definition: confini.h:468
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:4726
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 using a FILE structure as argument.
Definition: confini.c:2771
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:4268
ini_get_bool
int ini_get_bool(const char *const ini_string, const int return_value)
Checks whether a string matches one of the booleans listed in the private constant INI_BOOLEANS (case...
Definition: confini.c:4833
IniDispatch
Dispatch of a single INI node.
Definition: confini.h:110
IniStatistics::members
const size_t members
Definition: confini.h:103
INI_IGNORE
@ INI_IGNORE
Definition: confini.h:435
INI_SECTION
@ INI_SECTION
Definition: confini.h:401
IniDispatch::dispatch_id
size_t dispatch_id
Definition: confini.h:119
INI_GLOBAL_IMPLICIT_V_LEN
size_t INI_GLOBAL_IMPLICIT_V_LEN
Length of the value assigned to implicit keys – this may be any unsigned number, independently of the...
Definition: confini.c:4907
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:2271
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:3751
ini_get_double
double(*const ini_get_double)(const char *ini_string)
Pointer to atof()
Definition: confini.c:4890
ini_get_int
int(*const ini_get_int)(const char *ini_string)
Pointer to atoi()
Definition: confini.c:4884
INI_ONE_LEVEL_ONLY
@ INI_ONE_LEVEL_ONLY
Definition: confini.h:452
IniStatistics::format
const IniFormat format
Definition: confini.h:101
IniDispatch::value
char * value
Definition: confini.h:114
CONFINI_EFBIG
@ CONFINI_EFBIG
Definition: confini.h:386
CONFINI_SUCCESS
@ CONFINI_SUCCESS
Definition: confini.h:373
INI_INLINE_COMMENT
@ INI_INLINE_COMMENT
Definition: confini.h:404
INI_DISABLED_OR_COMMENT
@ INI_DISABLED_OR_COMMENT
Definition: confini.h:432
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:3937
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 if they match.
Definition: confini.c:3392
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 if they match.
Definition: confini.c:3030
IniStatistics
struct IniStatistics IniStatistics
Global statistics about an INI file.
IniDispatch::append_to
const char * append_to
Definition: confini.h:115
INI_IS_NOT_A_MARKER
@ INI_IS_NOT_A_MARKER
Definition: confini.h:437
INI_NO_MULTILINE
@ INI_NO_MULTILINE
Definition: confini.h:474
IniDispHandler
int(* IniDispHandler)(IniDispatch *dispatch, void *user_data)
Callback function for handling an IniDispatch structure.
Definition: confini.h:141
IniSectionPaths
IniSectionPaths
Possible values of IniFormat::section_paths.
Definition: confini.h:445
INI_ONLY_COMMENT
@ INI_ONLY_COMMENT
Definition: confini.h:434
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:490
IniNodeType
IniNodeType
INI node types.
Definition: confini.h:393
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:4903
INI_KEY
@ INI_KEY
Definition: confini.h:400
INI_COMMENT
@ INI_COMMENT
Definition: confini.h:403
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:151
IniMultiline
IniMultiline
Possible values of IniFormat::multiline_nodes.
Definition: confini.h:464
ini_ntof
IniFormat ini_ntof(const IniFormatNum format_id)
Constructs a new IniFormat according to an IniFormatNum.
Definition: confini.c:4788
IniStatistics::bytes
const size_t bytes
Definition: confini.h:102
CONFINI_IINTR
@ CONFINI_IINTR
Definition: confini.h:375
IniDispatch::type
uint8_t type
Definition: confini.h:112
INI_COLON
@ INI_COLON
Definition: confini.h:420
INI_DISABLED_KEY
@ INI_DISABLED_KEY
Definition: confini.h:405
INI_GLOBAL_IMPLICIT_VALUE
char * INI_GLOBAL_IMPLICIT_VALUE
Value to be assigned to implicit keys (default value: NULL)
Definition: confini.c:4905
INI_EQUALS
@ INI_EQUALS
Definition: confini.h:419
IniDispatch::at_len
size_t at_len
Definition: confini.h:118
IniDispatch::d_len
size_t d_len
Definition: confini.h:116
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 using a path as argument.
Definition: confini.c:2855
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:4751
INI_DEFAULT_FORMAT
static const IniFormat INI_DEFAULT_FORMAT
A model format for standard INI files.
Definition: confini.h:482
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:4053
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:4541
IniStatsHandler
int(* IniStatsHandler)(IniStatistics *statistics, void *user_data)
Callback function for handling an IniStatistics structure.
Definition: confini.h:132
INI_VALUE
@ INI_VALUE
Definition: confini.h:396
IniCommentMarker
IniCommentMarker
Possible values of IniFormat::semicolon_marker and IniFormat::hash_marker (i.e., meaning of /\s+;/ an...
Definition: confini.h:431