static void gen_conf(Entry * head, FILE * fp, int verbose_output) { Entry *entry; char buf[8192]; Line *def = NULL; for (entry = head; entry != NULL; entry = entry->next) { Line *line; if (!strcmp(entry->name, "comment")) (void) 0; else if (verbose_output) { fprintf(fp, "# TAG: %s", entry->name); if (entry->comment) fprintf(fp, "\t%s\n", entry->comment); else fprintf(fp, "\n"); } if (verbose_output) { if (!defined(entry->ifdef)) { fprintf(fp, "# Note: This option is only available if Squid is rebuilt with the\n"); fprintf(fp, "# %s option\n#\n", available_if(entry->ifdef)); } for (line = entry->doc; line != NULL; line = line->next) { fprintf(fp, "#%s\n", line->data); } } if (entry->default_value && strcmp(entry->default_value, "none") != 0) { snprintf(buf, sizeof(buf), "%s %s", entry->name, entry->default_value); lineAdd(&def, buf); } if (entry->default_if_none) { for (line = entry->default_if_none; line; line = line->next) { snprintf(buf, sizeof(buf), "%s %s", entry->name, line->data); lineAdd(&def, buf); } } if (!def && entry->doc && strcmp(entry->name, "comment") != 0) lineAdd(&def, "none"); if (verbose_output && def && (entry->doc || entry->nocomment)) { fprintf(fp, "#\n#Default:\n"); while (def != NULL) { line = def; def = line->next; fprintf(fp, "# %s\n", line->data); xfree(line->data); xfree(line); } } if (verbose_output && entry->nocomment) fprintf(fp, "#\n"); for (line = entry->nocomment; line != NULL; line = line->next) { fprintf(fp, "%s\n", line->data); } if (verbose_output && entry->doc != NULL) { fprintf(fp, "\n"); } } }
int main(int argc, char *argv[]) { FILE *fp; char *input_filename = argv[1]; const char *output_filename = _PATH_PARSER; const 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); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif 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, *aliasname; if ((name = strtok(buff + 5, WS)) == NULL) { printf("Error in input file\n"); exit(1); } curr = xcalloc(1, sizeof(Entry)); curr->name = xstrdup(name); while ((aliasname = strtok(NULL, WS)) != NULL) { EntryAlias *alias = xcalloc(1, sizeof(EntryAlias)); alias->next = curr->alias; alias->name = xstrdup(aliasname); curr->alias = alias; } state = s1; } else if (!strcmp(buff, "EOF")) { state = sEXIT; } else if (!strcmp(buff, "COMMENT_START")) { curr = xcalloc(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++; lineAdd(&curr->default_if_none, 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); } /* hack to support arrays, rather than pointers */ if (0 == strcmp(ptr + strlen(ptr) - 2, "[]")) { curr->array_flag = 1; *(ptr + strlen(ptr) - 2) = '\0'; } 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 = xcalloc(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 = xcalloc(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.default file *-------------------------------------------------------------------*/ /* Open output x.c file */ if ((fp = fopen(output_filename, "w")) == NULL) { perror(output_filename); exit(1); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif 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); } #ifdef _SQUID_WIN32_ setmode(fileno(fp), O_TEXT); #endif gen_conf(entries, fp); fclose(fp); return (rc); }