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; }