• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 /* inih -- simple .INI file parser
4 
5    SPDX-License-Identifier: BSD-3-Clause
6 
7    Copyright (C) 2009-2020, Ben Hoyt
8 
9    ini is released under the New BSD license.
10 
11    https://github.com/benhoyt/inih
12 
13  */
14 
15 #ifndef IWINI_H
16 #define IWINI_H
17 
18 #include "basedefs.h"
19 #include "iwlog.h"
20 
21 #include <stdio.h>
22 #include <strings.h>
23 
24 IW_EXTERN_C_START
25 
26 #define IWINI_PARSE_BOOL(var__) { \
27     if (!strcasecmp(value, "true") || !strcasecmp(value, "on") || !strcasecmp(value, "yes")) { \
28       var__ = true; \
29     } else if (!strcasecmp(value, "false") || !strcasecmp(value, "off") || !strcasecmp(value, "no")) { \
30       var__ = false; \
31     } else { \
32       iwlog_error("Config: Wrong [%s] section property %s value", section, name); \
33     } \
34 }
35 
36 /* Nonzero if ini_handler callback should accept lineno parameter. */
37 #ifndef IWINI_HANDLER_LINENO
38 #define IWINI_HANDLER_LINENO 0
39 #endif
40 
41 /* Typedef for prototype of handler function. */
42 #if IWINI_HANDLER_LINENO
43 typedef int (*iwini_handler)(
44   void*user, const char*section,
45   const char*name, const char*value,
46   int lineno);
47 #else
48 typedef int (*iwini_handler)(
49   void*user, const char*section,
50   const char*name, const char*value);
51 #endif
52 
53 /* Typedef for prototype of fgets-style reader function. */
54 typedef char* (*iwini_reader)(char*str, int num, void*stream);
55 
56 /* Parse given INI-style file. May have [section]s, name=value pairs
57    (whitespace stripped), and comments starting with ';' (semicolon). Section
58    is "" if name=value pair parsed before any section heading. name:value
59    pairs are also supported as a concession to Python's configparser.
60 
61    For each name=value pair parsed, call handler function with given user
62    pointer as well as section, name, and value (data only valid for duration
63    of handler call). Handler should return nonzero on success, zero on error.
64 
65    Returns 0 on success, line number of first error on parse error (doesn't
66    stop on first error), -1 on file open error, or -2 on memory allocation
67    error (only when INI_USE_STACK is zero).
68  */
69 IW_EXPORT int iwini_parse(const char*filename, iwini_handler handler, void*user);
70 
71 /* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
72    close the file when it's finished -- the caller must do that. */
73 IW_EXPORT int iwini_parse_file(FILE*file, iwini_handler handler, void*user);
74 
75 /* Same as ini_parse(), but takes an ini_reader function pointer instead of
76    filename. Used for implementing custom or string-based I/O (see also
77    iwini_parse_string). */
78 IW_EXPORT int iwini_parse_stream(
79   iwini_reader reader, void*stream, iwini_handler handler,
80   void*user);
81 
82 /* Same as ini_parse(), but takes a zero-terminated string with the INI data
83    instead of a file. Useful for parsing INI data from a network socket or
84    already in memory. */
85 IW_EXPORT int iwini_parse_string(const char*string, iwini_handler handler, void*user);
86 
87 /* Nonzero to allow multi-line value parsing, in the style of Python's
88    configparser. If allowed, ini_parse() will call the handler with the same
89    name for each subsequent line parsed. */
90 #ifndef IWINI_ALLOW_MULTILINE
91 #define IWINI_ALLOW_MULTILINE 1
92 #endif
93 
94 /* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
95    the file. See https://github.com/benhoyt/inih/issues/21 */
96 #ifndef IWINI_ALLOW_BOM
97 #define IWINI_ALLOW_BOM 1
98 #endif
99 
100 /* Chars that begin a start-of-line comment. Per Python configparser, allow
101    both ; and # comments at the start of a line by default. */
102 #ifndef IWINI_START_COMMENT_PREFIXES
103 #define IWINI_START_COMMENT_PREFIXES ";#"
104 #endif
105 
106 /* Nonzero to allow inline comments (with valid inline comment characters
107    specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
108    Python 3.2+ configparser behaviour. */
109 #ifndef IWINI_ALLOW_INLINE_COMMENTS
110 #define IWINI_ALLOW_INLINE_COMMENTS 1
111 #endif
112 #ifndef IWINI_INLINE_COMMENT_PREFIXES
113 #define IWINI_INLINE_COMMENT_PREFIXES ";"
114 #endif
115 
116 /* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
117 #ifndef IWINI_USE_STACK
118 #define IWINI_USE_STACK 1
119 #endif
120 
121 /* Maximum line length for any line in INI file (stack or heap). Note that
122    this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
123 #ifndef IWINI_MAX_LINE
124 #define IWINI_MAX_LINE 200
125 #endif
126 
127 /* Nonzero to allow heap line buffer to grow via realloc(), zero for a
128    fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
129    zero. */
130 #ifndef IWINI_ALLOW_REALLOC
131 #define IWINI_ALLOW_REALLOC 0
132 #endif
133 
134 /* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
135    is zero. */
136 #ifndef IWINI_INITIAL_ALLOC
137 #define IWINI_INITIAL_ALLOC 200
138 #endif
139 
140 /* Stop parsing on first error (default is to keep parsing). */
141 #ifndef IWINI_STOP_ON_FIRST_ERROR
142 #define IWINI_STOP_ON_FIRST_ERROR 0
143 #endif
144 
145 /* Nonzero to call the handler at the start of each new section (with
146    name and value NULL). Default is to only call the handler on
147    each name=value pair. */
148 #ifndef IWINI_CALL_HANDLER_ON_NEW_SECTION
149 #define IWINI_CALL_HANDLER_ON_NEW_SECTION 0
150 #endif
151 
152 /* Nonzero to allow a name without a value (no '=' or ':' on the line) and
153    call the handler with value NULL in this case. Default is to treat
154    no-value lines as an error. */
155 #ifndef IWINI_ALLOW_NO_VALUE
156 #define IWINI_ALLOW_NO_VALUE 0
157 #endif
158 
159 /* Nonzero to use custom ini_malloc, ini_free, and ini_realloc memory
160    allocation functions (INI_USE_STACK must also be 0). These functions must
161    have the same signatures as malloc/free/realloc and behave in a similar
162    way. ini_realloc is only needed if INI_ALLOW_REALLOC is set. */
163 #ifndef IWINI_CUSTOM_ALLOCATOR
164 #define IWINI_CUSTOM_ALLOCATOR 0
165 #endif
166 
167 
168 #ifdef __cplusplus
169 }
170 #endif
171 
172 IW_EXTERN_C_END
173 #endif /* IWINI_H */
174