]>
Commit | Line | Data |
---|---|---|
f740a279 | 1 | |
934b03fc | 2 | /* |
2b6662ba | 3 | * $Id: cf_gen.cc,v 1.40 2001/01/12 00:37:15 wessels Exp $ |
934b03fc | 4 | * |
f740a279 | 5 | * DEBUG: none Generate squid.conf and cf_parser.c |
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. | |
3a278cb8 | 39 | * (ie it creates the squid.conf file from the cf.data file) |
934b03fc | 40 | * |
41 | * The output files are as follows: | |
42 | * cf_parser.c - this file contains, default_all() which | |
f53b06f9 | 43 | * initializes variables with the default |
44 | * values, parse_line() that parses line from | |
45 | * squid.conf, dump_config that dumps the | |
934b03fc | 46 | * current the values of the variables. |
47 | * squid.conf - default configuration file given to the server | |
48 | * administrator. | |
49 | *****************************************************************************/ | |
50 | ||
6507d007 | 51 | #include "config.h" |
6b53c392 | 52 | #include "cf_gen_defines.h" |
6507d007 | 53 | |
54 | #if HAVE_STDIO_H | |
934b03fc | 55 | #include <stdio.h> |
6507d007 | 56 | #endif |
57 | #if HAVE_STRING_H | |
934b03fc | 58 | #include <string.h> |
6507d007 | 59 | #endif |
60 | #if HAVE_STDLIB_H | |
934b03fc | 61 | #include <stdlib.h> |
6507d007 | 62 | #endif |
63 | #if HAVE_CTYPE_H | |
934b03fc | 64 | #include <ctype.h> |
6507d007 | 65 | #endif |
66 | #if HAVE_ASSERT_H | |
934b03fc | 67 | #include <assert.h> |
6507d007 | 68 | #endif |
c4aefe96 | 69 | #if defined(_SQUID_CYGWIN_) |
70 | #include <io.h> | |
71 | #endif | |
72 | #if HAVE_FCNTL_H | |
73 | #include <fcntl.h> | |
74 | #endif | |
6507d007 | 75 | |
c68e9c6b | 76 | #include "util.h" |
77 | ||
934b03fc | 78 | #define MAX_LINE 1024 /* longest configuration line */ |
79 | #define _PATH_PARSER "cf_parser.c" | |
80 | #define _PATH_SQUID_CONF "squid.conf" | |
81 | ||
82 | enum State { | |
83 | sSTART, | |
84 | s1, | |
85 | sDOC, | |
c68e9c6b | 86 | sNOCOMMENT, |
934b03fc | 87 | sEXIT |
88 | }; | |
89 | ||
90 | typedef struct Line { | |
91 | char *data; | |
92 | struct Line *next; | |
93 | } Line; | |
94 | ||
95 | typedef struct Entry { | |
96 | char *name; | |
97 | char *type; | |
98 | char *loc; | |
99 | char *default_value; | |
6b53c392 | 100 | Line *default_if_none; |
934b03fc | 101 | char *comment; |
1df370e3 | 102 | char *ifdef; |
934b03fc | 103 | Line *doc; |
c68e9c6b | 104 | Line *nocomment; |
b3de4c9b | 105 | int array_flag; |
934b03fc | 106 | struct Entry *next; |
107 | } Entry; | |
108 | ||
109 | ||
110 | static const char WS[] = " \t"; | |
f1dc9b30 | 111 | static int gen_default(Entry *, FILE *); |
934b03fc | 112 | static void gen_parse(Entry *, FILE *); |
113 | static void gen_dump(Entry *, FILE *); | |
0153d498 | 114 | static void gen_free(Entry *, FILE *); |
934b03fc | 115 | static void gen_conf(Entry *, FILE *); |
f53b06f9 | 116 | static void gen_default_if_none(Entry *, FILE *); |
934b03fc | 117 | |
a4b8110e | 118 | static void |
119 | lineAdd(Line ** L, char *str) | |
6b53c392 | 120 | { |
a4b8110e | 121 | while (*L) |
122 | L = &(*L)->next; | |
123 | *L = xcalloc(1, sizeof(Line)); | |
6b53c392 | 124 | (*L)->data = xstrdup(str); |
125 | } | |
126 | ||
934b03fc | 127 | int |
128 | main(int argc, char *argv[]) | |
129 | { | |
130 | FILE *fp; | |
131 | char *input_filename = argv[1]; | |
132 | char *output_filename = _PATH_PARSER; | |
133 | char *conf_filename = _PATH_SQUID_CONF; | |
134 | int linenum = 0; | |
135 | Entry *entries = NULL; | |
136 | Entry *curr = NULL; | |
137 | enum State state; | |
f1dc9b30 | 138 | int rc = 0; |
9906e724 | 139 | char *ptr = NULL; |
cd377065 | 140 | #ifdef _SQUID_OS2_ |
141 | const char *rmode = "rt"; | |
142 | #else | |
143 | const char *rmode = "r"; | |
144 | #endif | |
934b03fc | 145 | |
146 | /*-------------------------------------------------------------------* | |
147 | * Parse input file | |
148 | *-------------------------------------------------------------------*/ | |
149 | ||
150 | /* Open input file */ | |
cd377065 | 151 | if ((fp = fopen(input_filename, rmode)) == NULL) { |
934b03fc | 152 | perror(input_filename); |
153 | exit(1); | |
154 | } | |
c4aefe96 | 155 | #if defined(_SQUID_CYGWIN_) |
156 | setmode(fileno(fp), O_TEXT); | |
157 | #endif | |
934b03fc | 158 | state = sSTART; |
159 | while (feof(fp) == 0 && state != sEXIT) { | |
160 | char buff[MAX_LINE]; | |
ff11b0ff | 161 | char *t; |
162 | if (NULL == fgets(buff, MAX_LINE, fp)) | |
163 | break; | |
934b03fc | 164 | linenum++; |
69d80593 | 165 | if ((t = strchr(buff, '\n'))) |
ff11b0ff | 166 | *t = '\0'; |
934b03fc | 167 | switch (state) { |
168 | case sSTART: | |
169 | if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { | |
170 | /* ignore empty and comment lines */ | |
79d39a72 | 171 | (void) 0; |
934b03fc | 172 | } else if (!strncmp(buff, "NAME:", 5)) { |
173 | char *name; | |
934b03fc | 174 | if ((name = strtok(buff + 5, WS)) == NULL) { |
175 | printf("Error in input file\n"); | |
176 | exit(1); | |
177 | } | |
14a31364 | 178 | curr = calloc(1, sizeof(Entry)); |
c68e9c6b | 179 | curr->name = xstrdup(name); |
934b03fc | 180 | state = s1; |
934b03fc | 181 | } else if (!strcmp(buff, "EOF")) { |
182 | state = sEXIT; | |
0f74202c | 183 | } else if (!strcmp(buff, "COMMENT_START")) { |
184 | curr = calloc(1, sizeof(Entry)); | |
c68e9c6b | 185 | curr->name = xstrdup("comment"); |
186 | curr->loc = xstrdup("none"); | |
0f74202c | 187 | state = sDOC; |
934b03fc | 188 | } else { |
189 | printf("Error on line %d\n", linenum); | |
e0d26b98 | 190 | printf("--> %s\n", buff); |
934b03fc | 191 | exit(1); |
192 | } | |
193 | break; | |
194 | ||
195 | case s1: | |
196 | if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) { | |
197 | /* ignore empty and comment lines */ | |
79d39a72 | 198 | (void) 0; |
934b03fc | 199 | } else if (!strncmp(buff, "COMMENT:", 8)) { |
9906e724 | 200 | ptr = buff + 8; |
b6a2f15e | 201 | while (xisspace(*ptr)) |
9906e724 | 202 | ptr++; |
c68e9c6b | 203 | curr->comment = xstrdup(ptr); |
934b03fc | 204 | } else if (!strncmp(buff, "DEFAULT:", 8)) { |
9906e724 | 205 | ptr = buff + 8; |
b6a2f15e | 206 | while (xisspace(*ptr)) |
9906e724 | 207 | ptr++; |
c68e9c6b | 208 | curr->default_value = xstrdup(ptr); |
f53b06f9 | 209 | } else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) { |
210 | ptr = buff + 16; | |
b6a2f15e | 211 | while (xisspace(*ptr)) |
f53b06f9 | 212 | ptr++; |
6b53c392 | 213 | lineAdd(&curr->default_if_none, ptr); |
934b03fc | 214 | } else if (!strncmp(buff, "LOC:", 4)) { |
934b03fc | 215 | if ((ptr = strtok(buff + 4, WS)) == NULL) { |
216 | printf("Error on line %d\n", linenum); | |
217 | exit(1); | |
218 | } | |
c68e9c6b | 219 | curr->loc = xstrdup(ptr); |
934b03fc | 220 | } else if (!strncmp(buff, "TYPE:", 5)) { |
934b03fc | 221 | if ((ptr = strtok(buff + 5, WS)) == NULL) { |
222 | printf("Error on line %d\n", linenum); | |
223 | exit(1); | |
224 | } | |
b3de4c9b | 225 | /* hack to support arrays, rather than pointers */ |
226 | if (0 == strcmp(ptr + strlen(ptr) - 2, "[]")) { | |
227 | curr->array_flag = 1; | |
228 | *(ptr + strlen(ptr) - 2) = '\0'; | |
229 | } | |
c68e9c6b | 230 | curr->type = xstrdup(ptr); |
1df370e3 | 231 | } else if (!strncmp(buff, "IFDEF:", 6)) { |
232 | if ((ptr = strtok(buff + 6, WS)) == NULL) { | |
233 | printf("Error on line %d\n", linenum); | |
234 | exit(1); | |
235 | } | |
c68e9c6b | 236 | curr->ifdef = xstrdup(ptr); |
934b03fc | 237 | } else if (!strcmp(buff, "DOC_START")) { |
238 | state = sDOC; | |
934b03fc | 239 | } else if (!strcmp(buff, "DOC_NONE")) { |
240 | /* add to list of entries */ | |
241 | curr->next = entries; | |
242 | entries = curr; | |
934b03fc | 243 | state = sSTART; |
934b03fc | 244 | } else { |
245 | printf("Error on line %d\n", linenum); | |
246 | exit(1); | |
247 | } | |
248 | break; | |
249 | ||
250 | case sDOC: | |
0f74202c | 251 | if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) { |
934b03fc | 252 | Line *head = NULL; |
253 | Line *line = curr->doc; | |
934b03fc | 254 | /* reverse order of doc lines */ |
255 | while (line != NULL) { | |
256 | Line *tmp; | |
257 | tmp = line->next; | |
258 | line->next = head; | |
259 | head = line; | |
260 | line = tmp; | |
261 | } | |
262 | curr->doc = head; | |
934b03fc | 263 | /* add to list of entries */ |
264 | curr->next = entries; | |
265 | entries = curr; | |
934b03fc | 266 | state = sSTART; |
c68e9c6b | 267 | } else if (!strcmp(buff, "NOCOMMENT_START")) { |
268 | state = sNOCOMMENT; | |
934b03fc | 269 | } else { |
14a31364 | 270 | Line *line = calloc(1, sizeof(Line)); |
c68e9c6b | 271 | line->data = xstrdup(buff); |
934b03fc | 272 | line->next = curr->doc; |
273 | curr->doc = line; | |
274 | } | |
275 | break; | |
276 | ||
c68e9c6b | 277 | case sNOCOMMENT: |
278 | if (!strcmp(buff, "NOCOMMENT_END")) { | |
279 | Line *head = NULL; | |
280 | Line *line = curr->nocomment; | |
281 | /* reverse order of lines */ | |
282 | while (line != NULL) { | |
283 | Line *tmp; | |
284 | tmp = line->next; | |
285 | line->next = head; | |
286 | head = line; | |
287 | line = tmp; | |
288 | } | |
289 | curr->nocomment = head; | |
290 | state = sDOC; | |
291 | } else { | |
292 | Line *line = calloc(1, sizeof(Line)); | |
293 | line->data = xstrdup(buff); | |
294 | line->next = curr->nocomment; | |
295 | curr->nocomment = line; | |
296 | } | |
297 | break; | |
298 | ||
934b03fc | 299 | case sEXIT: |
300 | assert(0); /* should never get here */ | |
301 | break; | |
302 | } | |
303 | } | |
304 | if (state != sEXIT) { | |
305 | printf("Error unexpected EOF\n"); | |
306 | exit(1); | |
307 | } else { | |
308 | /* reverse order of entries */ | |
309 | Entry *head = NULL; | |
310 | ||
311 | while (entries != NULL) { | |
312 | Entry *tmp; | |
313 | ||
314 | tmp = entries->next; | |
315 | entries->next = head; | |
316 | head = entries; | |
317 | entries = tmp; | |
318 | } | |
319 | entries = head; | |
320 | } | |
321 | fclose(fp); | |
322 | ||
323 | /*-------------------------------------------------------------------* | |
324 | * Generate default_all() | |
325 | * Generate parse_line() | |
f53b06f9 | 326 | * Generate dump_config() |
0153d498 | 327 | * Generate free_all() |
934b03fc | 328 | * Generate example squid.conf file |
329 | *-------------------------------------------------------------------*/ | |
330 | ||
331 | /* Open output x.c file */ | |
332 | if ((fp = fopen(output_filename, "w")) == NULL) { | |
333 | perror(output_filename); | |
334 | exit(1); | |
335 | } | |
c4aefe96 | 336 | #if defined(_SQUID_CYGWIN_) |
337 | setmode(fileno(fp), O_TEXT); | |
338 | #endif | |
934b03fc | 339 | fprintf(fp, |
340 | "/*\n" | |
341 | " * Generated automatically from %s by %s\n" | |
342 | " *\n" | |
343 | " * Abstract: This file contains routines used to configure the\n" | |
344 | " * variables in the squid server.\n" | |
345 | " */\n" | |
346 | "\n", | |
347 | input_filename, argv[0] | |
348 | ); | |
f1dc9b30 | 349 | rc = gen_default(entries, fp); |
f53b06f9 | 350 | gen_default_if_none(entries, fp); |
934b03fc | 351 | gen_parse(entries, fp); |
352 | gen_dump(entries, fp); | |
0153d498 | 353 | gen_free(entries, fp); |
934b03fc | 354 | fclose(fp); |
355 | ||
356 | /* Open output x.conf file */ | |
357 | if ((fp = fopen(conf_filename, "w")) == NULL) { | |
358 | perror(conf_filename); | |
359 | exit(1); | |
360 | } | |
c4aefe96 | 361 | #if defined(_SQUID_CYGWIN_) |
362 | setmode(fileno(fp), O_TEXT); | |
363 | #endif | |
934b03fc | 364 | gen_conf(entries, fp); |
365 | fclose(fp); | |
366 | ||
f1dc9b30 | 367 | return (rc); |
934b03fc | 368 | } |
369 | ||
f1dc9b30 | 370 | static int |
934b03fc | 371 | gen_default(Entry * head, FILE * fp) |
372 | { | |
373 | Entry *entry; | |
f1dc9b30 | 374 | int rc = 0; |
b556b1e9 | 375 | fprintf(fp, |
d9586c3c | 376 | "static void\n" |
b556b1e9 | 377 | "default_line(const char *s)\n" |
378 | "{\n" | |
379 | "\tLOCAL_ARRAY(char, tmp_line, BUFSIZ);\n" | |
9906e724 | 380 | "\txstrncpy(tmp_line, s, BUFSIZ);\n" |
381 | "\txstrncpy(config_input_line, s, BUFSIZ);\n" | |
b556b1e9 | 382 | "\tconfig_lineno++;\n" |
9906e724 | 383 | "\tparse_line(tmp_line);\n" |
b556b1e9 | 384 | "}\n" |
385 | ); | |
934b03fc | 386 | fprintf(fp, |
d9586c3c | 387 | "static void\n" |
934b03fc | 388 | "default_all(void)\n" |
389 | "{\n" | |
1273d501 | 390 | "\tcfg_filename = \"Default Configuration\";\n" |
b556b1e9 | 391 | "\tconfig_lineno = 0;\n" |
934b03fc | 392 | ); |
393 | for (entry = head; entry != NULL; entry = entry->next) { | |
394 | assert(entry->name); | |
c68e9c6b | 395 | assert(entry != entry->next); |
3a278cb8 | 396 | |
0f74202c | 397 | if (!strcmp(entry->name, "comment")) |
3a278cb8 | 398 | continue; |
934b03fc | 399 | if (entry->loc == NULL) { |
400 | fprintf(stderr, "NO LOCATION FOR %s\n", entry->name); | |
f1dc9b30 | 401 | rc |= 1; |
934b03fc | 402 | continue; |
403 | } | |
404 | if (entry->default_value == NULL) { | |
405 | fprintf(stderr, "NO DEFAULT FOR %s\n", entry->name); | |
f1dc9b30 | 406 | rc |= 1; |
934b03fc | 407 | continue; |
408 | } | |
f1dc9b30 | 409 | assert(entry->default_value); |
1df370e3 | 410 | if (entry->ifdef) |
75339a46 | 411 | fprintf(fp, "#if %s\n", entry->ifdef); |
f1dc9b30 | 412 | if (strcmp(entry->default_value, "none") == 0) { |
413 | fprintf(fp, "\t/* No default for %s */\n", entry->name); | |
934b03fc | 414 | } else { |
b556b1e9 | 415 | fprintf(fp, "\tdefault_line(\"%s %s\");\n", |
934b03fc | 416 | entry->name, |
417 | entry->default_value); | |
f1dc9b30 | 418 | } |
1df370e3 | 419 | if (entry->ifdef) |
420 | fprintf(fp, "#endif\n"); | |
934b03fc | 421 | } |
1273d501 | 422 | fprintf(fp, "\tcfg_filename = NULL;\n"); |
934b03fc | 423 | fprintf(fp, "}\n\n"); |
f1dc9b30 | 424 | return rc; |
934b03fc | 425 | } |
426 | ||
f53b06f9 | 427 | static void |
428 | gen_default_if_none(Entry * head, FILE * fp) | |
429 | { | |
430 | Entry *entry; | |
6b53c392 | 431 | Line *line; |
f53b06f9 | 432 | fprintf(fp, |
d9586c3c | 433 | "static void\n" |
f53b06f9 | 434 | "defaults_if_none(void)\n" |
435 | "{\n" | |
436 | ); | |
437 | for (entry = head; entry != NULL; entry = entry->next) { | |
438 | assert(entry->name); | |
439 | assert(entry->loc); | |
440 | if (entry->default_if_none == NULL) | |
441 | continue; | |
1df370e3 | 442 | if (entry->ifdef) |
75339a46 | 443 | fprintf(fp, "#if %s\n", entry->ifdef); |
6b53c392 | 444 | if (entry->default_if_none) { |
445 | fprintf(fp, | |
446 | "\tif (check_null_%s(%s)) {\n", | |
447 | entry->type, | |
448 | entry->loc); | |
449 | for (line = entry->default_if_none; line; line = line->next) | |
450 | fprintf(fp, | |
451 | "\t\tdefault_line(\"%s %s\");\n", | |
452 | entry->name, | |
453 | line->data); | |
454 | fprintf(fp, "\t}\n"); | |
455 | } | |
1df370e3 | 456 | if (entry->ifdef) |
a4b8110e | 457 | fprintf(fp, "#endif\n"); |
f53b06f9 | 458 | } |
459 | fprintf(fp, "}\n\n"); | |
460 | } | |
461 | ||
934b03fc | 462 | static void |
463 | gen_parse(Entry * head, FILE * fp) | |
464 | { | |
465 | Entry *entry; | |
466 | ||
467 | fprintf(fp, | |
f8c4d483 | 468 | "static int\n" |
934b03fc | 469 | "parse_line(char *buff)\n" |
470 | "{\n" | |
471 | "\tint\tresult = 1;\n" | |
472 | "\tchar\t*token;\n" | |
1273d501 | 473 | "\tdebug(0,10)(\"parse_line: %%s\\n\", buff);\n" |
7b3942d3 | 474 | "\tif ((token = strtok(buff, w_space)) == NULL)\n" |
475 | "\t\t(void) 0;\t/* ignore empty lines */\n" | |
934b03fc | 476 | ); |
477 | ||
478 | for (entry = head; entry != NULL; entry = entry->next) { | |
0f74202c | 479 | if (strcmp(entry->name, "comment") == 0) |
480 | continue; | |
7b3942d3 | 481 | if (entry->ifdef) |
482 | fprintf(fp, "#if %s\n", entry->ifdef); | |
483 | fprintf(fp, "\telse if (!strcmp(token, \"%s\"))\n", | |
934b03fc | 484 | entry->name |
485 | ); | |
f1dc9b30 | 486 | assert(entry->loc); |
487 | if (strcmp(entry->loc, "none") == 0) { | |
934b03fc | 488 | fprintf(fp, |
489 | "\t\tparse_%s();\n", | |
490 | entry->type | |
491 | ); | |
0f74202c | 492 | } else { |
934b03fc | 493 | fprintf(fp, |
b3de4c9b | 494 | "\t\tparse_%s(&%s%s);\n", |
495 | entry->type, entry->loc, | |
496 | entry->array_flag ? "[0]" : "" | |
934b03fc | 497 | ); |
498 | } | |
1df370e3 | 499 | if (entry->ifdef) |
500 | fprintf(fp, "#endif\n"); | |
934b03fc | 501 | } |
502 | ||
503 | fprintf(fp, | |
7b3942d3 | 504 | "\telse\n" |
934b03fc | 505 | "\t\tresult = 0; /* failure */\n" |
934b03fc | 506 | "\treturn(result);\n" |
507 | "}\n\n" | |
508 | ); | |
509 | } | |
510 | ||
511 | static void | |
512 | gen_dump(Entry * head, FILE * fp) | |
513 | { | |
514 | Entry *entry; | |
934b03fc | 515 | fprintf(fp, |
5e29a294 | 516 | "static void\n" |
f53b06f9 | 517 | "dump_config(StoreEntry *entry)\n" |
934b03fc | 518 | "{\n" |
519 | ); | |
934b03fc | 520 | for (entry = head; entry != NULL; entry = entry->next) { |
f1dc9b30 | 521 | assert(entry->loc); |
522 | if (strcmp(entry->loc, "none") == 0) | |
523 | continue; | |
0f74202c | 524 | if (strcmp(entry->name, "comment") == 0) |
3a278cb8 | 525 | continue; |
1df370e3 | 526 | if (entry->ifdef) |
75339a46 | 527 | fprintf(fp, "#if %s\n", entry->ifdef); |
f53b06f9 | 528 | fprintf(fp, "\tdump_%s(entry, \"%s\", %s);\n", |
a7d59104 | 529 | entry->type, |
530 | entry->name, | |
531 | entry->loc); | |
1df370e3 | 532 | if (entry->ifdef) |
533 | fprintf(fp, "#endif\n"); | |
934b03fc | 534 | } |
535 | fprintf(fp, "}\n\n"); | |
536 | } | |
537 | ||
0153d498 | 538 | static void |
539 | gen_free(Entry * head, FILE * fp) | |
540 | { | |
541 | Entry *entry; | |
542 | fprintf(fp, | |
d9586c3c | 543 | "static void\n" |
0153d498 | 544 | "free_all(void)\n" |
545 | "{\n" | |
546 | ); | |
547 | for (entry = head; entry != NULL; entry = entry->next) { | |
f1dc9b30 | 548 | assert(entry->loc); |
549 | if (strcmp(entry->loc, "none") == 0) | |
550 | continue; | |
0f74202c | 551 | if (strcmp(entry->name, "comment") == 0) |
3a278cb8 | 552 | continue; |
1df370e3 | 553 | if (entry->ifdef) |
75339a46 | 554 | fprintf(fp, "#if %s\n", entry->ifdef); |
b3de4c9b | 555 | fprintf(fp, "\tfree_%s(&%s%s);\n", |
556 | entry->type, entry->loc, | |
557 | entry->array_flag ? "[0]" : ""); | |
1df370e3 | 558 | if (entry->ifdef) |
559 | fprintf(fp, "#endif\n"); | |
0153d498 | 560 | } |
561 | fprintf(fp, "}\n\n"); | |
562 | } | |
563 | ||
a4b8110e | 564 | static int |
565 | defined(char *name) | |
6b53c392 | 566 | { |
a4b8110e | 567 | int i = 0; |
568 | if (!name) | |
569 | return 1; | |
570 | for (i = 0; strcmp(defines[i].name, name) != 0; i++) { | |
571 | assert(defines[i].name); | |
572 | } | |
573 | return defines[i].defined; | |
6b53c392 | 574 | } |
575 | ||
a4b8110e | 576 | static const char * |
577 | available_if(char *name) | |
6b53c392 | 578 | { |
a4b8110e | 579 | int i = 0; |
580 | assert(name); | |
581 | for (i = 0; strcmp(defines[i].name, name) != 0; i++) { | |
582 | assert(defines[i].name); | |
583 | } | |
584 | return defines[i].enable; | |
6b53c392 | 585 | } |
586 | ||
934b03fc | 587 | static void |
588 | gen_conf(Entry * head, FILE * fp) | |
589 | { | |
590 | Entry *entry; | |
6b53c392 | 591 | char buf[8192]; |
592 | Line *def = NULL; | |
934b03fc | 593 | |
594 | for (entry = head; entry != NULL; entry = entry->next) { | |
595 | Line *line; | |
6b53c392 | 596 | int blank = 1; |
934b03fc | 597 | |
c68e9c6b | 598 | if (!strcmp(entry->name, "comment")) |
599 | (void) 0; | |
600 | else | |
ea3a2a69 | 601 | fprintf(fp, "# TAG: %s", entry->name); |
934b03fc | 602 | if (entry->comment) |
9906e724 | 603 | fprintf(fp, "\t%s", entry->comment); |
934b03fc | 604 | fprintf(fp, "\n"); |
6b53c392 | 605 | if (!defined(entry->ifdef)) { |
606 | fprintf(fp, "# Note: This option is only available if Squid is rebuilt with the\n"); | |
607 | fprintf(fp, "# %s option\n#\n", available_if(entry->ifdef)); | |
608 | } | |
934b03fc | 609 | for (line = entry->doc; line != NULL; line = line->next) { |
610 | fprintf(fp, "#%s\n", line->data); | |
611 | } | |
a4b8110e | 612 | if (entry->default_value && strcmp(entry->default_value, "none") != 0) { |
6b53c392 | 613 | sprintf(buf, "%s %s", entry->name, entry->default_value); |
614 | lineAdd(&def, buf); | |
615 | } | |
616 | if (entry->default_if_none) { | |
617 | for (line = entry->default_if_none; line; line = line->next) { | |
618 | sprintf(buf, "%s %s", entry->name, line->data); | |
619 | lineAdd(&def, buf); | |
620 | } | |
621 | } | |
622 | if (entry->nocomment) | |
623 | blank = 0; | |
624 | if (!def && entry->doc && !entry->nocomment && | |
a4b8110e | 625 | strcmp(entry->name, "comment") != 0) |
6b53c392 | 626 | lineAdd(&def, "none"); |
627 | if (def && (entry->doc || entry->nocomment)) { | |
628 | if (blank) | |
629 | fprintf(fp, "#\n"); | |
630 | fprintf(fp, "#Default:\n"); | |
631 | while (def != NULL) { | |
632 | line = def; | |
633 | def = line->next; | |
634 | fprintf(fp, "# %s\n", line->data); | |
8eb042dc | 635 | xfree(line->data); |
636 | xfree(line); | |
6b53c392 | 637 | } |
a4b8110e | 638 | blank = 1; |
6b53c392 | 639 | } |
640 | if (entry->nocomment && blank) | |
641 | fprintf(fp, "#\n"); | |
c68e9c6b | 642 | for (line = entry->nocomment; line != NULL; line = line->next) { |
643 | fprintf(fp, "%s\n", line->data); | |
644 | } | |
934b03fc | 645 | if (entry->doc != NULL) { |
646 | fprintf(fp, "\n"); | |
647 | } | |
648 | } | |
649 | } |