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
|
/// @file ini.h
#ifndef STASIS_INI_H
#define STASIS_INI_H
#include <stddef.h>
#include <stdbool.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_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_INT 1 ///< Integer
#define INIVAL_TYPE_UINT 2 ///< Unsigned integer
#define INIVAL_TYPE_LONG 3 ///< Long integer
#define INIVAL_TYPE_ULONG 4 ///< Unsigned long integer
#define INIVAL_TYPE_LLONG 5 ///< Long long integer
#define INIVAL_TYPE_ULLONG 6 ///< Unsigned long long integer
#define INIVAL_TYPE_DOUBLE 7 ///< Double precision float
#define INIVAL_TYPE_FLOAT 8 ///< Single precision float
#define INIVAL_TYPE_STR 9 ///< String
#define INIVAL_TYPE_STR_ARRAY 10 ///< String Array
#define INIVAL_TYPE_BOOL 11 ///< Boolean
#define INIVAL_TO_LIST 1 << 1
/*! \union INIVal
* \brief Consolidation possible value types
*/
union INIVal {
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
};
/*! \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, 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);
#endif //STASIS_INI_H
|