annotate src/ini.c @ 12:dd427b7cc459 default tip

json: replace with nxjson library more lightweight, reduces the binary size by about 40 kb
author Paper <paper@paper.us.eu.org>
date Fri, 15 Mar 2024 20:46:18 -0400
parents e6a594f16403
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 /* inih -- simple .INI file parser
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 SPDX-License-Identifier: BSD-3-Clause
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 Copyright (C) 2009-2020, Ben Hoyt
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7 inih is released under the New BSD license (see LICENSE.txt). Go to the project
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 home page for more info:
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 https://github.com/benhoyt/inih
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12 */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15 #define _CRT_SECURE_NO_WARNINGS
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18 #include <stdio.h>
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19 #include <ctype.h>
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
20 #include <string.h>
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
21
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22 #include "ini.h"
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24 #if !INI_USE_STACK
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
25 #if INI_CUSTOM_ALLOCATOR
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
26 #include <stddef.h>
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27 void* ini_malloc(size_t size);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28 void ini_free(void* ptr);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 void* ini_realloc(void* ptr, size_t size);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 #else
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31 #include <stdlib.h>
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32 #define ini_malloc malloc
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33 #define ini_free free
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 #define ini_realloc realloc
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38 #define MAX_SECTION 50
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 #define MAX_NAME 50
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 /* Used by ini_parse_string() to keep track of string parsing state. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42 typedef struct {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43 const char* ptr;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44 size_t num_left;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45 } ini_parse_string_ctx;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47 /* Strip whitespace chars off end of given string, in place. Return s. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 static char* ini_rstrip(char* s)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50 char* p = s + strlen(s);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 while (p > s && isspace((unsigned char)(*--p)))
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52 *p = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53 return s;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 /* Return pointer to first non-whitespace char in given string. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57 static char* ini_lskip(const char* s)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 while (*s && isspace((unsigned char)(*s)))
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60 s++;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61 return (char*)s;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64 /* Return pointer to first char (of chars) or inline comment in given string,
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65 or pointer to NUL at end of string if neither found. Inline comment must
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 be prefixed by a whitespace character to register as a comment. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 static char* ini_find_chars_or_comment(const char* s, const char* chars)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 #if INI_ALLOW_INLINE_COMMENTS
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
70 int was_space = 0;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
71 while (*s && (!chars || !strchr(chars, *s)) &&
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
72 !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
73 was_space = isspace((unsigned char)(*s));
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74 s++;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
76 #else
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
77 while (*s && (!chars || !strchr(chars, *s))) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
78 s++;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
79 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
80 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81 return (char*)s;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
82 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
84 /* Similar to strncpy, but ensures dest (size bytes) is
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
85 NUL-terminated, and doesn't pad with NULs. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86 static char* ini_strncpy0(char* dest, const char* src, size_t size)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
87 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
88 /* Could use strncpy internally, but it causes gcc warnings (see issue #91) */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89 size_t i;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
90 for (i = 0; i < size - 1 && src[i]; i++)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91 dest[i] = src[i];
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92 dest[i] = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
93 return dest;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96 /* See documentation in header file. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97 int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98 void* user)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100 /* Uses a fair bit of stack (use heap instead if you need to) */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 #if INI_USE_STACK
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102 char line[INI_MAX_LINE];
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103 size_t max_line = INI_MAX_LINE;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 #else
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105 char* line;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 size_t max_line = INI_INITIAL_ALLOC;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108 #if INI_ALLOW_REALLOC && !INI_USE_STACK
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 char* new_line;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110 size_t offset;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112 char section[MAX_SECTION] = "";
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113 char prev_name[MAX_NAME] = "";
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115 char* start;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 char* end;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 char* name;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 char* value;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119 int lineno = 0;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120 int error = 0;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122 #if !INI_USE_STACK
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 line = (char*)ini_malloc(INI_INITIAL_ALLOC);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124 if (!line) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 return -2;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 #if INI_HANDLER_LINENO
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 #define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131 #else
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132 #define HANDLER(u, s, n, v) handler(u, s, n, v)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 /* Scan through stream line by line */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136 while (reader(line, (int)max_line, stream) != NULL) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137 #if INI_ALLOW_REALLOC && !INI_USE_STACK
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 offset = strlen(line);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139 while (offset == max_line - 1 && line[offset - 1] != '\n') {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140 max_line *= 2;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141 if (max_line > INI_MAX_LINE)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142 max_line = INI_MAX_LINE;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 new_line = ini_realloc(line, max_line);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144 if (!new_line) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 ini_free(line);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
146 return -2;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
147 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
148 line = new_line;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
149 if (reader(line + offset, (int)(max_line - offset), stream) == NULL)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
150 break;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151 if (max_line >= INI_MAX_LINE)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152 break;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 offset += strlen(line + offset);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
154 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
155 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
156
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157 lineno++;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
158
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
159 start = line;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
160 #if INI_ALLOW_BOM
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
162 (unsigned char)start[1] == 0xBB &&
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
163 (unsigned char)start[2] == 0xBF) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
164 start += 3;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167 start = ini_lskip(ini_rstrip(start));
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
169 if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
170 /* Start-of-line comment */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
171 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 #if INI_ALLOW_MULTILINE
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
173 else if (*prev_name && *start && start > line) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
174 #if INI_ALLOW_INLINE_COMMENTS
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
175 end = ini_find_chars_or_comment(start, NULL);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 if (*end)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
177 *end = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
178 ini_rstrip(start);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
179 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180 /* Non-blank line with leading whitespace, treat as continuation
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181 of previous name's value (as per Python configparser). */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
182 if (!HANDLER(user, section, prev_name, start) && !error)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
183 error = lineno;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
184 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
185 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
186 else if (*start == '[') {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
187 /* A "[section]" line */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188 end = ini_find_chars_or_comment(start + 1, "]");
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189 if (*end == ']') {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 *end = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 ini_strncpy0(section, start + 1, sizeof(section));
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192 *prev_name = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
193 #if INI_CALL_HANDLER_ON_NEW_SECTION
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
194 if (!HANDLER(user, section, NULL, NULL) && !error)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 error = lineno;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
196 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
197 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
198 else if (!error) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 /* No ']' found on section line */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 error = lineno;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
201 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
203 else if (*start) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204 /* Not a comment, must be a name[=:]value pair */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
205 end = ini_find_chars_or_comment(start, "=:");
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
206 if (*end == '=' || *end == ':') {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 *end = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208 name = ini_rstrip(start);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209 value = end + 1;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210 #if INI_ALLOW_INLINE_COMMENTS
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 end = ini_find_chars_or_comment(value, NULL);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212 if (*end)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213 *end = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
214 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 value = ini_lskip(value);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216 ini_rstrip(value);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218 /* Valid name[=:]value pair found, call handler */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 ini_strncpy0(prev_name, name, sizeof(prev_name));
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220 if (!HANDLER(user, section, name, value) && !error)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221 error = lineno;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
222 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
223 else if (!error) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224 /* No '=' or ':' found on name[=:]value line */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225 #if INI_ALLOW_NO_VALUE
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226 *end = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
227 name = ini_rstrip(start);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 if (!HANDLER(user, section, name, NULL) && !error)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229 error = lineno;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
230 #else
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
231 error = lineno;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
235
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 #if INI_STOP_ON_FIRST_ERROR
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 if (error)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238 break;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
239 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242 #if !INI_USE_STACK
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243 ini_free(line);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244 #endif
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 return error;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
248
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
249 /* See documentation in header file. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
250 int ini_parse_file(FILE* file, ini_handler handler, void* user)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252 return ini_parse_stream((ini_reader)fgets, file, handler, user);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 /* See documentation in header file. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256 int ini_parse(const char* filename, ini_handler handler, void* user)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 FILE* file;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259 int error;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261 file = fopen(filename, "r");
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 if (!file)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 return -1;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264 error = ini_parse_file(file, handler, user);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 fclose(file);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266 return error;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
268
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
269 /* An ini_reader function to read the next line from a string buffer. This
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
270 is the fgets() equivalent used by ini_parse_string(). */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
271 static char* ini_reader_string(char* str, int num, void* stream) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272 ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273 const char* ctx_ptr = ctx->ptr;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
274 size_t ctx_num_left = ctx->num_left;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
275 char* strp = str;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
276 char c;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
277
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
278 if (ctx_num_left == 0 || num < 2)
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
279 return NULL;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
280
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
281 while (num > 1 && ctx_num_left != 0) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
282 c = *ctx_ptr++;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
283 ctx_num_left--;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
284 *strp++ = c;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
285 if (c == '\n')
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
286 break;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287 num--;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290 *strp = '\0';
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
291 ctx->ptr = ctx_ptr;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
292 ctx->num_left = ctx_num_left;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
293 return str;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
294 }
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
295
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
296 /* See documentation in header file. */
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
297 int ini_parse_string(const char* string, ini_handler handler, void* user) {
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
298 ini_parse_string_ctx ctx;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
299
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
300 ctx.ptr = string;
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
301 ctx.num_left = strlen(string);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
302 return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
303 user);
e6a594f16403 *: huge refactor
Paper <paper@paper.us.eu.org>
parents:
diff changeset
304 }