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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
/// @file ini.h
#ifndef STASIS_INI_H
#define STASIS_INI_H
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#include "template.h"
#define INI_WRITE_RAW 0 ///< Dump INI data. Contents are not modified.
#define INI_WRITE_PRESERVE 1 ///< Dump INI data. Template strings are
#define INI_READ_RAW 0 ///< Dump INI data. Contents are not modified.
#define INI_READ_RENDER 1 ///< Dump INI data. Template strings are
#define INI_SETVAL_APPEND 0
#define INI_SETVAL_REPLACE 1
#define INI_SEARCH_EXACT 0
#define INI_SEARCH_BEGINS 1
#define INI_SEARCH_SUBSTR 2
///< expanded to preserve runtime state.
#define INIVAL_TYPE_CHAR 1 ///< Byte
#define INIVAL_TYPE_UCHAR 2 ///< Unsigned byte
#define INIVAL_TYPE_SHORT 3 ///< Short integer
#define INIVAL_TYPE_USHORT 4 ///< Unsigned short integer
#define INIVAL_TYPE_INT 5 ///< Integer
#define INIVAL_TYPE_UINT 6 ///< Unsigned integer
#define INIVAL_TYPE_LONG 7 ///< Long integer
#define INIVAL_TYPE_ULONG 8 ///< Unsigned long integer
#define INIVAL_TYPE_LLONG 9 ///< Long long integer
#define INIVAL_TYPE_ULLONG 10 ///< Unsigned long long integer
#define INIVAL_TYPE_DOUBLE 11 ///< Double precision float
#define INIVAL_TYPE_FLOAT 12 ///< Single precision float
#define INIVAL_TYPE_STR 13 ///< String
#define INIVAL_TYPE_STR_ARRAY 14 ///< String Array
#define INIVAL_TYPE_BOOL 15 ///< Boolean
#define INIVAL_TO_LIST 1 << 1
/*! \union INIVal
* \brief Consolidate possible value types
*/
union INIVal {
char as_char; ///< Byte
unsigned char as_uchar; ///< Unsigned byte
short as_short; ///< Short integer
unsigned short as_ushort; ///< Unsigned short integer
int as_int; ///< Integer
unsigned as_uint; ///< Unsigned integer
long as_long; ///< Long integer
unsigned long as_ulong; ///< Unsigned long integer
long long as_llong; ///< Long long integer
unsigned long long as_ullong; ///< Unsigned long long integer
double as_double; ///< Double precision float
float as_float; ///< Single precision float
char *as_char_p; ///< String
char **as_char_array_p; ///< String Array
bool as_bool; ///< Boolean
};
/*! \struct INIData
* \brief A structure to describe an INI data record
*/
struct INIData {
char *key; ///< INI variable name
char *value; ///< INI variable value
unsigned type_hint;
};
/*! \struct INISection
* \brief A structure to describe an INI section
*/
struct INISection {
size_t data_count; ///< Total INIData records
char *key; ///< INI section name
struct INIData **data; ///< Array of INIData records
};
/*! \struct INIFILE
* \brief A structure to describe an INI configuration file
*/
struct INIFILE {
size_t section_count; ///< Total INISection records
struct INISection **section; ///< Array of INISection records
};
/**
* Open and parse and INI configuration file
*
* ~~~.c
* #include "ini.h"
* int main(int argc, char *argv[]) {
* const char *filename = "example.ini"
* struct INIFILE *ini;
* ini = ini_open(filename);
* if (!ini) {
* perror(filename);
* exit(1);
* }
* }
* ~~~
*
* @param filename path to INI file
* @return pointer to INIFILE
*/
struct INIFILE *ini_open(const char *filename);
/**
*
* @param ini
* @param value
* @return
*/
struct INISection *ini_section_search(struct INIFILE **ini, unsigned mode, const char *value);
/**
*
* @param ini
* @param key
* @return
*/
int ini_section_create(struct INIFILE **ini, char *key);
/**
*
* @param ini
* @param section
* @param key
* @return
*/
int ini_has_key(struct INIFILE *ini, const char *section, const char *key);
/**
* Assign value to a section key
* @param ini
* @param type INI_SETVAL_APPEND or INI_SETVAL_REPLACE
* @param section_name
* @param key
* @param value
* @return
*/
int ini_setval(struct INIFILE **ini, unsigned type, char *section_name, char *key, char *value);
/**
* Retrieve all data records in an INI section
*
* `example.ini`
* ~~~.ini
* [example]
* key_1 = a string
* key_2 = 100
* ~~~
*
* `example.c`
* ~~~.c
* #include "ini.h"
* int main(int argc, char *argv[]) {
* const char *filename = "example.ini"
* struct INIData *data;
* struct INIFILE *ini;
* ini = ini_open(filename);
* if (!ini) {
* perror(filename);
* exit(1);
* }
* // Read all records in "example" section
* for (size_t i = 0; ((data = ini_getall(&ini, "example") != NULL); i++) {
* printf("key=%s, value=%s\n", data->key, data->value);
* }
* }
* ~~~
*
* @param ini pointer to INIFILE
* @param section_name to read
* @return pointer to INIData
*/
struct INIData *ini_getall(struct INIFILE *ini, char *section_name);
/**
* Retrieve a single record from a section key
*
* `example.ini`
* ~~~.ini
* [example]
* key_1 = a string
* key_2 = 100
* ~~~
*
* `example.c`
* ~~~.c
* #include "ini.h"
* int main(int argc, char *argv[]) {
* const char *filename = "example.ini"
* union INIVal *data;
* struct INIFILE *ini;
* ini = ini_open(filename);
* if (!ini) {
* perror(filename);
* exit(1);
* }
* data = ini_getval(&ini, "example", "key_1", INIVAL_TYPE_STR);
* puts(data.as_char_p);
* data = ini_getval(&ini, "example", "key_2", INIVAL_TYPE_INT);
* printf("%d\n", data.as_int);
* }
* ~~~
*
* @param ini pointer to INIFILE
* @param section_name to read
* @param key to return
* @param type INIVAL_TYPE_INT
* @param type INIVAL_TYPE_UINT
* @param type INIVAL_TYPE_LONG
* @param type INIVAL_TYPE_ULONG
* @param type INIVAL_TYPE_LLONG
* @param type INIVAL_TYPE_ULLONG
* @param type INIVAL_TYPE_DOUBLE
* @param type INIVAL_TYPE_FLOAT
* @param type INIVAL_TYPE_STR
* @param type INIVAL_TYPE_STR_ARRAY
* @param type INIVAL_TYPE_BOOL
* @param result pointer to INIVal
* @return 0 on success
* @return Non-zero on error
*/
int ini_getval(struct INIFILE *ini, char *section_name, char *key, int type, int flags, union INIVal *result);
/**
* Write INIFILE sections and data to a file stream
* @param ini pointer to INIFILE
* @param file pointer to address of file stream
* @return 0 on success, -1 on error
*/
int ini_write(struct INIFILE *ini, FILE **stream, unsigned mode);
/**
* Free memory allocated by ini_open()
* @param ini
*/
void ini_free(struct INIFILE **ini);
int ini_getval_int(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
unsigned int ini_getval_uint(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
long ini_getval_long(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
unsigned long ini_getval_ulong(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
long long ini_getval_llong(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
unsigned long long ini_getval_ullong(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
float ini_getval_float(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
double ini_getval_double(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
bool ini_getval_bool(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
short ini_getval_short(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
unsigned short ini_getval_ushort(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
char ini_getval_char(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
unsigned char ini_getval_uchar(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
char *ini_getval_char_p(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
char *ini_getval_str(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
char *ini_getval_char_array_p(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
char *ini_getval_str_array(struct INIFILE *ini, char *section_name, char *key, int flags, int *state);
struct StrList *ini_getval_strlist(struct INIFILE *ini, char *section_name, char *key, char *tok, int flags, int *state);
#endif //STASIS_INI_H
|