configparser.h 14.4 KB
Newer Older
Bernhard Link's avatar
Bernhard Link committed
1 2 3 4 5 6
#ifndef REPREPRO_CONFIGPARSER_H
#define REPREPRO_CONFIGPARSER_H

#ifndef REPREPRO_STRLIST_H
#include "strlist.h"
#endif
7 8 9
#ifndef REPREPRO_CHECKS_H
#include "checks.h"
#endif
10 11 12
#ifndef REPREPRO_ATOMS_H
#include "atoms.h"
#endif
Bernhard Link's avatar
Bernhard Link committed
13 14 15

struct configiterator;

16 17
typedef retvalue configsetfunction(void *, const char *, void *, struct configiterator *);
typedef retvalue configinitfunction(void *, void *, void **);
18
typedef retvalue configfinishfunction(void *, void *, void **, bool, struct configiterator *);
Bernhard Link's avatar
Bernhard Link committed
19

20
retvalue linkedlistfinish(void *, void *, void **, bool, struct configiterator *);
Bernhard Link's avatar
Bernhard Link committed
21 22 23 24 25 26

struct configfield {
	const char *name;
	size_t namelen;
	/* privdata, allocated struct, iterator */
	configsetfunction *setfunc;
27
	bool required;
Bernhard Link's avatar
Bernhard Link committed
28 29 30 31 32 33 34
};

struct constant {
	const char *name;
	int value;
};

35 36
#define CFr(name, sname, field) {name, sizeof(name)-1, configparser_ ## sname ## _set_ ## field, true}
#define CF(name, sname, field) {name, sizeof(name)-1, configparser_ ## sname ## _set_ ## field, false}
Bernhard Link's avatar
Bernhard Link committed
37

38
/*@observer@*/const char *config_filename(const struct configiterator *) __attribute__((pure));
Bernhard Link's avatar
Bernhard Link committed
39 40 41 42 43
unsigned int config_line(const struct configiterator *) __attribute__((pure));
unsigned int config_column(const struct configiterator *) __attribute__((pure));
unsigned int config_firstline(const struct configiterator *) __attribute__((pure));
unsigned int config_markerline(const struct configiterator *) __attribute__((pure));
unsigned int config_markercolumn(const struct configiterator *) __attribute__((pure));
44
retvalue config_getflags(struct configiterator *, const char *, const struct constant *, bool *, bool, const char *);
Bernhard Link's avatar
Bernhard Link committed
45
int config_nextnonspaceinline(struct configiterator *iter);
46 47
retvalue config_getlines(struct configiterator *, struct strlist *);
retvalue config_getwords(struct configiterator *, struct strlist *);
48 49 50
retvalue config_getall(struct configiterator *iter, /*@out@*/char **result_p);
retvalue config_getword(struct configiterator *, /*@out@*/char **);
retvalue config_getwordinline(struct configiterator *, /*@out@*/char **);
51
retvalue config_geturl(struct configiterator *, const char *, /*@out@*/char **);
52
retvalue config_getonlyword(struct configiterator *, const char *, checkfunc, /*@out@*/char **);
53
retvalue config_getuniqwords(struct configiterator *, const char *, checkfunc, struct strlist *);
54
retvalue config_getinternatomlist(struct configiterator *, const char *, enum atom_type, checkfunc, struct atomlist *);
55
retvalue config_getatom(struct configiterator *, const char *, enum atom_type, atom_t *);
56 57 58
retvalue config_getatomlist(struct configiterator *, const char *, enum atom_type, struct atomlist *);
retvalue config_getatomsublist(struct configiterator *, const char *, enum atom_type, struct atomlist *, const struct atomlist *, const char *);
retvalue config_getsplitatoms(struct configiterator *, const char *, enum atom_type, struct atomlist *, struct atomlist *);
Bernhard Link's avatar
Bernhard Link committed
59
retvalue config_getsplitwords(struct configiterator *, const char *, struct strlist *, struct strlist *);
60
retvalue config_gettruth(struct configiterator *, const char *, bool *);
61
retvalue config_getnumber(struct configiterator *, const char *, long long *, long long /*minvalue*/, long long /*maxvalue*/);
Bernhard Link's avatar
Bernhard Link committed
62
retvalue config_getconstant(struct configiterator *, const struct constant *, int *);
63
#define config_getenum(iter, type, constants, result) ({int _val;retvalue _r = config_getconstant(iter, type ## _ ## constants, &_val);*(result) = (enum type)_val;_r;})
64
retvalue config_completeword(struct configiterator *, char, /*@out@*/char **);
65
retvalue config_gettimespan(struct configiterator *, const char *, /*@out@*/unsigned long *);
66 67
retvalue config_getscript(struct configiterator *, const char *, /*@out@*/char **);
retvalue config_getsignwith(struct configiterator *, const char *, struct strlist *);
Bernhard Link's avatar
Bernhard Link committed
68
void config_overline(struct configiterator *);
69
bool config_nextline(struct configiterator *);
70
retvalue configfile_parse(const char * /*filename*/, bool /*ignoreunknown*/, configinitfunction, configfinishfunction, const char *chunkname, const struct configfield *, size_t, void *);
Bernhard Link's avatar
Bernhard Link committed
71 72 73 74 75

#define CFlinkedlistinit(sname) \
static retvalue configparser_ ## sname ## _init(void *rootptr, void *lastitem, void **newptr) { \
	struct sname *n, **root_p = rootptr, *last = lastitem; \
	n = calloc(1, sizeof(struct sname)); \
76
	if (n == NULL) \
Bernhard Link's avatar
Bernhard Link committed
77
		return RET_ERROR_OOM; \
78
	if (last == NULL) \
Bernhard Link's avatar
Bernhard Link committed
79 80 81 82 83 84
		*root_p = n; \
	else \
		last->next = n; \
	*newptr = n; \
	return RET_OK; \
}
85 86 87 88 89
#define CFtimespanSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	return config_gettimespan(iter, name, &item->field); \
}
90
#define CFcheckvalueSETPROC(sname, field, checker) \
91
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
92 93 94
	struct sname *item = data; \
	return config_getonlyword(iter, name, checker, &item->field); \
}
Bernhard Link's avatar
Bernhard Link committed
95
#define CFvalueSETPROC(sname, field) \
96
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
97
	struct sname *item = data; \
98
	return config_getonlyword(iter, name, NULL, &item->field); \
Bernhard Link's avatar
Bernhard Link committed
99
}
100 101 102 103 104
#define CFurlSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	return config_geturl(iter, name, &item->field); \
}
105
#define CFscriptSETPROC(sname, field) \
106
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
107
	struct sname *item = data; \
108
	return config_getscript(iter, name, &item->field); \
109
}
110
#define CFlinelistSETPROC(sname, field) \
111
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
112
	struct sname *item = data; \
113
	item->field ## _set = true; \
114 115
	return config_getlines(iter, &item->field); \
}
Bernhard Link's avatar
Bernhard Link committed
116
#define CFstrlistSETPROC(sname, field) \
117
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
118 119 120
	struct sname *item = data; \
	return config_getwords(iter, &item->field); \
}
121 122 123 124 125
#define CFsignwithSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	return config_getsignwith(iter, name, &item->field); \
}
126
#define CFcheckuniqstrlistSETPROC(sname, field, checker) \
127
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
128
	struct sname *item = data; \
129 130
	retvalue r; \
	r = config_getuniqwords(iter, name, checker, &item->field); \
131
	if (r == RET_NOTHING) { \
132
		fprintf(stderr, \
133 134 135 136 137 138 139 140 141 142 143 144 145 146
"Error parsing %s, line %d, column %d:\n" \
" An empty %s-field is not allowed.\n", config_filename(iter), \
					config_line(iter), \
					config_column(iter), \
					name); \
		r = RET_ERROR; \
	} \
	return r; \
}
#define CFinternatomsSETPROC(sname, field, checker, type) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	retvalue r; \
	r = config_getinternatomlist(iter, name, type, checker, &item->field); \
147
	if (r == RET_NOTHING) { \
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		fprintf(stderr, \
"Error parsing %s, line %d, column %d:\n" \
" An empty %s-field is not allowed.\n", config_filename(iter), \
					config_line(iter), \
					config_column(iter), \
					name); \
		r = RET_ERROR; \
	} \
	return r; \
}
#define CFatomlistSETPROC(sname, field, type) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	retvalue r; \
	item->field ## _set = true; \
	r = config_getatomlist(iter, name, type, &item->field); \
164
	if (r == RET_NOTHING) { \
165 166 167 168 169 170 171 172 173 174
		fprintf(stderr, \
"Error parsing %s, line %d, column %d:\n" \
" An empty %s-field is not allowed.\n", config_filename(iter), \
					config_line(iter), \
					config_column(iter), \
					name); \
		r = RET_ERROR; \
	} \
	return r; \
}
175 176 177 178 179
#define CFatomSETPROC(sname, field, type) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	return config_getatom(iter, name, type, &item->field); \
}
180 181 182 183 184
#define CFatomsublistSETPROC(sname, field, type, superset, superset_header) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	retvalue r; \
	item->field ## _set = true; \
185
	if (item->superset.count == 0) { \
186 187 188 189 190 191 192 193
		fprintf(stderr, \
"Error parsing %s, line %d, column %d:\n" \
" A '%s'-field is only allowed after a '%s'-field.\n", config_filename(iter), \
					config_line(iter), \
					config_column(iter), \
					name, superset_header); \
		return RET_ERROR; \
	} \
194 195 196
	r = config_getatomsublist(iter, name, type, &item->field, \
			&item->superset, superset_header); \
	if (r == RET_NOTHING) { \
197
		fprintf(stderr, \
198 199 200 201 202 203 204 205
"Error parsing %s, line %d, column %d:\n" \
" An empty %s-field is not allowed.\n", config_filename(iter), \
					config_line(iter), \
					config_column(iter), \
					name); \
		r = RET_ERROR; \
	} \
	return r; \
206
}
Bernhard Link's avatar
Bernhard Link committed
207
#define CFuniqstrlistSETPROC(sname, field) \
208
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
209
	struct sname *item = data; \
210
	return config_getuniqwords(iter, name, NULL, &item->field); \
Bernhard Link's avatar
Bernhard Link committed
211
}
212
#define CFuniqstrlistSETPROCset(sname, name) \
213
static retvalue configparser_ ## sname ## _set_ ## name (UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
214
	struct sname *item = data; \
215 216
	item->name ## _set = true; \
	return config_getuniqwords(iter, name, NULL, &item->name); \
Bernhard Link's avatar
Bernhard Link committed
217 218
}
#define CFtruthSETPROC(sname, field) \
219
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
220
	struct sname *item = data; \
221
	item->field ## _set = true; \
Bernhard Link's avatar
Bernhard Link committed
222 223 224
	return config_gettruth(iter, name, &item->field); \
}
#define CFtruthSETPROC2(sname, name, field) \
225
static retvalue configparser_ ## sname ## _set_ ## name(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
226 227 228 229
	struct sname *item = data; \
	return config_gettruth(iter, name, &item->field); \
}
#define CFallSETPROC(sname, field) \
230
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
231 232 233 234
	struct sname *item = data; \
	return config_getall(iter, &item->field); \
}
#define CFfilterlistSETPROC(sname, field) \
235
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
236
	struct sname *item = data; \
237
	return filterlist_load(&item->field, iter); \
Bernhard Link's avatar
Bernhard Link committed
238 239
}
#define CFexportmodeSETPROC(sname, field) \
240
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
241
	struct sname *item = data; \
242
	return exportmode_set(&item->field, iter); \
Bernhard Link's avatar
Bernhard Link committed
243
}
244 245 246 247 248
#define CFUSETPROC(sname, field) static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *thisdata_ ## sname, struct configiterator *iter)
#define CFuSETPROC(sname, field) static retvalue configparser_ ## sname ## _set_ ## field(void *privdata_ ## sname, UNUSED(const char *name), void *thisdata_ ## sname, struct configiterator *iter)
#define CFSETPROC(sname, field) static retvalue configparser_ ## sname ## _set_ ## field(void *privdata_ ## sname, const char *headername, void *thisdata_ ## sname, struct configiterator *iter)
#define CFSETPROCVARS(sname, item, mydata) struct sname *item = thisdata_ ## sname; struct read_ ## sname ## _data *mydata = privdata_ ## sname
#define CFSETPROCVAR(sname, item) struct sname *item = thisdata_ ## sname
Bernhard Link's avatar
Bernhard Link committed
249 250

#define CFstartparse(sname) static retvalue startparse ## sname(UNUSED(void *dummyprivdata), UNUSED(void *lastdata), void **result_p_ ##sname)
251
#define CFstartparseVAR(sname, r) struct sname **r = (void*)result_p_ ## sname
252
#define CFfinishparse(sname) static retvalue finishparse ## sname(void *privdata_ ## sname, void *thisdata_ ## sname, void **lastdata_p_ ##sname, bool complete, struct configiterator *iter)
253 254
#define CFfinishparseVARS(sname, this, last, mydata) struct sname *this = thisdata_ ## sname, **last = (void*)lastdata_p_ ## sname; struct read_ ## sname ## _data *mydata = privdata_ ## sname
#define CFUfinishparseVARS(sname, this, last, mydata) struct sname *this = thisdata_ ## sname
Bernhard Link's avatar
Bernhard Link committed
255 256 257 258
#define CFhashesSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	retvalue r; \
259
	item->field ## _set = true; \
260 261 262
	r = config_getflags(iter, name, hashnames, item->field, false, \
			"(allowed values: md5, sha1 and sha256)"); \
	if (!RET_IS_OK(r)) \
Bernhard Link's avatar
Bernhard Link committed
263 264 265
		return r; \
	return RET_OK; \
}
Bernhard Link's avatar
Bernhard Link committed
266 267 268

// TODO: better error reporting:
#define CFtermSETPROC(sname, field) \
269
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
Bernhard Link's avatar
Bernhard Link committed
270 271 272 273
	struct sname *item = data; \
	char *formula; \
	retvalue r; \
	r = config_getall(iter, &formula); \
274
	if (! RET_IS_OK(r)) \
Bernhard Link's avatar
Bernhard Link committed
275
		return r; \
276
	r = term_compilefortargetdecision(&item->field, formula); \
Bernhard Link's avatar
Bernhard Link committed
277 278 279
	free(formula); \
	return r; \
}
280 281 282 283 284 285
#define CFtermSSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
	struct sname *item = data; \
	char *formula; \
	retvalue r; \
	r = config_getall(iter, &formula); \
286
	if (! RET_IS_OK(r)) \
287
		return r; \
288
	r = term_compilefortargetdecision(&item->field, formula); \
289 290 291 292
	free(formula); \
	item->field ## _set = true; \
	return r; \
}
Bernhard Link's avatar
Bernhard Link committed
293

294
// TODO: decide which should get better checking, which might allow escaping spaces:
Bernhard Link's avatar
Bernhard Link committed
295 296 297 298
#define CFdirSETPROC CFvalueSETPROC
#define CFfileSETPROC CFvalueSETPROC
#define config_getfileinline config_getwordinline

299
char *configfile_expandname(const char *, /*@only@*//*@null@*/char *);
Bernhard Link's avatar
Bernhard Link committed
300
#endif /* REPREPRO_CONFIGPARSER_H */