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