cf_gen.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:13k
源码类别:

代理服务器

开发平台:

Unix_Linux

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