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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
|
#ifndef REPREPRO_CONFIGPARSER_H
#define REPREPRO_CONFIGPARSER_H
#ifndef REPREPRO_STRLIST_H
#include "strlist.h"
#endif
#ifndef REPREPRO_CHECKS_H
#include "checks.h"
#endif
#ifndef REPREPRO_ATOMS_H
#include "atoms.h"
#endif
struct configiterator;
typedef retvalue configsetfunction(void *, const char *, void *, struct configiterator *);
typedef retvalue configinitfunction(void *, void *, void **);
typedef retvalue configfinishfunction(void *, void *, void **, bool, struct configiterator *);
retvalue linkedlistfinish(void *, void *, void **, bool, struct configiterator *);
struct configfield {
const char *name;
size_t namelen;
/* privdata, allocated struct, iterator */
configsetfunction *setfunc;
bool required;
};
struct constant {
const char *name;
int value;
};
#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}
/*@observer@*/const char *config_filename(const struct configiterator *) __attribute__((pure));
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));
retvalue config_getflags(struct configiterator *, const char *, const struct constant *, bool *, bool, const char *);
int config_nextnonspaceinline(struct configiterator *iter);
retvalue config_getlines(struct configiterator *, struct strlist *);
retvalue config_getwords(struct configiterator *, struct strlist *);
retvalue config_getall(struct configiterator *iter, /*@out@*/char **result_p);
retvalue config_getword(struct configiterator *, /*@out@*/char **);
retvalue config_getwordinline(struct configiterator *, /*@out@*/char **);
retvalue config_geturl(struct configiterator *, const char *, /*@out@*/char **);
retvalue config_getonlyword(struct configiterator *, const char *, checkfunc, /*@out@*/char **);
retvalue config_getuniqwords(struct configiterator *, const char *, checkfunc, struct strlist *);
retvalue config_getinternatomlist(struct configiterator *, const char *, enum atom_type, checkfunc, struct atomlist *);
retvalue config_getatom(struct configiterator *, const char *, enum atom_type, atom_t *);
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 *);
retvalue config_getsplitwords(struct configiterator *, const char *, struct strlist *, struct strlist *);
retvalue config_gettruth(struct configiterator *, const char *, bool *);
retvalue config_getnumber(struct configiterator *, const char *, long long *, long long /*minvalue*/, long long /*maxvalue*/);
retvalue config_getconstant(struct configiterator *, const struct constant *, int *);
#define config_getenum(iter, type, constants, result) ({int _val;retvalue _r = config_getconstant(iter, type ## _ ## constants, &_val);*(result) = (enum type)_val;_r;})
retvalue config_completeword(struct configiterator *, char, /*@out@*/char **);
retvalue config_gettimespan(struct configiterator *, const char *, /*@out@*/unsigned long *);
retvalue config_getscript(struct configiterator *, const char *, /*@out@*/char **);
retvalue config_getsignwith(struct configiterator *, const char *, struct strlist *);
void config_overline(struct configiterator *);
bool config_nextline(struct configiterator *);
retvalue configfile_parse(const char * /*filename*/, bool /*ignoreunknown*/, configinitfunction, configfinishfunction, const char *chunkname, const struct configfield *, size_t, void *);
#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)); \
if (n == NULL) \
return RET_ERROR_OOM; \
if (last == NULL) \
*root_p = n; \
else \
last->next = n; \
*newptr = n; \
return RET_OK; \
}
#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); \
}
#define CFcheckvalueSETPROC(sname, field, checker) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
struct sname *item = data; \
return config_getonlyword(iter, name, checker, &item->field); \
}
#define CFvalueSETPROC(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_getonlyword(iter, name, NULL, &item->field); \
}
#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); \
}
#define CFscriptSETPROC(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_getscript(iter, name, &item->field); \
}
#define CFlinelistSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
item->field ## _set = true; \
return config_getlines(iter, &item->field); \
}
#define CFstrlistSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
return config_getwords(iter, &item->field); \
}
#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); \
}
#define CFcheckuniqstrlistSETPROC(sname, field, checker) \
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_getuniqwords(iter, name, checker, &item->field); \
if (r == RET_NOTHING) { \
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 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); \
if (r == RET_NOTHING) { \
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); \
if (r == RET_NOTHING) { \
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 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); \
}
#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; \
if (item->superset.count == 0) { \
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; \
} \
r = config_getatomsublist(iter, name, type, &item->field, \
&item->superset, superset_header); \
if (r == RET_NOTHING) { \
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 CFuniqstrlistSETPROC(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_getuniqwords(iter, name, NULL, &item->field); \
}
#define CFuniqstrlistSETPROCset(sname, name) \
static retvalue configparser_ ## sname ## _set_ ## name (UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
struct sname *item = data; \
item->name ## _set = true; \
return config_getuniqwords(iter, name, NULL, &item->name); \
}
#define CFtruthSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
struct sname *item = data; \
item->field ## _set = true; \
return config_gettruth(iter, name, &item->field); \
}
#define CFtruthSETPROC2(sname, name, field) \
static retvalue configparser_ ## sname ## _set_ ## name(UNUSED(void *dummy), const char *name, void *data, struct configiterator *iter) { \
struct sname *item = data; \
return config_gettruth(iter, name, &item->field); \
}
#define CFnumberSETPROC(sname, minval, maxval, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
return config_getnumber(iter, name, &item->field, minval, maxval); \
}
#define CFallSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
return config_getall(iter, &item->field); \
}
#define CFfilterlistSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
return filterlist_load(&item->field, iter); \
}
#define CFexportmodeSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
return exportmode_set(&item->field, iter); \
}
#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
#define CFstartparse(sname) static retvalue startparse ## sname(UNUSED(void *dummyprivdata), UNUSED(void *lastdata), void **result_p_ ##sname)
#define CFstartparseVAR(sname, r) struct sname **r = (void*)result_p_ ## sname
#define CFfinishparse(sname) static retvalue finishparse ## sname(void *privdata_ ## sname, void *thisdata_ ## sname, void **lastdata_p_ ##sname, bool complete, struct configiterator *iter)
#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
#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; \
item->field ## _set = true; \
r = config_getflags(iter, name, hashnames, item->field, false, \
"(allowed values: md5, sha1, sha256, and sha512)"); \
if (!RET_IS_OK(r)) \
return r; \
return RET_OK; \
}
// TODO: better error reporting:
#define CFtermSETPROC(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); \
if (! RET_IS_OK(r)) \
return r; \
r = term_compilefortargetdecision(&item->field, formula); \
free(formula); \
return r; \
}
#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); \
if (! RET_IS_OK(r)) \
return r; \
r = term_compilefortargetdecision(&item->field, formula); \
free(formula); \
item->field ## _set = true; \
return r; \
}
// TODO: decide which should get better checking, which might allow escaping spaces:
#define CFdirSETPROC CFvalueSETPROC
#define CFfileSETPROC CFvalueSETPROC
#define config_getfileinline config_getwordinline
char *configfile_expandname(const char *, /*@only@*//*@null@*/char *);
#endif /* REPREPRO_CONFIGPARSER_H */
|