⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cf_gen.c

📁 -
💻 C
字号:
/* * $Id: cf_gen.c,v 1.31.2.1 1999/02/12 19:38:24 wessels Exp $ * * DEBUG: none * AUTHOR: Max Okumoto * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * *//***************************************************************************** * Abstract:	This program parses the input file and generates code and *		files used to configure the variables in squid. *		(ie it creates the squid.conf file from the cf.data file) * *		The output files are as follows: *		cf_parser.c - this file contains, default_all() which *			  initializes variables with the default *			  values, parse_line() that parses line from *			  squid.conf, dump_config that dumps the *			  current the values of the variables. *		squid.conf - default configuration file given to the server *			 administrator. *****************************************************************************/#include "config.h"#if HAVE_STDIO_H#include <stdio.h>#endif#if HAVE_STRING_H#include <string.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_CTYPE_H#include <ctype.h>#endif#if HAVE_ASSERT_H#include <assert.h>#endif#include "util.h"#define MAX_LINE	1024	/* longest configuration line */#define _PATH_PARSER		"cf_parser.c"#define _PATH_SQUID_CONF	"squid.conf"enum State {    sSTART,    s1,    sDOC,    sNOCOMMENT,    sEXIT};typedef struct Line {    char *data;    struct Line *next;} Line;typedef struct Entry {    char *name;    char *type;    char *loc;    char *default_value;    char *default_if_none;    char *comment;    char *ifdef;    Line *doc;    Line *nocomment;    struct Entry *next;} Entry;static const char WS[] = " \t";static int gen_default(Entry *, FILE *);static void gen_parse(Entry *, FILE *);static void gen_dump(Entry *, FILE *);static void gen_free(Entry *, FILE *);static void gen_conf(Entry *, FILE *);static void gen_default_if_none(Entry *, FILE *);intmain(int argc, char *argv[]){    FILE *fp;    char *input_filename = argv[1];    char *output_filename = _PATH_PARSER;    char *conf_filename = _PATH_SQUID_CONF;    int linenum = 0;    Entry *entries = NULL;    Entry *curr = NULL;    enum State state;    int rc = 0;    char *ptr = NULL;#ifdef _SQUID_OS2_    const char *rmode = "rt";#else    const char *rmode = "r";#endif    /*-------------------------------------------------------------------*     * Parse input file     *-------------------------------------------------------------------*/    /* Open input file */    if ((fp = fopen(input_filename, rmode)) == NULL) {	perror(input_filename);	exit(1);    }    state = sSTART;    while (feof(fp) == 0 && state != sEXIT) {	char buff[MAX_LINE];	char *t;	if (NULL == fgets(buff, MAX_LINE, fp))	    break;	linenum++;	if ((t = strchr(buff, '\n')))	    *t = '\0';	switch (state) {	case sSTART:	    if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) {		/* ignore empty and comment lines */		(void) 0;	    } else if (!strncmp(buff, "NAME:", 5)) {		char *name;		if ((name = strtok(buff + 5, WS)) == NULL) {		    printf("Error in input file\n");		    exit(1);		}		curr = calloc(1, sizeof(Entry));		curr->name = xstrdup(name);		state = s1;	    } else if (!strcmp(buff, "EOF")) {		state = sEXIT;	    } else if (!strcmp(buff, "COMMENT_START")) {		curr = calloc(1, sizeof(Entry));		curr->name = xstrdup("comment");		curr->loc = xstrdup("none");		state = sDOC;	    } else {		printf("Error on line %d\n", linenum);		printf("--> %s\n", buff);		exit(1);	    }	    break;	case s1:	    if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) {		/* ignore empty and comment lines */		(void) 0;	    } else if (!strncmp(buff, "COMMENT:", 8)) {		ptr = buff + 8;		while (xisspace(*ptr))		    ptr++;		curr->comment = xstrdup(ptr);	    } else if (!strncmp(buff, "DEFAULT:", 8)) {		ptr = buff + 8;		while (xisspace(*ptr))		    ptr++;		curr->default_value = xstrdup(ptr);	    } else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) {		ptr = buff + 16;		while (xisspace(*ptr))		    ptr++;		curr->default_if_none = xstrdup(ptr);	    } else if (!strncmp(buff, "LOC:", 4)) {		if ((ptr = strtok(buff + 4, WS)) == NULL) {		    printf("Error on line %d\n", linenum);		    exit(1);		}		curr->loc = xstrdup(ptr);	    } else if (!strncmp(buff, "TYPE:", 5)) {		if ((ptr = strtok(buff + 5, WS)) == NULL) {		    printf("Error on line %d\n", linenum);		    exit(1);		}		curr->type = xstrdup(ptr);	    } else if (!strncmp(buff, "IFDEF:", 6)) {		if ((ptr = strtok(buff + 6, WS)) == NULL) {		    printf("Error on line %d\n", linenum);		    exit(1);		}		curr->ifdef = xstrdup(ptr);	    } else if (!strcmp(buff, "DOC_START")) {		state = sDOC;	    } else if (!strcmp(buff, "DOC_NONE")) {		/* add to list of entries */		curr->next = entries;		entries = curr;		state = sSTART;	    } else {		printf("Error on line %d\n", linenum);		exit(1);	    }	    break;	case sDOC:	    if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) {		Line *head = NULL;		Line *line = curr->doc;		/* reverse order of doc lines */		while (line != NULL) {		    Line *tmp;		    tmp = line->next;		    line->next = head;		    head = line;		    line = tmp;		}		curr->doc = head;		/* add to list of entries */		curr->next = entries;		entries = curr;		state = sSTART;	    } else if (!strcmp(buff, "NOCOMMENT_START")) {		state = sNOCOMMENT;	    } else {		Line *line = calloc(1, sizeof(Line));		line->data = xstrdup(buff);		line->next = curr->doc;		curr->doc = line;	    }	    break;	case sNOCOMMENT:	    if (!strcmp(buff, "NOCOMMENT_END")) {		Line *head = NULL;		Line *line = curr->nocomment;		/* reverse order of lines */		while (line != NULL) {		    Line *tmp;		    tmp = line->next;		    line->next = head;		    head = line;		    line = tmp;		}		curr->nocomment = head;		state = sDOC;	    } else {		Line *line = calloc(1, sizeof(Line));		line->data = xstrdup(buff);		line->next = curr->nocomment;		curr->nocomment = line;	    }	    break;	case sEXIT:	    assert(0);		/* should never get here */	    break;	}    }    if (state != sEXIT) {	printf("Error unexpected EOF\n");	exit(1);    } else {	/* reverse order of entries */	Entry *head = NULL;	while (entries != NULL) {	    Entry *tmp;	    tmp = entries->next;	    entries->next = head;	    head = entries;	    entries = tmp;	}	entries = head;    }    fclose(fp);    /*-------------------------------------------------------------------*     * Generate default_all()     * Generate parse_line()     * Generate dump_config()     * Generate free_all()     * Generate example squid.conf file     *-------------------------------------------------------------------*/    /* Open output x.c file */    if ((fp = fopen(output_filename, "w")) == NULL) {	perror(output_filename);	exit(1);    }    fprintf(fp,	"/*\n"	" * Generated automatically from %s by %s\n"	" *\n"	" * Abstract: This file contains routines used to configure the\n"	" *           variables in the squid server.\n"	" */\n"	"\n",	input_filename, argv[0]	);    rc = gen_default(entries, fp);    gen_default_if_none(entries, fp);    gen_parse(entries, fp);    gen_dump(entries, fp);    gen_free(entries, fp);    fclose(fp);    /* Open output x.conf file */    if ((fp = fopen(conf_filename, "w")) == NULL) {	perror(conf_filename);	exit(1);    }    gen_conf(entries, fp);    fclose(fp);    return (rc);}static intgen_default(Entry * head, FILE * fp){    Entry *entry;    int rc = 0;    fprintf(fp,	"static void\n"	"default_line(const char *s)\n"	"{\n"	"\tLOCAL_ARRAY(char, tmp_line, BUFSIZ);\n"	"\txstrncpy(tmp_line, s, BUFSIZ);\n"	"\txstrncpy(config_input_line, s, BUFSIZ);\n"	"\tconfig_lineno++;\n"	"\tparse_line(tmp_line);\n"	"}\n"	);    fprintf(fp,	"static void\n"	"default_all(void)\n"	"{\n"	"\tcfg_filename = \"Default Configuration\";\n"	"\tconfig_lineno = 0;\n"	);    for (entry = head; entry != NULL; entry = entry->next) {	assert(entry->name);	assert(entry != entry->next);	if (!strcmp(entry->name, "comment"))	    continue;	if (entry->loc == NULL) {	    fprintf(stderr, "NO LOCATION FOR %s\n", entry->name);	    rc |= 1;	    continue;	}	if (entry->default_value == NULL) {	    fprintf(stderr, "NO DEFAULT FOR %s\n", entry->name);	    rc |= 1;	    continue;	}	assert(entry->default_value);	if (entry->ifdef)	    fprintf(fp, "#if %s\n", entry->ifdef);	if (strcmp(entry->default_value, "none") == 0) {	    fprintf(fp, "\t/* No default for %s */\n", entry->name);	} else {	    fprintf(fp, "\tdefault_line(\"%s %s\");\n",		entry->name,		entry->default_value);	}	if (entry->ifdef)	    fprintf(fp, "#endif\n");    }    fprintf(fp, "\tcfg_filename = NULL;\n");    fprintf(fp, "}\n\n");    return rc;}static voidgen_default_if_none(Entry * head, FILE * fp){    Entry *entry;    fprintf(fp,	"static void\n"	"defaults_if_none(void)\n"	"{\n"	);    for (entry = head; entry != NULL; entry = entry->next) {	assert(entry->name);	assert(entry->loc);	if (entry->default_if_none == NULL)	    continue;	if (entry->ifdef)	    fprintf(fp, "#if %s\n", entry->ifdef);	fprintf(fp,	    "\tif (check_null_%s(%s))\n"	    "\t\tdefault_line(\"%s %s\");\n",	    entry->type,	    entry->loc,	    entry->name,	    entry->default_if_none);	if (entry->ifdef)	    fprintf(fp, "#endif\n");    }    fprintf(fp, "}\n\n");}static voidgen_parse(Entry * head, FILE * fp){    Entry *entry;    fprintf(fp,	"static int\n"	"parse_line(char *buff)\n"	"{\n"	"\tint\tresult = 1;\n"	"\tchar\t*token;\n"	"\tdebug(0,10)(\"parse_line: %%s\\n\", buff);\n"	"\tif ((token = strtok(buff, w_space)) == NULL)\n"	"\t\t(void) 0;\t/* ignore empty lines */\n"	);    for (entry = head; entry != NULL; entry = entry->next) {	if (strcmp(entry->name, "comment") == 0)	    continue;	if (entry->ifdef)	    fprintf(fp, "#if %s\n", entry->ifdef);	fprintf(fp, "\telse if (!strcmp(token, \"%s\"))\n",	    entry->name	    );	assert(entry->loc);	if (strcmp(entry->loc, "none") == 0) {	    fprintf(fp,		"\t\tparse_%s();\n",		entry->type		);	} else {	    fprintf(fp,		"\t\tparse_%s(&%s);\n",		entry->type, entry->loc		);	}	if (entry->ifdef)	    fprintf(fp, "#endif\n");    }    fprintf(fp,	"\telse\n"	"\t\tresult = 0; /* failure */\n"	"\treturn(result);\n"	"}\n\n"	);}static voidgen_dump(Entry * head, FILE * fp){    Entry *entry;    fprintf(fp,	"static void\n"	"dump_config(StoreEntry *entry)\n"	"{\n"	);    for (entry = head; entry != NULL; entry = entry->next) {	assert(entry->loc);	if (strcmp(entry->loc, "none") == 0)	    continue;	if (strcmp(entry->name, "comment") == 0)	    continue;	if (entry->ifdef)	    fprintf(fp, "#if %s\n", entry->ifdef);	fprintf(fp, "\tdump_%s(entry, \"%s\", %s);\n",	    entry->type,	    entry->name,	    entry->loc);	if (entry->ifdef)	    fprintf(fp, "#endif\n");    }    fprintf(fp, "}\n\n");}static voidgen_free(Entry * head, FILE * fp){    Entry *entry;    fprintf(fp,	"static void\n"	"free_all(void)\n"	"{\n"	);    for (entry = head; entry != NULL; entry = entry->next) {	assert(entry->loc);	if (strcmp(entry->loc, "none") == 0)	    continue;	if (strcmp(entry->name, "comment") == 0)	    continue;	if (entry->ifdef)	    fprintf(fp, "#if %s\n", entry->ifdef);	fprintf(fp, "\tfree_%s(&%s);\n", entry->type, entry->loc);	if (entry->ifdef)	    fprintf(fp, "#endif\n");    }    fprintf(fp, "}\n\n");}static voidgen_conf(Entry * head, FILE * fp){    Entry *entry;    for (entry = head; entry != NULL; entry = entry->next) {	Line *line;	if (!strcmp(entry->name, "comment"))	    (void) 0;	else	    fprintf(fp, "#  TAG: %s", entry->name);	if (entry->comment)	    fprintf(fp, "\t%s", entry->comment);	fprintf(fp, "\n");	for (line = entry->doc; line != NULL; line = line->next) {	    fprintf(fp, "#%s\n", line->data);	}	for (line = entry->nocomment; line != NULL; line = line->next) {	    fprintf(fp, "%s\n", line->data);	}	if (entry->doc != NULL) {	    fprintf(fp, "\n");	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -