ref: e922ef10cc79b48a7085ec76f343bee5859be94b
dir: /ini.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
void
tolowercase(char *c)
{
while (*c != 0) {
*c = tolower(*c);
c++;
}
}
int
extractsection(char *line, char **section)
{
char *start, *end;
start = strchr(line, '[');
end = strchr(line, ']');
if (start == nil || end == nil)
return 0;
*section = malloc(end-start);
if (!section)
sysfatal("error allocating section string: %r");
if (!memcpy(*section, start+1, end-start-1))
sysfatal("error copying section string: %r");
(*section)[end-start-1] = 0;
return 1;
}
int
extractkeyvalue(char *line, char **key, char **value)
{
char *arg[2];
arg[0] = nil;
arg[1] = nil;
if (getfields(line, arg, 2, 1, "=") == 0)
return 0;
*key = arg[0] ? strdup(arg[0]) : nil;
*value = arg[1] ? strdup(arg[1]) : nil;
if (!(key && value))
sysfatal("error copying key/value strings: %r");
return 1;
}
int
parseini(char *file, void (*f)(char*,char*,char*), int forcelower)
{
char *line;
int callback;
Biobuf *bio = Bopen(file, OREAD);
char *section = nil;
char *key = nil;
char *value = nil;
if (!bio)
return 0;
while (line = Brdstr(bio, '\n', 1)) {
if (!line)
return 1;
if (forcelower)
tolowercase(line);
callback = 0;
if (*line == ';')
goto endline;
if (extractsection(line, §ion))
goto endline;
if (callback = extractkeyvalue(line, &key, &value))
goto endline;
endline:
free(line);
if (callback && f)
f(section, key, value);
}
Bterm(bio);
return 1;
}