]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cf_gen.cc
Merged from trunk.
[thirdparty/squid.git] / src / cf_gen.cc
CommitLineData
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
60enum State {
61 sSTART,
62 s1,
63 sDOC,
c68e9c6b 64 sNOCOMMENT,
934b03fc 65 sEXIT
66};
67
62e76326 68typedef struct Line
69{
934b03fc 70 char *data;
62e76326 71
934b03fc 72 struct Line *next;
2fadd50d 73} Line;
62e76326 74
75typedef struct EntryAlias
76{
934b03fc 77
7af1c5ab 78 struct EntryAlias *next;
79 char *name;
2fadd50d 80} EntryAlias;
7af1c5ab 81
62e76326 82typedef 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 99typedef struct TypeDep
100{
101 char *name;
102
103 TypeDep *next;
104} TypeDep;
105
106typedef struct Type
107{
108 char *name;
109 TypeDep *depend;
934b03fc 110
41bd17a4 111 struct Type *next;
112} Type;
113
114static const char WS[] = " \t\n";
f1dc9b30 115static int gen_default(Entry *, FILE *);
934b03fc 116static void gen_parse(Entry *, FILE *);
147a3e90 117static void gen_parse_entry(Entry *entry, FILE *fp);
118static void gen_parse_alias(char *, EntryAlias *, Entry *, FILE *);
934b03fc 119static void gen_dump(Entry *, FILE *);
0153d498 120static void gen_free(Entry *, FILE *);
934b03fc 121static void gen_conf(Entry *, FILE *);
f53b06f9 122static void gen_default_if_none(Entry *, FILE *);
934b03fc 123
d89f9532 124
a4b8110e 125static void
c193c972 126lineAdd(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 136static void
137checkDepend(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 161int
162main(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 495static int
934b03fc 496gen_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 560static void
561gen_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 603void
604gen_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
625void
626gen_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
657static void
658gen_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
679static void
680gen_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 713static void
714gen_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 746static int
747defined(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 761static const char *
762available_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 774static void
775gen_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}