/* conf.c - config file parser */ #include "config.h" #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "src/conf.h" void strip_char (char *line, char c) { char *p = strchr (line, c); if (p) *p = '\0'; } void strip_newlines (char *line) { strip_char (line, '\n'); strip_char (line, '\r'); } char *eat_whitespace (char *line) { while (isspace ((int)(unsigned char)*line)) line++; return line; } int is_ignored_line (char *line) { return !*line || *line == '#'; } struct conf_entry *conf_parse (FILE *f) { struct conf_entry *head = NULL; struct conf_entry *tail = NULL; char buf[CONF_MAX_LINE]; while (fgets (buf, sizeof (buf), f)) { struct conf_entry *e; char *start = buf; char *key; char *val; strip_newlines (start); start = eat_whitespace (start); if (is_ignored_line (start)) continue; key = strtok (start, " \t"); val = strtok (NULL, ""); if (val) val = eat_whitespace (val); e = malloc (sizeof *e); if (!e) goto fail; e->next = NULL; e->key = strdup (key); e->value = val ? strdup (val) : NULL; if (!e->key || (val && !e->value)) { free (e->key); free (e->value); goto fail; } if (!head) { head = e; tail = e; } else { tail->next = e; tail = e; } } return head; fail: conf_free (head); return NULL; } void conf_free (struct conf_entry *e) { struct conf_entry *n; while (e) { n = e->next; free (e->key); free (e->value); free (e); e = n; } }