]>
Commit | Line | Data |
---|---|---|
934b03fc | 1 | /* |
cca8ba0d | 2 | * DEBUG: none Generate squid.conf.default and cf_parser.cci |
934b03fc | 3 | * AUTHOR: Max Okumoto |
4 | * | |
2b6662ba | 5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
e25c139f | 6 | * ---------------------------------------------------------- |
934b03fc | 7 | * |
2b6662ba | 8 | * Squid is the result of efforts by numerous individuals from |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
934b03fc | 16 | * |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
26ac0430 | 21 | * |
934b03fc | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26ac0430 | 26 | * |
934b03fc | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program; if not, write to the Free Software | |
cbdec147 | 29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
e25c139f | 30 | * |
934b03fc | 31 | */ |
32 | ||
33 | /***************************************************************************** | |
34 | * Abstract: This program parses the input file and generates code and | |
35 | * files used to configure the variables in squid. | |
e321c7d4 | 36 | * (ie it creates the squid.conf.default file from the cf.data file) |
934b03fc | 37 | * |
38 | * The output files are as follows: | |
cca8ba0d | 39 | * cf_parser.cci - this file contains, default_all() which |
f53b06f9 | 40 | * initializes variables with the default |
41 | * values, parse_line() that parses line from | |
e321c7d4 | 42 | * squid.conf.default, dump_config that dumps the |
934b03fc | 43 | * current the values of the variables. |
e321c7d4 | 44 | * squid.conf.default - default configuration file given to the server |
934b03fc | 45 | * administrator. |
46 | *****************************************************************************/ | |
47 | ||
9fb4efad | 48 | #include "config.h" |
9fb4efad AJ |
49 | #include "util.h" |
50 | ||
7ff7a211 FC |
51 | #include <iostream> |
52 | #include <fstream> | |
9fb4efad AJ |
53 | #if HAVE_STRING_H |
54 | #include <string.h> | |
55 | #endif | |
56 | #if HAVE_STRING_H | |
57 | #include <ctype.h> | |
58 | #endif | |
0e6dc28c FC |
59 | #if HAVE_ERRNO_H |
60 | #include <errno.h> | |
61 | #endif | |
6507d007 | 62 | |
cca8ba0d HN |
63 | #include "cf_gen_defines.cci" |
64 | ||
a7d95664 AJ |
65 | /* libmisc pulls in dependency on time.cc via new() / mem |
66 | * but for cross-compilers we cannot link to the available time.o | |
67 | */ | |
68 | #include "time.cc" | |
69 | ||
934b03fc | 70 | #define MAX_LINE 1024 /* longest configuration line */ |
cca8ba0d | 71 | #define _PATH_PARSER "cf_parser.cci" |
1446a5fd | 72 | #define _PATH_SQUID_CONF "squid.conf.documented" |
509fba1a | 73 | #define _PATH_SQUID_CONF_SHORT "squid.conf.default" |
41bd17a4 | 74 | #define _PATH_CF_DEPEND "cf.data.depend" |
934b03fc | 75 | |
76 | enum State { | |
77 | sSTART, | |
78 | s1, | |
79 | sDOC, | |
c68e9c6b | 80 | sNOCOMMENT, |
934b03fc | 81 | sEXIT |
82 | }; | |
83 | ||
26ac0430 | 84 | typedef struct Line { |
934b03fc | 85 | char *data; |
62e76326 | 86 | |
934b03fc | 87 | struct Line *next; |
2fadd50d | 88 | } Line; |
62e76326 | 89 | |
26ac0430 | 90 | typedef struct EntryAlias { |
934b03fc | 91 | |
7af1c5ab | 92 | struct EntryAlias *next; |
93 | char *name; | |
2fadd50d | 94 | } EntryAlias; |
7af1c5ab | 95 | |
26ac0430 | 96 | typedef struct Entry { |
934b03fc | 97 | char *name; |
7af1c5ab | 98 | EntryAlias *alias; |
934b03fc | 99 | char *type; |
100 | char *loc; | |
101 | char *default_value; | |
6b53c392 | 102 | Line *default_if_none; |
934b03fc | 103 | char *comment; |
1df370e3 | 104 | char *ifdef; |
934b03fc | 105 | Line *doc; |
c68e9c6b | 106 | Line *nocomment; |
b3de4c9b | 107 | int array_flag; |
62e76326 | 108 | |
934b03fc | 109 | struct Entry *next; |
2fadd50d | 110 | } Entry; |
934b03fc | 111 | |
26ac0430 | 112 | typedef struct TypeDep { |
41bd17a4 | 113 | char *name; |
114 | ||
115 | TypeDep *next; | |
116 | } TypeDep; | |
117 | ||
26ac0430 | 118 | typedef struct Type { |
41bd17a4 | 119 | char *name; |
120 | TypeDep *depend; | |
934b03fc | 121 | |
41bd17a4 | 122 | struct Type *next; |
123 | } Type; | |
124 | ||
125 | static const char WS[] = " \t\n"; | |
7ff7a211 FC |
126 | static int gen_default(Entry *, std::ostream &); |
127 | static void gen_parse(Entry *, std::ostream &); | |
128 | static void gen_parse_entry(Entry *entry, std::ostream&); | |
129 | static void gen_parse_alias(char *, EntryAlias *, Entry *, std::ostream &); | |
130 | static void gen_dump(Entry *, std::ostream&); | |
131 | static void gen_free(Entry *, std::ostream&); | |
132 | static void gen_conf(Entry *, std::ostream&, bool verbose_output); | |
133 | static void gen_default_if_none(Entry *, std::ostream&); | |
934b03fc | 134 | |
d89f9532 | 135 | |
a4b8110e | 136 | static void |
c193c972 | 137 | lineAdd(Line ** L, const char *str) |
6b53c392 | 138 | { |
a4b8110e | 139 | while (*L) |
62e76326 | 140 | L = &(*L)->next; |
141 | ||
e6ccf245 | 142 | *L = (Line *)xcalloc(1, sizeof(Line)); |
62e76326 | 143 | |
6b53c392 | 144 | (*L)->data = xstrdup(str); |
145 | } | |
146 | ||
41bd17a4 | 147 | static void |
148 | checkDepend(const char *directive, const char *name, const Type *types, const Entry *entries) | |
149 | { | |
150 | const Type *type; | |
151 | for (type = types; type; type = type->next) { | |
26ac0430 AJ |
152 | const TypeDep *dep; |
153 | if (strcmp(type->name, name) != 0) | |
154 | continue; | |
155 | for (dep = type->depend; dep; dep = dep->next) { | |
156 | const Entry *entry; | |
157 | for (entry = entries; entry; entry = entry->next) { | |
158 | if (strcmp(entry->name, dep->name) == 0) | |
159 | break; | |
160 | } | |
161 | if (!entry) { | |
7ff7a211 | 162 | std::cerr << "ERROR: '" << directive << "' (" << name << ") depends on '" << dep->name << "'\n"; |
26ac0430 AJ |
163 | exit(1); |
164 | } | |
165 | } | |
166 | return; | |
41bd17a4 | 167 | } |
7ff7a211 | 168 | std::cerr << "ERROR: Dependencies for cf.data type '" << name << "' used in ' " << directive << "' not defined\n" ; |
41bd17a4 | 169 | exit(1); |
170 | } | |
171 | ||
509fba1a HN |
172 | static void |
173 | usage(const char *program_name) | |
174 | { | |
7ff7a211 | 175 | std::cerr << "Usage: " << program_name << " cf.data cf.data.depend\n"; |
509fba1a HN |
176 | exit(1); |
177 | } | |
178 | ||
934b03fc | 179 | int |
180 | main(int argc, char *argv[]) | |
181 | { | |
509fba1a | 182 | char *input_filename; |
c193c972 | 183 | const char *output_filename = _PATH_PARSER; |
184 | const char *conf_filename = _PATH_SQUID_CONF; | |
509fba1a HN |
185 | const char *conf_filename_short = _PATH_SQUID_CONF_SHORT; |
186 | const char *type_depend; | |
934b03fc | 187 | int linenum = 0; |
188 | Entry *entries = NULL; | |
189 | Entry *curr = NULL; | |
41bd17a4 | 190 | Type *types = NULL; |
934b03fc | 191 | enum State state; |
f1dc9b30 | 192 | int rc = 0; |
9906e724 | 193 | char *ptr = NULL; |
41bd17a4 | 194 | char buff[MAX_LINE]; |
7ff7a211 | 195 | std::ifstream fp; |
41bd17a4 | 196 | |
509fba1a | 197 | if (argc != 3) |
c98dcee3 | 198 | usage(argv[0]); |
509fba1a HN |
199 | |
200 | input_filename = argv[1]; | |
201 | type_depend = argv[2]; | |
41bd17a4 | 202 | |
203 | /*-------------------------------------------------------------------* | |
204 | * Parse type dependencies | |
205 | *-------------------------------------------------------------------*/ | |
7ff7a211 FC |
206 | fp.open(type_depend, std::ifstream::in); |
207 | if (fp.fail()) { | |
ce02627f FC |
208 | std::cerr << "error while opening type dependencies file '" << |
209 | input_filename << "': " << strerror(errno) << std::endl; | |
41bd17a4 | 210 | exit(1); |
211 | } | |
212 | ||
7ff7a211 FC |
213 | while (fp.good()) { |
214 | fp.getline(buff,MAX_LINE); | |
26ac0430 AJ |
215 | const char *type = strtok(buff, WS); |
216 | const char *dep; | |
217 | if (!type || type[0] == '#') | |
218 | continue; | |
219 | Type *t = (Type *)xcalloc(1, sizeof(*t)); | |
220 | t->name = xstrdup(type); | |
221 | while ((dep = strtok(NULL, WS)) != NULL) { | |
222 | TypeDep *d = (TypeDep *)xcalloc(1, sizeof(*d)); | |
223 | d->name = xstrdup(dep); | |
224 | d->next = t->depend; | |
225 | t->depend = d; | |
226 | } | |
227 | t->next = types; | |
228 | types = t; | |
41bd17a4 | 229 | } |
7ff7a211 | 230 | fp.close(); |
934b03fc | 231 | |
232 | /*-------------------------------------------------------------------* | |
233 | * Parse input file | |
234 | *-------------------------------------------------------------------*/ | |
235 | ||
236 | /* Open input file */ | |
62e76326 | 237 | |
7ff7a211 FC |
238 | fp.open(input_filename, std::ifstream::in); |
239 | if (fp.fail()) { | |
ce02627f FC |
240 | std::cerr << "error while opening input file '" << |
241 | input_filename << "': " << strerror(errno) << std::endl; | |
62e76326 | 242 | exit(1); |
934b03fc | 243 | } |
62e76326 | 244 | |
934b03fc | 245 | state = sSTART; |
62e76326 | 246 | |
7ff7a211 | 247 | while (fp.getline(buff,MAX_LINE), fp.good() && state != sEXIT) { |
62e76326 | 248 | char *t; |
249 | ||
62e76326 | 250 | linenum++; |
251 | ||
252 | if ((t = strchr(buff, '\n'))) | |
253 | *t = '\0'; | |
254 | ||
255 | switch (state) { | |
256 | ||
257 | case sSTART: | |
258 | ||
259 | if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { | |
260 | /* ignore empty and comment lines */ | |
261 | (void) 0; | |
262 | } else if (!strncmp(buff, "NAME:", 5)) { | |
263 | char *name, *aliasname; | |
264 | ||
265 | if ((name = strtok(buff + 5, WS)) == NULL) { | |
7ff7a211 | 266 | std::cerr << "Error in input file\n"; |
62e76326 | 267 | exit(1); |
268 | } | |
269 | ||
bc79fb54 | 270 | curr = (Entry *)xcalloc(1, sizeof(Entry)); |
62e76326 | 271 | curr->name = xstrdup(name); |
272 | ||
273 | while ((aliasname = strtok(NULL, WS)) != NULL) { | |
bc79fb54 | 274 | EntryAlias *alias = (EntryAlias *)xcalloc(1, sizeof(EntryAlias)); |
62e76326 | 275 | alias->next = curr->alias; |
276 | alias->name = xstrdup(aliasname); | |
277 | curr->alias = alias; | |
278 | } | |
279 | ||
280 | state = s1; | |
281 | } else if (!strcmp(buff, "EOF")) { | |
282 | state = sEXIT; | |
283 | } else if (!strcmp(buff, "COMMENT_START")) { | |
bc79fb54 | 284 | curr = (Entry *)xcalloc(1, sizeof(Entry)); |
62e76326 | 285 | curr->name = xstrdup("comment"); |
286 | curr->loc = xstrdup("none"); | |
287 | state = sDOC; | |
288 | } else { | |
7ff7a211 FC |
289 | std::cerr << "Error on line " << linenum << std::endl << |
290 | "--> " << buff << std::endl; | |
62e76326 | 291 | exit(1); |
292 | } | |
293 | ||
294 | break; | |
295 | ||
296 | case s1: | |
297 | ||
298 | if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { | |
299 | /* ignore empty and comment lines */ | |
300 | (void) 0; | |
301 | } else if (!strncmp(buff, "COMMENT:", 8)) { | |
302 | ptr = buff + 8; | |
303 | ||
304 | while (xisspace(*ptr)) | |
305 | ptr++; | |
306 | ||
307 | curr->comment = xstrdup(ptr); | |
308 | } else if (!strncmp(buff, "DEFAULT:", 8)) { | |
309 | ptr = buff + 8; | |
310 | ||
311 | while (xisspace(*ptr)) | |
312 | ptr++; | |
313 | ||
314 | curr->default_value = xstrdup(ptr); | |
315 | } else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) { | |
316 | ptr = buff + 16; | |
317 | ||
318 | while (xisspace(*ptr)) | |
319 | ptr++; | |
320 | ||
321 | lineAdd(&curr->default_if_none, ptr); | |
322 | } else if (!strncmp(buff, "LOC:", 4)) { | |
323 | if ((ptr = strtok(buff + 4, WS)) == NULL) { | |
7ff7a211 | 324 | std::cerr << "Error on line " << linenum << std::endl; |
62e76326 | 325 | exit(1); |
326 | } | |
327 | ||
328 | curr->loc = xstrdup(ptr); | |
329 | } else if (!strncmp(buff, "TYPE:", 5)) { | |
330 | if ((ptr = strtok(buff + 5, WS)) == NULL) { | |
7ff7a211 | 331 | std::cerr << "Error on line " << linenum << std::endl; |
62e76326 | 332 | exit(1); |
333 | } | |
334 | ||
335 | /* hack to support arrays, rather than pointers */ | |
336 | if (0 == strcmp(ptr + strlen(ptr) - 2, "[]")) { | |
337 | curr->array_flag = 1; | |
338 | *(ptr + strlen(ptr) - 2) = '\0'; | |
339 | } | |
340 | ||
26ac0430 | 341 | checkDepend(curr->name, ptr, types, entries); |
62e76326 | 342 | curr->type = xstrdup(ptr); |
343 | } else if (!strncmp(buff, "IFDEF:", 6)) { | |
344 | if ((ptr = strtok(buff + 6, WS)) == NULL) { | |
7ff7a211 | 345 | std::cerr << "Error on line " << linenum << std::endl; |
62e76326 | 346 | exit(1); |
347 | } | |
348 | ||
349 | curr->ifdef = xstrdup(ptr); | |
350 | } else if (!strcmp(buff, "DOC_START")) { | |
351 | state = sDOC; | |
352 | } else if (!strcmp(buff, "DOC_NONE")) { | |
353 | /* add to list of entries */ | |
354 | curr->next = entries; | |
355 | entries = curr; | |
356 | state = sSTART; | |
357 | } else { | |
7ff7a211 | 358 | std::cerr << "Error on line " << linenum << std::endl; |
62e76326 | 359 | exit(1); |
360 | } | |
361 | ||
362 | break; | |
363 | ||
364 | case sDOC: | |
365 | ||
366 | if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) { | |
367 | Line *head = NULL; | |
368 | Line *line = curr->doc; | |
369 | /* reverse order of doc lines */ | |
370 | ||
371 | while (line != NULL) { | |
372 | Line *tmp; | |
373 | tmp = line->next; | |
374 | line->next = head; | |
375 | head = line; | |
376 | line = tmp; | |
377 | } | |
378 | ||
379 | curr->doc = head; | |
380 | /* add to list of entries */ | |
381 | curr->next = entries; | |
382 | entries = curr; | |
383 | state = sSTART; | |
384 | } else if (!strcmp(buff, "NOCOMMENT_START")) { | |
385 | state = sNOCOMMENT; | |
386 | } else { | |
bc79fb54 | 387 | Line *line = (Line *)xcalloc(1, sizeof(Line)); |
62e76326 | 388 | line->data = xstrdup(buff); |
389 | line->next = curr->doc; | |
390 | curr->doc = line; | |
391 | } | |
392 | ||
393 | break; | |
394 | ||
395 | case sNOCOMMENT: | |
396 | ||
397 | if (!strcmp(buff, "NOCOMMENT_END")) { | |
398 | Line *head = NULL; | |
399 | Line *line = curr->nocomment; | |
400 | /* reverse order of lines */ | |
401 | ||
402 | while (line != NULL) { | |
403 | Line *tmp; | |
404 | tmp = line->next; | |
405 | line->next = head; | |
406 | head = line; | |
407 | line = tmp; | |
408 | } | |
409 | ||
410 | curr->nocomment = head; | |
411 | state = sDOC; | |
412 | } else { | |
bc79fb54 | 413 | Line *line = (Line *)xcalloc(1, sizeof(Line)); |
62e76326 | 414 | line->data = xstrdup(buff); |
415 | line->next = curr->nocomment; | |
416 | curr->nocomment = line; | |
417 | } | |
418 | ||
419 | break; | |
420 | ||
421 | case sEXIT: | |
422 | assert(0); /* should never get here */ | |
423 | break; | |
424 | } | |
7ff7a211 | 425 | |
934b03fc | 426 | } |
62e76326 | 427 | |
934b03fc | 428 | if (state != sEXIT) { |
7ff7a211 | 429 | std::cerr << "Error: unexpected EOF\n"; |
62e76326 | 430 | exit(1); |
934b03fc | 431 | } else { |
62e76326 | 432 | /* reverse order of entries */ |
433 | Entry *head = NULL; | |
434 | ||
435 | while (entries != NULL) { | |
436 | Entry *tmp; | |
437 | ||
438 | tmp = entries->next; | |
439 | entries->next = head; | |
440 | head = entries; | |
441 | entries = tmp; | |
442 | } | |
443 | ||
444 | entries = head; | |
934b03fc | 445 | } |
62e76326 | 446 | |
7ff7a211 | 447 | fp.close(); |
934b03fc | 448 | |
449 | /*-------------------------------------------------------------------* | |
450 | * Generate default_all() | |
451 | * Generate parse_line() | |
f53b06f9 | 452 | * Generate dump_config() |
0153d498 | 453 | * Generate free_all() |
e321c7d4 | 454 | * Generate example squid.conf.default file |
934b03fc | 455 | *-------------------------------------------------------------------*/ |
456 | ||
457 | /* Open output x.c file */ | |
62e76326 | 458 | |
7ff7a211 FC |
459 | std::ofstream fout(output_filename,std::ostream::out); |
460 | if (!fout.good()) { | |
ce02627f FC |
461 | std::cerr << "error while opening output .c file '" << |
462 | output_filename << "': " << strerror(errno) << std::endl; | |
62e76326 | 463 | exit(1); |
934b03fc | 464 | } |
62e76326 | 465 | |
7ff7a211 FC |
466 | fout << "/*\n" << |
467 | " * Generated automatically from " << input_filename << " by " << | |
468 | argv[0] << "\n" | |
62e76326 | 469 | " *\n" |
470 | " * Abstract: This file contains routines used to configure the\n" | |
471 | " * variables in the squid server.\n" | |
472 | " */\n" | |
bf0ba190 AJ |
473 | "\n" |
474 | "#include \"config.h\"\n" | |
7ff7a211 | 475 | "\n"; |
62e76326 | 476 | |
7ff7a211 | 477 | rc = gen_default(entries, fout); |
62e76326 | 478 | |
7ff7a211 | 479 | gen_default_if_none(entries, fout); |
62e76326 | 480 | |
7ff7a211 | 481 | gen_parse(entries, fout); |
62e76326 | 482 | |
7ff7a211 | 483 | gen_dump(entries, fout); |
62e76326 | 484 | |
7ff7a211 | 485 | gen_free(entries, fout); |
62e76326 | 486 | |
7ff7a211 | 487 | fout.close(); |
934b03fc | 488 | |
489 | /* Open output x.conf file */ | |
7ff7a211 FC |
490 | fout.open(conf_filename,std::ostream::out); |
491 | if (!fout.good()) { | |
ce02627f FC |
492 | std::cerr << "error while opening output conf file '" << |
493 | output_filename << "': " << strerror(errno) << std::endl; | |
62e76326 | 494 | exit(1); |
934b03fc | 495 | } |
62e76326 | 496 | |
7ff7a211 | 497 | gen_conf(entries, fout, 1); |
62e76326 | 498 | |
7ff7a211 | 499 | fout.close(); |
934b03fc | 500 | |
7ff7a211 FC |
501 | fout.open(conf_filename_short,std::ostream::out); |
502 | if (!fout.good()) { | |
ce02627f FC |
503 | std::cerr << "error while opening output short conf file '" << |
504 | output_filename << "': " << strerror(errno) << std::endl; | |
509fba1a HN |
505 | exit(1); |
506 | } | |
7ff7a211 FC |
507 | gen_conf(entries, fout, 0); |
508 | fout.close(); | |
509fba1a | 509 | |
f1dc9b30 | 510 | return (rc); |
934b03fc | 511 | } |
512 | ||
f1dc9b30 | 513 | static int |
7ff7a211 | 514 | gen_default(Entry * head, std::ostream &fout) |
934b03fc | 515 | { |
516 | Entry *entry; | |
f1dc9b30 | 517 | int rc = 0; |
7ff7a211 | 518 | fout << "static void\n" |
62e76326 | 519 | "default_line(const char *s)\n" |
520 | "{\n" | |
521 | "\tLOCAL_ARRAY(char, tmp_line, BUFSIZ);\n" | |
522 | "\txstrncpy(tmp_line, s, BUFSIZ);\n" | |
523 | "\txstrncpy(config_input_line, s, BUFSIZ);\n" | |
524 | "\tconfig_lineno++;\n" | |
525 | "\tparse_line(tmp_line);\n" | |
7ff7a211 FC |
526 | "}\n"; |
527 | fout << "static void\n" | |
62e76326 | 528 | "default_all(void)\n" |
529 | "{\n" | |
530 | "\tcfg_filename = \"Default Configuration\";\n" | |
7ff7a211 | 531 | "\tconfig_lineno = 0;\n"; |
62e76326 | 532 | |
934b03fc | 533 | for (entry = head; entry != NULL; entry = entry->next) { |
62e76326 | 534 | assert(entry->name); |
535 | assert(entry != entry->next); | |
536 | ||
537 | if (!strcmp(entry->name, "comment")) | |
538 | continue; | |
539 | ||
76f44481 AJ |
540 | if (!strcmp(entry->type, "obsolete")) |
541 | continue; | |
542 | ||
62e76326 | 543 | if (entry->loc == NULL) { |
7ff7a211 | 544 | std::cerr << "NO LOCATION FOR " << entry->name << std::endl; |
62e76326 | 545 | rc |= 1; |
546 | continue; | |
547 | } | |
548 | ||
c58a4b53 | 549 | if (entry->default_value == NULL && entry->default_if_none == NULL) { |
7ff7a211 | 550 | std::cerr << "NO DEFAULT FOR " << entry->name << std::endl; |
62e76326 | 551 | rc |= 1; |
552 | continue; | |
553 | } | |
554 | ||
c58a4b53 | 555 | if (entry->default_value == NULL || strcmp(entry->default_value, "none") == 0) { |
7ff7a211 | 556 | fout << "\t/* No default for " << entry->name << " */\n"; |
62e76326 | 557 | } else { |
c58a4b53 | 558 | if (entry->ifdef) |
7ff7a211 | 559 | fout << "#if " << entry->ifdef << std::endl; |
c58a4b53 | 560 | |
7ff7a211 FC |
561 | fout << "\tdefault_line(\"" << entry->name << " " << |
562 | entry->default_value << "\");\n"; | |
62e76326 | 563 | |
c58a4b53 | 564 | if (entry->ifdef) |
7ff7a211 | 565 | fout << "#endif\n"; } |
934b03fc | 566 | } |
62e76326 | 567 | |
7ff7a211 FC |
568 | fout << "\tcfg_filename = NULL;\n" |
569 | "}\n\n"; | |
f1dc9b30 | 570 | return rc; |
934b03fc | 571 | } |
572 | ||
f53b06f9 | 573 | static void |
7ff7a211 | 574 | gen_default_if_none(Entry * head, std::ostream &fout) |
f53b06f9 | 575 | { |
576 | Entry *entry; | |
6b53c392 | 577 | Line *line; |
7ff7a211 | 578 | fout << "static void\n" |
62e76326 | 579 | "defaults_if_none(void)\n" |
7ff7a211 | 580 | "{\n"; |
62e76326 | 581 | |
f53b06f9 | 582 | for (entry = head; entry != NULL; entry = entry->next) { |
62e76326 | 583 | assert(entry->name); |
76f44481 AJ |
584 | |
585 | if (!entry->loc) | |
586 | continue; | |
62e76326 | 587 | |
588 | if (entry->default_if_none == NULL) | |
589 | continue; | |
590 | ||
591 | if (entry->ifdef) | |
7ff7a211 | 592 | fout << "#if " << entry->ifdef << std::endl; |
62e76326 | 593 | |
594 | if (entry->default_if_none) { | |
7ff7a211 FC |
595 | fout << "\tif (check_null_" << entry->type << "(" << |
596 | entry->loc << ")) {\n"; | |
62e76326 | 597 | |
598 | for (line = entry->default_if_none; line; line = line->next) | |
7ff7a211 FC |
599 | fout << "\t\tdefault_line(\"" << entry->name << " " << |
600 | line->data <<"\");\n"; | |
62e76326 | 601 | |
7ff7a211 | 602 | fout << "\t}\n"; |
62e76326 | 603 | } |
604 | ||
605 | if (entry->ifdef) | |
7ff7a211 | 606 | fout << "#endif\n"; |
f53b06f9 | 607 | } |
62e76326 | 608 | |
7ff7a211 | 609 | fout << "}\n\n"; |
f53b06f9 | 610 | } |
611 | ||
147a3e90 | 612 | void |
7ff7a211 | 613 | gen_parse_alias(char *name, EntryAlias *alias, Entry *entry, std::ostream &fout) |
934b03fc | 614 | { |
7ff7a211 | 615 | fout << "\tif (!strcmp(token, \"" << name << "\")) {\n"; |
62e76326 | 616 | |
76f44481 | 617 | if (strcmp(entry->type,"obsolete") == 0) { |
7ff7a211 | 618 | fout << "\t\tdebugs(0, DBG_CRITICAL, \"ERROR: Directive '" << name << "' is obsolete.\");\n"; |
76f44481 AJ |
619 | for (Line *line = entry->doc; line != NULL; line = line->next) { |
620 | // offset line to strip initial whitespace tab byte | |
7ff7a211 | 621 | fout << "\t\tdebugs(0, opt_parse_cfg_only?0:1, \"" << name << " : " << &line->data[1] << "\");\n"; |
76f44481 | 622 | } |
7ff7a211 | 623 | fout << "\t\tparse_obsolete(token);\n"; |
76f44481 | 624 | } else if (!entry->loc || strcmp(entry->loc, "none") == 0) { |
7ff7a211 | 625 | fout << "\t\tparse_" << entry->type << "();\n"; |
62e76326 | 626 | } else { |
7ff7a211 FC |
627 | fout << "\t\tparse_" << entry->type << "(&" << entry->loc << |
628 | (entry->array_flag ? "[0]" : "") << ");\n"; | |
62e76326 | 629 | } |
630 | ||
7ff7a211 FC |
631 | fout << "\t\treturn 1;\n"; |
632 | fout << "\t};\n"; | |
147a3e90 | 633 | } |
634 | ||
635 | void | |
7ff7a211 | 636 | gen_parse_entry(Entry *entry, std::ostream &fout) |
147a3e90 | 637 | { |
62e76326 | 638 | if (strcmp(entry->name, "comment") == 0) |
639 | return; | |
640 | ||
641 | if (entry->ifdef) | |
7ff7a211 | 642 | fout << "#if " << entry->ifdef << std::endl; |
62e76326 | 643 | |
644 | char *name = entry->name; | |
645 | ||
646 | EntryAlias *alias = entry->alias; | |
647 | ||
62e76326 | 648 | bool more; |
649 | ||
650 | do { | |
7ff7a211 | 651 | gen_parse_alias (name, alias,entry, fout); |
62e76326 | 652 | more = false; |
653 | ||
654 | if (alias) { | |
655 | name = alias->name; | |
656 | alias = alias->next; | |
657 | more = true; | |
658 | } | |
659 | } while (more); | |
660 | ||
661 | if (entry->ifdef) | |
7ff7a211 | 662 | fout << "#endif\n"; |
147a3e90 | 663 | } |
664 | ||
665 | static void | |
7ff7a211 | 666 | gen_parse(Entry * head, std::ostream &fout) |
147a3e90 | 667 | { |
7ff7a211 | 668 | fout << |
62e76326 | 669 | "static int\n" |
670 | "parse_line(char *buff)\n" | |
671 | "{\n" | |
672 | "\tchar\t*token;\n" | |
62e76326 | 673 | "\tif ((token = strtok(buff, w_space)) == NULL) \n" |
7ff7a211 | 674 | "\t\treturn 1;\t/* ignore empty lines */\n"; |
147a3e90 | 675 | |
676 | for (Entry *entry = head; entry != NULL; entry = entry->next) | |
7ff7a211 FC |
677 | gen_parse_entry (entry, fout); |
678 | ||
679 | fout << "\treturn 0; /* failure */\n" | |
680 | "}\n\n"; | |
934b03fc | 681 | |
934b03fc | 682 | } |
683 | ||
684 | static void | |
7ff7a211 | 685 | gen_dump(Entry * head, std::ostream &fout) |
934b03fc | 686 | { |
687 | Entry *entry; | |
7ff7a211 | 688 | fout << |
62e76326 | 689 | "static void\n" |
690 | "dump_config(StoreEntry *entry)\n" | |
691 | "{\n" | |
7ff7a211 | 692 | " debugs(5, 4, HERE);\n"; |
62e76326 | 693 | |
934b03fc | 694 | for (entry = head; entry != NULL; entry = entry->next) { |
62e76326 | 695 | |
76f44481 | 696 | if (!entry->loc || strcmp(entry->loc, "none") == 0) |
62e76326 | 697 | continue; |
698 | ||
699 | if (strcmp(entry->name, "comment") == 0) | |
700 | continue; | |
701 | ||
702 | if (entry->ifdef) | |
7ff7a211 | 703 | fout << "#if " << entry->ifdef << std::endl; |
62e76326 | 704 | |
7ff7a211 FC |
705 | fout << "\tdump_" << entry->type << "(entry, \"" << entry->name << |
706 | "\", " << entry->loc << ");\n"; | |
62e76326 | 707 | |
708 | if (entry->ifdef) | |
7ff7a211 | 709 | fout << "#endif\n"; |
934b03fc | 710 | } |
62e76326 | 711 | |
7ff7a211 | 712 | fout << "}\n\n"; |
934b03fc | 713 | } |
714 | ||
0153d498 | 715 | static void |
7ff7a211 | 716 | gen_free(Entry * head, std::ostream &fout) |
0153d498 | 717 | { |
718 | Entry *entry; | |
7ff7a211 | 719 | fout << |
62e76326 | 720 | "static void\n" |
721 | "free_all(void)\n" | |
722 | "{\n" | |
7ff7a211 | 723 | " debugs(5, 4, HERE);\n"; |
62e76326 | 724 | |
0153d498 | 725 | for (entry = head; entry != NULL; entry = entry->next) { |
76f44481 | 726 | if (!entry->loc || strcmp(entry->loc, "none") == 0) |
62e76326 | 727 | continue; |
728 | ||
729 | if (strcmp(entry->name, "comment") == 0) | |
730 | continue; | |
731 | ||
732 | if (entry->ifdef) | |
7ff7a211 | 733 | fout << "#if " << entry->ifdef << std::endl; |
62e76326 | 734 | |
7ff7a211 FC |
735 | fout << "\tfree_" << entry->type << "(&" << entry->loc << |
736 | (entry->array_flag ? "[0]" : "") << ");\n"; | |
62e76326 | 737 | |
738 | if (entry->ifdef) | |
7ff7a211 | 739 | fout << "#endif\n"; |
0153d498 | 740 | } |
62e76326 | 741 | |
7ff7a211 | 742 | fout << "}\n\n"; |
0153d498 | 743 | } |
744 | ||
a4b8110e | 745 | static int |
746 | defined(char *name) | |
6b53c392 | 747 | { |
a4b8110e | 748 | int i = 0; |
62e76326 | 749 | |
a4b8110e | 750 | if (!name) |
62e76326 | 751 | return 1; |
752 | ||
a4b8110e | 753 | for (i = 0; strcmp(defines[i].name, name) != 0; i++) { |
62e76326 | 754 | assert(defines[i].name); |
a4b8110e | 755 | } |
62e76326 | 756 | |
a4b8110e | 757 | return defines[i].defined; |
6b53c392 | 758 | } |
759 | ||
a4b8110e | 760 | static const char * |
761 | available_if(char *name) | |
6b53c392 | 762 | { |
a4b8110e | 763 | int i = 0; |
764 | assert(name); | |
62e76326 | 765 | |
a4b8110e | 766 | for (i = 0; strcmp(defines[i].name, name) != 0; i++) { |
62e76326 | 767 | assert(defines[i].name); |
a4b8110e | 768 | } |
62e76326 | 769 | |
a4b8110e | 770 | return defines[i].enable; |
6b53c392 | 771 | } |
772 | ||
934b03fc | 773 | static void |
7ff7a211 | 774 | gen_conf(Entry * head, std::ostream &fout, bool verbose_output) |
934b03fc | 775 | { |
776 | Entry *entry; | |
6b53c392 | 777 | char buf[8192]; |
778 | Line *def = NULL; | |
934b03fc | 779 | |
780 | for (entry = head; entry != NULL; entry = entry->next) { | |
62e76326 | 781 | Line *line; |
26ac0430 | 782 | int enabled = 1; |
62e76326 | 783 | |
784 | if (!strcmp(entry->name, "comment")) | |
785 | (void) 0; | |
76f44481 AJ |
786 | else if (!strcmp(entry->name, "obsolete")) |
787 | (void) 0; | |
c98dcee3 | 788 | else if (verbose_output) { |
7ff7a211 | 789 | fout << "# TAG: " << entry->name; |
62e76326 | 790 | |
c98dcee3 | 791 | if (entry->comment) |
7ff7a211 | 792 | fout << "\t" << entry->comment; |
62e76326 | 793 | |
7ff7a211 | 794 | fout << std::endl; |
c98dcee3 | 795 | } |
62e76326 | 796 | |
c98dcee3 A |
797 | if (!defined(entry->ifdef)) { |
798 | if (verbose_output) { | |
7ff7a211 FC |
799 | |
800 | fout << "# Note: This option is only available if " | |
801 | "Squid is rebuilt with the\n" << | |
802 | "# " << available_if(entry->ifdef) << "\n#\n"; | |
c98dcee3 A |
803 | } |
804 | enabled = 0; | |
62e76326 | 805 | } |
806 | ||
c98dcee3 A |
807 | if (verbose_output) { |
808 | for (line = entry->doc; line != NULL; line = line->next) { | |
7ff7a211 | 809 | fout << "#" << line->data << std::endl; |
c98dcee3 A |
810 | } |
811 | } | |
62e76326 | 812 | |
813 | if (entry->default_value && strcmp(entry->default_value, "none") != 0) { | |
3db24c0f | 814 | snprintf(buf, sizeof(buf), "%s %s", entry->name, entry->default_value); |
62e76326 | 815 | lineAdd(&def, buf); |
816 | } | |
817 | ||
818 | if (entry->default_if_none) { | |
819 | for (line = entry->default_if_none; line; line = line->next) { | |
3db24c0f | 820 | snprintf(buf, sizeof(buf), "%s %s", entry->name, line->data); |
62e76326 | 821 | lineAdd(&def, buf); |
822 | } | |
823 | } | |
824 | ||
62e76326 | 825 | if (!def && entry->doc && !entry->nocomment && |
826 | strcmp(entry->name, "comment") != 0) | |
827 | lineAdd(&def, "none"); | |
828 | ||
509fba1a | 829 | if (verbose_output && def && (entry->doc || entry->nocomment)) { |
7ff7a211 | 830 | fout << "#Default:\n"; |
62e76326 | 831 | while (def != NULL) { |
832 | line = def; | |
833 | def = line->next; | |
7ff7a211 | 834 | fout << "# " << line->data << std::endl; |
62e76326 | 835 | xfree(line->data); |
836 | xfree(line); | |
837 | } | |
62e76326 | 838 | } |
839 | ||
509fba1a | 840 | if (verbose_output && entry->nocomment) |
7ff7a211 | 841 | fout << "#" << std::endl; |
62e76326 | 842 | |
c98dcee3 A |
843 | if (enabled || verbose_output) { |
844 | for (line = entry->nocomment; line != NULL; line = line->next) { | |
8df44716 AJ |
845 | if (!line->data) |
846 | continue; | |
c98dcee3 | 847 | if (!enabled && line->data[0] != '#') |
7ff7a211 | 848 | fout << "#" << line->data << std::endl; |
c98dcee3 | 849 | else |
7ff7a211 | 850 | fout << line->data << std::endl; |
c98dcee3 A |
851 | } |
852 | } | |
62e76326 | 853 | |
509fba1a | 854 | if (verbose_output && entry->doc != NULL) { |
7ff7a211 | 855 | fout << std::endl; |
62e76326 | 856 | } |
934b03fc | 857 | } |
858 | } |