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