]> git.ipfire.org Git - thirdparty/squid.git/blame - src/cf_gen.cc
Fix 'arbtext' wierdnesses
[thirdparty/squid.git] / src / cf_gen.cc
CommitLineData
934b03fc 1/*
0f74202c 2 * $Id: cf_gen.cc,v 1.14 1997/11/04 23:21:12 wessels Exp $
934b03fc 3 *
4 * DEBUG: section 1 Startup and Main Loop
5 * AUTHOR: Max Okumoto
6 *
7 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
8 * --------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from the
11 * Internet community. Development is led by Duane Wessels of the
12 * National Laboratory for Applied Network Research and funded by
13 * the National Science Foundation.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
30
31/*****************************************************************************
32 * Abstract: This program parses the input file and generates code and
33 * files used to configure the variables in squid.
3a278cb8 34 * (ie it creates the squid.conf file from the cf.data file)
934b03fc 35 *
36 * The output files are as follows:
37 * cf_parser.c - this file contains, default_all() which
f53b06f9 38 * initializes variables with the default
39 * values, parse_line() that parses line from
40 * squid.conf, dump_config that dumps the
934b03fc 41 * current the values of the variables.
42 * squid.conf - default configuration file given to the server
43 * administrator.
44 *****************************************************************************/
45
46#include <stdio.h>
47#include <string.h>
48#include <stdlib.h>
49#include <ctype.h>
50#include <assert.h>
51
52#define MAX_LINE 1024 /* longest configuration line */
53#define _PATH_PARSER "cf_parser.c"
54#define _PATH_SQUID_CONF "squid.conf"
55
56enum State {
57 sSTART,
58 s1,
59 sDOC,
60 sEXIT
61};
62
63typedef struct Line {
64 char *data;
65 struct Line *next;
66} Line;
67
68typedef struct Entry {
69 char *name;
70 char *type;
71 char *loc;
72 char *default_value;
f53b06f9 73 char *default_if_none;
934b03fc 74 char *comment;
75 Line *doc;
76 struct Entry *next;
77} Entry;
78
79
80static const char WS[] = " \t";
9906e724 81static const char NS[] = "";
f1dc9b30 82static int gen_default(Entry *, FILE *);
934b03fc 83static void gen_parse(Entry *, FILE *);
84static void gen_dump(Entry *, FILE *);
0153d498 85static void gen_free(Entry *, FILE *);
934b03fc 86static void gen_conf(Entry *, FILE *);
f53b06f9 87static void gen_default_if_none(Entry *, FILE *);
934b03fc 88
89int
90main(int argc, char *argv[])
91{
92 FILE *fp;
93 char *input_filename = argv[1];
94 char *output_filename = _PATH_PARSER;
95 char *conf_filename = _PATH_SQUID_CONF;
96 int linenum = 0;
97 Entry *entries = NULL;
98 Entry *curr = NULL;
99 enum State state;
f1dc9b30 100 int rc = 0;
9906e724 101 char *ptr = NULL;
934b03fc 102
103 /*-------------------------------------------------------------------*
104 * Parse input file
105 *-------------------------------------------------------------------*/
106
107 /* Open input file */
108 if ((fp = fopen(input_filename, "r")) == NULL) {
109 perror(input_filename);
110 exit(1);
111 }
112 state = sSTART;
113 while (feof(fp) == 0 && state != sEXIT) {
114 char buff[MAX_LINE];
115
116 fgets(buff, MAX_LINE, fp);
117 linenum++;
118 *(strchr(buff, '\n')) = '\0';
119 switch (state) {
120 case sSTART:
121 if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) {
122 /* ignore empty and comment lines */
934b03fc 123 } else if (!strncmp(buff, "NAME:", 5)) {
124 char *name;
934b03fc 125 if ((name = strtok(buff + 5, WS)) == NULL) {
126 printf("Error in input file\n");
127 exit(1);
128 }
14a31364 129 curr = calloc(1, sizeof(Entry));
934b03fc 130 curr->name = strdup(name);
934b03fc 131 state = s1;
934b03fc 132 } else if (!strcmp(buff, "EOF")) {
133 state = sEXIT;
0f74202c 134 } else if (!strcmp(buff, "COMMENT_START")) {
135 curr = calloc(1, sizeof(Entry));
136 curr->name = strdup("comment");
137 curr->loc = strdup("none");
138 state = sDOC;
934b03fc 139 } else {
140 printf("Error on line %d\n", linenum);
141 exit(1);
142 }
143 break;
144
145 case s1:
146 if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) {
147 /* ignore empty and comment lines */
934b03fc 148 } else if (!strncmp(buff, "COMMENT:", 8)) {
9906e724 149 ptr = buff + 8;
150 while (isspace(*ptr))
151 ptr++;
934b03fc 152 curr->comment = strdup(ptr);
153 } else if (!strncmp(buff, "DEFAULT:", 8)) {
9906e724 154 ptr = buff + 8;
155 while (isspace(*ptr))
156 ptr++;
934b03fc 157 curr->default_value = strdup(ptr);
f53b06f9 158 } else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) {
159 ptr = buff + 16;
160 while (isspace(*ptr))
161 ptr++;
162 curr->default_if_none = strdup(ptr);
934b03fc 163 } else if (!strncmp(buff, "LOC:", 4)) {
934b03fc 164 if ((ptr = strtok(buff + 4, WS)) == NULL) {
165 printf("Error on line %d\n", linenum);
166 exit(1);
167 }
168 curr->loc = strdup(ptr);
934b03fc 169 } else if (!strncmp(buff, "TYPE:", 5)) {
934b03fc 170 if ((ptr = strtok(buff + 5, WS)) == NULL) {
171 printf("Error on line %d\n", linenum);
172 exit(1);
173 }
174 curr->type = strdup(ptr);
934b03fc 175 } else if (!strcmp(buff, "DOC_START")) {
176 state = sDOC;
934b03fc 177 } else if (!strcmp(buff, "DOC_NONE")) {
178 /* add to list of entries */
179 curr->next = entries;
180 entries = curr;
934b03fc 181 state = sSTART;
934b03fc 182 } else {
183 printf("Error on line %d\n", linenum);
184 exit(1);
185 }
186 break;
187
188 case sDOC:
0f74202c 189 if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) {
934b03fc 190 Line *head = NULL;
191 Line *line = curr->doc;
934b03fc 192 /* reverse order of doc lines */
193 while (line != NULL) {
194 Line *tmp;
195 tmp = line->next;
196 line->next = head;
197 head = line;
198 line = tmp;
199 }
200 curr->doc = head;
934b03fc 201 /* add to list of entries */
202 curr->next = entries;
203 entries = curr;
934b03fc 204 state = sSTART;
205 } else {
14a31364 206 Line *line = calloc(1, sizeof(Line));
934b03fc 207 line->data = strdup(buff);
208 line->next = curr->doc;
209 curr->doc = line;
210 }
211 break;
212
213 case sEXIT:
214 assert(0); /* should never get here */
215 break;
216 }
217 }
218 if (state != sEXIT) {
219 printf("Error unexpected EOF\n");
220 exit(1);
221 } else {
222 /* reverse order of entries */
223 Entry *head = NULL;
224
225 while (entries != NULL) {
226 Entry *tmp;
227
228 tmp = entries->next;
229 entries->next = head;
230 head = entries;
231 entries = tmp;
232 }
233 entries = head;
234 }
235 fclose(fp);
236
237 /*-------------------------------------------------------------------*
238 * Generate default_all()
239 * Generate parse_line()
f53b06f9 240 * Generate dump_config()
0153d498 241 * Generate free_all()
934b03fc 242 * Generate example squid.conf file
243 *-------------------------------------------------------------------*/
244
245 /* Open output x.c file */
246 if ((fp = fopen(output_filename, "w")) == NULL) {
247 perror(output_filename);
248 exit(1);
249 }
250 fprintf(fp,
251 "/*\n"
252 " * Generated automatically from %s by %s\n"
253 " *\n"
254 " * Abstract: This file contains routines used to configure the\n"
255 " * variables in the squid server.\n"
256 " */\n"
257 "\n",
258 input_filename, argv[0]
259 );
f1dc9b30 260 rc = gen_default(entries, fp);
f53b06f9 261 gen_default_if_none(entries, fp);
934b03fc 262 gen_parse(entries, fp);
263 gen_dump(entries, fp);
0153d498 264 gen_free(entries, fp);
934b03fc 265 fclose(fp);
266
267 /* Open output x.conf file */
268 if ((fp = fopen(conf_filename, "w")) == NULL) {
269 perror(conf_filename);
270 exit(1);
271 }
272 gen_conf(entries, fp);
273 fclose(fp);
274
f1dc9b30 275 return (rc);
934b03fc 276}
277
f1dc9b30 278static int
934b03fc 279gen_default(Entry * head, FILE * fp)
280{
281 Entry *entry;
f1dc9b30 282 int rc = 0;
b556b1e9 283 fprintf(fp,
d9586c3c 284 "static void\n"
b556b1e9 285 "default_line(const char *s)\n"
286 "{\n"
287 "\tLOCAL_ARRAY(char, tmp_line, BUFSIZ);\n"
9906e724 288 "\txstrncpy(tmp_line, s, BUFSIZ);\n"
289 "\txstrncpy(config_input_line, s, BUFSIZ);\n"
b556b1e9 290 "\tconfig_lineno++;\n"
9906e724 291 "\tparse_line(tmp_line);\n"
b556b1e9 292 "}\n"
293 );
934b03fc 294 fprintf(fp,
d9586c3c 295 "static void\n"
934b03fc 296 "default_all(void)\n"
297 "{\n"
1273d501 298 "\tcfg_filename = \"Default Configuration\";\n"
b556b1e9 299 "\tconfig_lineno = 0;\n"
934b03fc 300 );
301 for (entry = head; entry != NULL; entry = entry->next) {
302 assert(entry->name);
3a278cb8 303
0f74202c 304 if (!strcmp(entry->name, "comment"))
3a278cb8 305 continue;
934b03fc 306 if (entry->loc == NULL) {
307 fprintf(stderr, "NO LOCATION FOR %s\n", entry->name);
f1dc9b30 308 rc |= 1;
934b03fc 309 continue;
310 }
311 if (entry->default_value == NULL) {
312 fprintf(stderr, "NO DEFAULT FOR %s\n", entry->name);
f1dc9b30 313 rc |= 1;
934b03fc 314 continue;
315 }
f1dc9b30 316 assert(entry->default_value);
317 if (strcmp(entry->default_value, "none") == 0) {
318 fprintf(fp, "\t/* No default for %s */\n", entry->name);
934b03fc 319 } else {
b556b1e9 320 fprintf(fp, "\tdefault_line(\"%s %s\");\n",
934b03fc 321 entry->name,
322 entry->default_value);
f1dc9b30 323 }
934b03fc 324 }
1273d501 325 fprintf(fp, "\tcfg_filename = NULL;\n");
934b03fc 326 fprintf(fp, "}\n\n");
f1dc9b30 327 return rc;
934b03fc 328}
329
f53b06f9 330static void
331gen_default_if_none(Entry * head, FILE * fp)
332{
333 Entry *entry;
334 fprintf(fp,
d9586c3c 335 "static void\n"
f53b06f9 336 "defaults_if_none(void)\n"
337 "{\n"
338 );
339 for (entry = head; entry != NULL; entry = entry->next) {
340 assert(entry->name);
341 assert(entry->loc);
342 if (entry->default_if_none == NULL)
343 continue;
344 fprintf(fp,
345 "\tif (check_null_%s(%s))\n"
346 "\t\tdefault_line(\"%s %s\");\n",
347 entry->type,
348 entry->loc,
349 entry->name,
350 entry->default_if_none);
351 }
352 fprintf(fp, "}\n\n");
353}
354
934b03fc 355static void
356gen_parse(Entry * head, FILE * fp)
357{
358 Entry *entry;
359
360 fprintf(fp,
f8c4d483 361 "static int\n"
934b03fc 362 "parse_line(char *buff)\n"
363 "{\n"
364 "\tint\tresult = 1;\n"
365 "\tchar\t*token;\n"
1273d501 366 "\tdebug(0,10)(\"parse_line: %%s\\n\", buff);\n"
934b03fc 367 "\tif ((token = strtok(buff, w_space)) == NULL) {\n"
368 "\t\t/* ignore empty lines */\n"
369 );
370
371 for (entry = head; entry != NULL; entry = entry->next) {
0f74202c 372 if (strcmp(entry->name, "comment") == 0)
373 continue;
934b03fc 374 fprintf(fp,
375 "\t} else if (!strcmp(token, \"%s\")) {\n",
376 entry->name
377 );
f1dc9b30 378 assert(entry->loc);
379 if (strcmp(entry->loc, "none") == 0) {
934b03fc 380 fprintf(fp,
381 "\t\tparse_%s();\n",
382 entry->type
383 );
0f74202c 384 } else {
934b03fc 385 fprintf(fp,
386 "\t\tparse_%s(&%s);\n",
387 entry->type, entry->loc
388 );
389 }
390 }
391
392 fprintf(fp,
393 "\t} else {\n"
394 "\t\tresult = 0; /* failure */\n"
395 "\t}\n"
396 "\treturn(result);\n"
397 "}\n\n"
398 );
399}
400
401static void
402gen_dump(Entry * head, FILE * fp)
403{
404 Entry *entry;
934b03fc 405 fprintf(fp,
f8c4d483 406 "void\n"
f53b06f9 407 "dump_config(StoreEntry *entry)\n"
934b03fc 408 "{\n"
409 );
934b03fc 410 for (entry = head; entry != NULL; entry = entry->next) {
f1dc9b30 411 assert(entry->loc);
412 if (strcmp(entry->loc, "none") == 0)
413 continue;
0f74202c 414 if (strcmp(entry->name, "comment") == 0)
3a278cb8 415 continue;
f53b06f9 416 fprintf(fp, "\tdump_%s(entry, \"%s\", %s);\n",
a7d59104 417 entry->type,
418 entry->name,
419 entry->loc);
934b03fc 420 }
421 fprintf(fp, "}\n\n");
422}
423
0153d498 424static void
425gen_free(Entry * head, FILE * fp)
426{
427 Entry *entry;
428 fprintf(fp,
d9586c3c 429 "static void\n"
0153d498 430 "free_all(void)\n"
431 "{\n"
432 );
433 for (entry = head; entry != NULL; entry = entry->next) {
f1dc9b30 434 assert(entry->loc);
435 if (strcmp(entry->loc, "none") == 0)
436 continue;
0f74202c 437 if (strcmp(entry->name, "comment") == 0)
3a278cb8 438 continue;
f1dc9b30 439 fprintf(fp, "\tfree_%s(&%s);\n", entry->type, entry->loc);
0153d498 440 }
441 fprintf(fp, "}\n\n");
442}
443
934b03fc 444static void
445gen_conf(Entry * head, FILE * fp)
446{
447 Entry *entry;
448
449 for (entry = head; entry != NULL; entry = entry->next) {
450 Line *line;
451
0f74202c 452 if (strcmp(entry->name, "comment"))
ea3a2a69 453 fprintf(fp, "# TAG: %s", entry->name);
934b03fc 454 if (entry->comment)
9906e724 455 fprintf(fp, "\t%s", entry->comment);
934b03fc 456 fprintf(fp, "\n");
457 for (line = entry->doc; line != NULL; line = line->next) {
458 fprintf(fp, "#%s\n", line->data);
459 }
460 if (entry->doc != NULL) {
461 fprintf(fp, "\n");
462 }
463 }
464}