38 #define ASCIILINESZ (1024)
39 #define INI_INVALID_KEY ((char*)NULL)
64 static char* strlwc(
const char* s)
66 static char l[ASCIILINESZ + 1];
72 for (i = 0; s[i] && i < ASCIILINESZ; i++)
90 static char* strstrip(
const char* s)
92 static char l[ASCIILINESZ + 1];
93 unsigned int i, numspc;
101 for (i = numspc = 0; s[i] && i < ASCIILINESZ; i++) {
108 l[i - numspc] =
'\0';
121 line_status ciniparser_line(
char* input_line,
char* section,
122 char* key,
char* value)
125 char line[ASCIILINESZ + 1];
128 strcpy(line, strstrip(input_line));
129 len = (int)strlen(line);
134 }
else if (line[0] ==
'#') {
137 }
else if (line[0] ==
'[' && line[len - 1] ==
']') {
139 if (sscanf(line,
"[%[^]]", section) == 1) {
140 strcpy(section, strstrip(section));
141 strcpy(section, strlwc(section));
144 }
else if (sscanf(line,
"%[^=] = \"%[^\"]\"", key, value) == 2
145 || sscanf(line,
"%[^=] = '%[^\']'", key, value) == 2
146 || sscanf(line,
"%[^=] = %[^;#]", key, value) == 2) {
148 strcpy(key, strstrip(key));
149 strcpy(key, strlwc(key));
150 strcpy(value, strstrip(value));
155 if (!strcmp(value,
"\"\"") || (!strcmp(value,
"''")))
158 }
else if (sscanf(line,
"%[^=] = %[;#]", key, value) == 2
159 || sscanf(line,
"%[^=] %[=]", key, value) == 2) {
166 strcpy(key, strstrip(key));
167 strcpy(key, strlwc(key));
188 for (i = 0; i < d->size; i++) {
189 if (d->key[i] == NULL)
191 if (strchr(d->key[i],
':') == NULL)
203 if (d == NULL || n < 0)
211 for (i = 0; i < d->size; i++) {
212 if (d->key[i] == NULL)
214 if (!strchr(d->key[i],
':')) {
231 if (d == NULL || f == NULL)
234 for (i = 0; i < d->size; i++) {
235 if (d->key[i] == NULL)
237 if (d->val[i] != NULL)
238 fprintf(f,
"[%s]=[%s]\n", d->key[i], d->val[i]);
240 fprintf(f,
"[%s]=UNDEF\n", d->key[i]);
247 char keym[ASCIILINESZ + 1];
252 if (d == NULL || f == NULL)
255 memset(keym, 0, ASCIILINESZ + 1);
260 for (i = 0; i < d->size; i++) {
261 if (d->key[i] == NULL)
263 fprintf(f,
"%s = %s\n", d->key[i], d->val[i]);
268 for (i = 0; i < nsec; i++) {
270 seclen = (int)strlen(secname);
271 fprintf(f,
"\n[%s]\n", secname);
272 snprintf(keym, ASCIILINESZ + 1,
"%s:", secname);
273 for (j = 0; j < d->size; j++) {
274 if (d->key[j] == NULL)
276 if (!strncmp(d->key[j], keym, seclen + 1)) {
277 fprintf(f,
"%-30s = %s\n",
278 d->key[j] + seclen + 1,
279 d->val[j] ? d->val[j] :
"");
291 if (d == NULL || key == NULL)
294 lc_key = strlwc(key);
306 if (str == INI_INVALID_KEY)
309 return (
int)strtol(str, NULL, 10);
318 if (str == INI_INVALID_KEY)
330 if (c == INI_INVALID_KEY)
334 case 'y':
case 'Y':
case '1':
case 't':
case 'T':
337 case 'n':
case 'N':
case '0':
case 'f':
case 'F':
371 char line[ASCIILINESZ + 1];
372 char section[ASCIILINESZ + 1];
373 char key[ASCIILINESZ + 1];
374 char tmp[ASCIILINESZ + 1];
375 char val[ASCIILINESZ + 1];
376 int last = 0, len, lineno = 0, errs = 0;
379 in = fopen(ininame,
"r");
381 fprintf(stderr,
"ciniparser: cannot open %s\n (ignored)",
392 memset(line, 0, ASCIILINESZ + 1);
393 memset(section, 0, ASCIILINESZ + 1);
394 memset(key, 0, ASCIILINESZ + 1);
395 memset(val, 0, ASCIILINESZ + 1);
398 while (fgets(line + last, ASCIILINESZ - last, in) != NULL) {
400 len = (int)strlen(line) - 1;
402 if (line[len] !=
'\n') {
404 "ciniparser: input line too long in %s (%d)\n",
414 ((line[len] ==
'\n') || (isspace(line[len])))) {
420 if (len >= 0 && line[len] ==
'\\') {
426 switch (ciniparser_line(line, section, key, val)) {
436 snprintf(tmp, ASCIILINESZ + 1,
"%s:%s", section, key);
441 fprintf(stderr,
"ciniparser: syntax error in %s (%d):\n",
443 fprintf(stderr,
"-> %s\n", line);
450 memset(line, 0, ASCIILINESZ);
453 fprintf(stderr,
"ciniparser: memory allocation failure\n");
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
int dictionary_set(dictionary *d, const char *key, const char *val)
Set a value in a dictionary.
dictionary * ciniparser_load(const char *ininame)
Parse an ini file and return an allocated dictionary object.
void ciniparser_dump_ini(dictionary *d, FILE *f)
Save a dictionary to a loadable ini file.
int ciniparser_getint(dictionary *d, const char *key, int notfound)
Get the string associated to a key, convert to an int.
const char * dictionary_get(dictionary *d, const char *key, const char *def)
Get a value from a dictionary.
dictionary * dictionary_new(int size)
Create a new dictionary object.
void dictionary_del(dictionary *d)
Delete a dictionary object.
void ciniparser_freedict(dictionary *d)
Free all memory associated to an ini dictionary.
int ciniparser_set(dictionary *d, const char *entry, const char *val)
Set an item in the dictionary.
int ciniparser_find_entry(dictionary *ini, const char *entry)
Finds out if a given entry exists in a dictionary.
void ciniparser_unset(dictionary *ini, char *entry)
Delete an entry in a dictionary.
double ciniparser_getdouble(dictionary *d, const char *key, double notfound)
Get the string associated to a key, convert to a double.
enum _line_status_ line_status
This enum stores the status for each parsed line (internal use only).
void dictionary_unset(dictionary *d, const char *key)
Delete a key in a dictionary.
const char * ciniparser_getsecname(dictionary *d, int n)
Get name for section n in a dictionary.
void ciniparser_dump(dictionary *d, FILE *f)
Dump a dictionary to an opened file pointer.
_line_status_
This enum stores the status for each parsed line (internal use only).
int ciniparser_getnsec(dictionary *d)
Get number of sections in a dictionary.
int ciniparser_getboolean(dictionary *d, const char *key, int notfound)
Get the string associated to a key, convert to a boolean.