annotate src/ini.c @ 11:e6a594f16403

*: huge refactor the config file has changed drastically, moving to an ini file from that custom format; i *would* have used the win32 functions for those, but they were barely functional, so I decided on using ini.h which is lightweight enough. additionally, I've added Deezer support so album art will be displayed! unfortunately though winhttp is a pain in the ass so if I send a request with any form of unicode chars in it it just returns a "bad request" error. I've tried debugging this but I could never really come up with anything: my hypothesis is that deezer expects their characters in percent-encoded UTF-8, but winhttp is sending them in some other encoding. the config dialog was moved out of config.c (overdue) and many more options are given in the config as well. main.c has been renamed to plugin.c to better differentiate it from... everything else.
author Paper <paper@paper.us.eu.org>
date Thu, 14 Mar 2024 20:25:37 -0400
parents
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 }