-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlc_ini.h
More file actions
139 lines (113 loc) · 2.54 KB
/
Copy pathlc_ini.h
File metadata and controls
139 lines (113 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef LC_INI_H
#define LC_INI_H
#ifndef LC_INI_API
#define LC_INI_API extern
#endif
#ifndef LC_HAVE_SV
#define LC_HAVE_SV
struct lc_sv {
size_t length;
const char *s;
};
#endif
#include <stdbool.h>
struct lc_ini_key_value {
struct lc_sv section;
struct lc_sv key;
struct lc_sv value;
};
LC_INI_API bool lc_ini_parse_sv(
struct lc_sv *iter,
struct lc_ini_key_value *kv,
size_t n, char section[restrict n],
size_t m, char buffer[restrict m]
);
#ifdef LC_IMPLEMENTATION
LC_INI_API bool lc_ini_parse_sv(
struct lc_sv *iter,
struct lc_ini_key_value *kv,
size_t n, char section[restrict n],
size_t m, char buffer[restrict m]
)
{
char *s = section;
char *t = section + n;
char *p = buffer;
char *q = buffer + m;
char *d = p;
skip_whitespace:
if (0 == iter->length)
return false;
switch (iter->s[0]) {
case ' ': iter->s++, iter->length--; goto skip_whitespace;
case '\t': iter->s++, iter->length--; goto skip_whitespace;
case '\r': iter->s++, iter->length--; goto skip_whitespace;
case '\n': iter->s++, iter->length--; goto skip_whitespace;
default: break;
}
switch (iter->s[0]) {
case ';': iter->s++, iter->length--; d = p; goto skip_comment;
case '#': iter->s++, iter->length--; d = p; goto skip_comment;
case '[': iter->s++, iter->length--; d = s; goto parse_section;
default: d = p; goto parse_key;
}
parse_section:
if (0 == iter->length)
return false;
if (t <= s)
return false;
switch (iter->s[0]) {
case ']':
kv->section.s = d, kv->section.length = s - d;
iter->s++, iter->length--;
goto skip_whitespace;
default:
*s++ = *iter->s++, iter->length--;
goto parse_section;
}
parse_key:
if (0 == iter->length)
return false;
if (q <= p)
return false;
switch (iter->s[0]) {
case '=':
kv->key.s = d, kv->key.length = p - d;
do {
iter->s++, iter->length--;
} while (iter->length && ' ' == iter->s[0]);
d = p;
goto parse_value;
default:
*p++ = *iter->s++, iter->length--;
goto parse_key;
}
parse_value:
if (0 == iter->length)
return false;
if (q <= p)
return false;
switch (iter->s[0]) {
case '\n':
kv->value.s = d, kv->value.length = p - d;
iter->s++, iter->length--;
d = p;
goto done;
default:
*p++ = *iter->s++, iter->length--;
goto parse_value;
}
skip_comment:
if (0 == iter->length)
return false;
switch (iter->s[0]) {
default: iter->s++, iter->length--; goto skip_comment;
case '\n': goto skip_whitespace;
}
done:
while (kv->key.length && ' ' == kv->key.s[kv->key.length - 1])
kv->key.length--;
return true;
}
#endif
#endif