-
Notifications
You must be signed in to change notification settings - Fork 8
/
config-parser.h
110 lines (97 loc) · 3.68 KB
/
config-parser.h
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
static inline bool is_line_key(const str* line, const str* key) {
return line->len > key->len && isspace(line->c_str[key->len]) &&
!strncmp(line->c_str, key->c_str, key->len);
}
static inline int conf_construct(conf* c) {
c->bootfs.val = (str*)calloc(1, sizeof(str));
c->bootfs.scoped = (str*)calloc(1, sizeof(str));
c->bootfs_hint.val = (str*)calloc(1, sizeof(str));
c->bootfs_hint.scoped = (str*)calloc(1, sizeof(str));
c->bootfstype.val = (str*)calloc(1, sizeof(str));
c->bootfstype.scoped = (str*)calloc(1, sizeof(str));
c->fs.val = (str*)calloc(1, sizeof(str));
c->fs.scoped = (str*)calloc(1, sizeof(str));
c->fstype.val = (str*)calloc(1, sizeof(str));
c->fstype.scoped = (str*)calloc(1, sizeof(str));
#ifdef SCSI_PROBE
c->scsi_dev.val = (str*)calloc(1, sizeof(str));
c->scsi_dev.scoped = (str*)calloc(1, sizeof(str));
#endif
return !c->bootfs.val || !c->bootfs.scoped || !c->bootfs_hint.val ||
!c->bootfs_hint.scoped || !c->bootfstype.val ||
!c->bootfstype.scoped || !c->fs.val || !c->fs.scoped ||
!c->fstype.val || !c->fstype.scoped;
}
static inline void set_conf(pair* conf, str** line, const size_t key_len) {
int i;
for (i = key_len; isspace((*line)->c_str[i]); ++i)
;
conf->val->c_str = (*line)->c_str + i;
for (i = (*line)->len; isspace((*line)->c_str[i]); --i)
;
(*line)->c_str[i - 1] = 0;
swap(conf->scoped, *line);
}
static inline void conf_set_pick(conf* c, str** line) {
const str bootfs_str = {.c_str = "bootfs", .len = sizeof("bootfs") - 1};
const str bootfs_hint_str = {.c_str = "bootfs_hint",
.len = sizeof("bootfs_hint") - 1};
const str bootfstype_str = {.c_str = "bootfstype",
.len = sizeof("bootfstype") - 1};
const str fs_str = {.c_str = "fs", .len = sizeof("fs") - 1};
const str fstype_str = {.c_str = "fstype", .len = sizeof("fstype") - 1};
#ifdef SCSI_PROBE
const str devtoscan_str = {.c_str = SCSI_ADDR_BOOT_ARG, .len = sizeof(SCSI_ADDR_BOOT_ARG) - 1};
#endif
if (is_line_key(*line, &bootfs_str))
set_conf(&c->bootfs, line, bootfs_str.len);
else if (is_line_key(*line, &bootfs_hint_str))
set_conf(&c->bootfs_hint, line, bootfs_hint_str.len);
else if (is_line_key(*line, &bootfstype_str))
set_conf(&c->bootfstype, line, bootfstype_str.len);
else if (is_line_key(*line, &fs_str))
set_conf(&c->fs, line, fs_str.len);
else if (is_line_key(*line, &fstype_str))
set_conf(&c->fstype, line, fstype_str.len);
#ifdef SCSI_PROBE
else if (is_line_key(*line, &devtoscan_str)){
(*line)->c_str[devtoscan_str.len]='=';
set_conf(&c->scsi_dev, line, devtoscan_str.len);
}
#endif
}
static inline conf* conf_print(conf* c) {
#ifdef DEBUG
printd(
"bootfs: {\"%s\", \"%s\"}, bootfs_hint: {\"%s\", \"%s\"}, bootfstype: "
"{\"%s\", \"%s\"}, fs: {\"%s\", "
"\"%s\"}, fstype: {\"%s\", \"%s\"}"
#ifdef SCSI_PROBE
", scsi_dev: {\"%s\", \"%s\"}"
#endif
"\n",
c->bootfs.val->c_str, c->bootfs.scoped->c_str, c->bootfs_hint.val->c_str,
c->bootfs_hint.scoped->c_str, c->bootfstype.val->c_str,
c->bootfstype.scoped->c_str, c->fs.val->c_str, c->fs.scoped->c_str,
c->fstype.val->c_str, c->fstype.scoped->c_str
#ifdef SCSI_PROBE
, c->scsi_dev.val->c_str, c->scsi_dev.scoped->c_str
#endif
);
#endif
return c;
}
static inline char* conf_read(conf* c, const char* file) {
autofclose FILE* f = fopen(file, "r");
autofree_str str* line = (str*)malloc(sizeof(str));
if (!line)
return NULL;
line->c_str = 0;
if (!f)
return NULL;
for (size_t len_alloc;
(line->len = getline(&line->c_str, &len_alloc, f)) != -1;)
conf_set_pick(c, &line);
conf_print(c);
return NULL;
}