blob: abb1b92dc1249299858885223acf87daf555bdee (
plain)
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
|
/* conf.c - config file parser */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* strchrnul */
#endif
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "src/conf.h"
#ifdef TARGET_OS_NETBSD
#include "src/common/android.h" // XXX: Dirty hack - make this more generic later
#endif
#ifdef TARGET_OS_OPENBSD
#include "src/common/android.h" // XXX: Dirty hack - make this more generic later
#endif
#ifdef TARGET_OS_DRAGONFLYBSD
#include "src/common/android.h" // XXX: Dirty hack - make this more generic later
#endif
#ifdef TARGET_OS_HAIKU
#include "src/common/android.h" // XXX: Dirty hack - make this more generic later
#endif
#ifdef TARGET_OS_FREEBSD
#ifndef HAVE_STRCHRNUL
#include "src/common/android.h" // XXX: Dirty hack - make this more generic later
#endif
#endif
#ifdef HAVE_ANDROID
#include "src/common/android.h"
#endif
void strip_newlines (char *line)
{
*strchrnul (line, '\n') = '\0';
*strchrnul (line, '\r') = '\0';
}
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;
}
}
|