From: John Millaway Date: Mon, 10 Mar 2003 20:00:55 +0000 (+0000) Subject: Added filter.c X-Git-Tag: flex-2-5-34~35^2~26 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e206db605a89542154d291507d67d72601c52ee;p=flex Added filter.c Added filter.c rules to Makefile.am Added filter prototypes to flexdef.h Flex now filters output through m4. --- diff --git a/Makefile.am b/Makefile.am index abe912e..bed7d74 100644 --- a/Makefile.am +++ b/Makefile.am @@ -65,7 +65,8 @@ flex_SOURCES = \ scanopt.c \ buf.c \ tables.c \ - tables_shared.c + tables_shared.c \ + filter.c libfl_a_SOURCES = \ libmain.c \ @@ -168,6 +169,7 @@ tables_shared.o: tables_shared.c flexdef.h flexint.h tables.h \ tables_shared.h tblcmp.o: tblcmp.c flexdef.h flexint.h yylex.o: yylex.c flexdef.h flexint.h parse.h +filter.o: filter.c flexdef.h flexint.h # Create a tags file. tags: diff --git a/filter.c b/filter.c new file mode 100644 index 0000000..7238ec9 --- /dev/null +++ b/filter.c @@ -0,0 +1,139 @@ +/* filter - postprocessing of flex output through filters */ + +/* Copyright (c) 1990 The Regents of the University of California. */ +/* All rights reserved. */ + +/* This code is derived from software contributed to Berkeley by */ +/* Vern Paxson. */ + +/* The United States Government has rights in this work pursuant */ +/* to contract no. DE-AC03-76SF00098 between the United States */ +/* Department of Energy and the University of California. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" + +/** global chain. */ +struct filter *output_chain = NULL; + +/* Allocate and initialize a filter. + * @param chain the current chain or NULL for new chain + * @param cmd the command to execute. + * @param ... a NULL terminated list of (const char*) arguments to command, + * not including argv[0]. + * @return newest filter in chain + */ +struct filter *filter_create (struct filter *chain, const char *cmd, ...) +{ + struct filter *f; + int max_args; + const char *s; + va_list ap; + + /* allocate and initialize new filter */ + f = (struct filter *) flex_alloc (sizeof (struct filter)); + memset (f, 0, sizeof (*f)); + f->next = NULL; + f->argc = 0; + + if (chain != NULL) { + /* append f to end of chain */ + while (chain->next) + chain = chain->next; + chain->next = f; + } + + + /* allocate argv, and populate it with the argument list. */ + max_args = 8; + f->argv = + (const char **) flex_alloc (sizeof (char *) * + (max_args + 1)); + f->argv[f->argc++] = cmd; + + va_start (ap, cmd); + while ((s = va_arg (ap, const char *)) != NULL) { + if (f->argc >= max_args) { + max_args += 8; + f->argv = + (const char **) flex_realloc (f->argv, + sizeof (char + *) * + (max_args + + 1)); + } + f->argv[f->argc++] = s; + } + f->argv[f->argc] = NULL; + + va_end (ap); + return f; +} + +/** Fork and exec entire filter chain. + * @param chain The head of the chain. + * @return true on success. + */ +bool filter_apply_chain (struct filter * chain) +{ + int pid, pipes[2]; + + if (chain == NULL) + return true; + + fflush (stdout); + fflush (stderr); + + if (pipe (pipes) == -1) + flexerror (_("pipe failed")); + + if ((pid = fork ()) == -1) + flexerror (_("fork failed")); + + if (pid == 0) { + /* child */ + close (pipes[1]); + if (dup2 (pipes[0], 0) == -1) + flexfatal (_("dup2(pipes[0],0)")); + close (pipes[0]); + if ((stdin = fdopen (0, "r")) == NULL) + flexfatal (_("fdopen(0) failed")); + + filter_apply_chain (chain->next); + execvp (chain->argv[0], (char **const) (chain->argv)); + flexfatal (_("exec failed")); + exit (1); + } + + /* Parent */ + close (pipes[0]); + if (dup2 (pipes[1], 1) == -1) + flexfatal (_("dup2(pipes[1],1)")); + close (pipes[1]); + if ((stdout = fdopen (1, "w")) == NULL) + flexfatal (_("fdopen(1) failed")); + + return true; +} + +/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ diff --git a/flex.skl b/flex.skl index 06f7456..c7bd556 100644 --- a/flex.skl +++ b/flex.skl @@ -1,6 +1,24 @@ -m4_changecom -%# -*-C-*- vi: set ft=c: +m4_dnl -*-C-*- vi: set ft=c: +m4_dnl This file is processed in several stages. +m4_dnl Here are the stages, as best as I can describe: +m4_dnl +m4_dnl 1. flex.skl is processed through GNU m4 during the +m4_dnl pre-compilation stage of flex. +m4_dnl 2. The preprocessed skeleton is translated verbatim into a +m4_dnl C array, saved as "skel.c" and compiled into the flex binary. +m4_dnl 3. At runtime, the skeleton is generated and filtered (again) +m4_dnl through m4. +m4_dnl /* A lexical scanner generated by flex */ +m4_changecom + +m4_dnl +m4_dnl Create macros for the generation phase, not the preproc phase. +m4_dnl +`m4_changecom' +m4_define(`YYDEFINE',``m4_define($@)'') +m4_define(`YYIFDEF',``m4_ifdef($@)'') +%# %# Lines in this skeleton starting with a '%' character are "control lines" %# and affect the generation of the scanner. The possible control codes are diff --git a/flexdef.h b/flexdef.h index e83422b..5a1af81 100644 --- a/flexdef.h +++ b/flexdef.h @@ -42,6 +42,7 @@ #ifdef STDC_HEADERS #include #include +#include #include #include #include @@ -1129,4 +1130,31 @@ int reverse_case(int c); /* return false if [c1-c2] is ambiguous for a caseless scanner. */ bool range_covers_case (int c1, int c2); +/* + * From "filter.c" + */ +struct filter { + int argc; + const char ** argv; + struct filter * next; +}; + +/* output filter chain */ +extern struct filter * output_chain; + +/* Allocate and initialize a filter. + * @param chain the current chain or NULL for new chain + * @param cmd the command to execute. + * @param ... a NULL terminated list of (const char*) arguments to command, + * not including argv[0]. + * @return newest filter in chain + */ +struct filter *filter_create (struct filter * chain, const char *cmd, ...); + +/* Fork and exec entire filter chain. + * @param chain The head of the chain. + * @return true on success. + */ +bool filter_apply_chain (struct filter * chain); + #endif /* not defined FLEXDEF_H */ diff --git a/main.c b/main.c index 9df7269..4440edf 100644 --- a/main.c +++ b/main.c @@ -129,6 +129,9 @@ static char *tablesfile_template = "lex%s.tbl"; extern unsigned _stklen = 16384; #endif +/* From scan.l */ +extern FILE* yyout; + static char outfile_path[MAXLINE]; static int outfile_created = 0; static char *skelname = NULL; @@ -151,8 +154,12 @@ int flex_main (argc, argv) * exit(n); */ exit_status = setjmp (flex_main_jmp_buf); - if (exit_status) + if (exit_status){ + fflush(stdout); + fclose(stdout); + wait(0); return exit_status - 1; + } flexinit (argc, argv); @@ -329,6 +336,12 @@ void check_options () outfile_created = 1; } + /* Setup the filter chain. */ + output_chain = filter_create(NULL,"m4","-P",0); + filter_apply_chain(output_chain); + yyout = stdout; + + /* always generate the tablesverify flag. */ action_define ("YY_TABLES_VERIFY", tablesverify ? 1 : 0); if (tablesext) diff --git a/misc.c b/misc.c index 0ef04be..9ff31d4 100644 --- a/misc.c +++ b/misc.c @@ -704,7 +704,7 @@ void out_dec (fmt, n) const char *fmt; int n; { - printf (fmt, n); + fprintf (stdout, fmt, n); out_line_count (fmt); } @@ -712,7 +712,7 @@ void out_dec2 (fmt, n1, n2) const char *fmt; int n1, n2; { - printf (fmt, n1, n2); + fprintf (stdout, fmt, n1, n2); out_line_count (fmt); } @@ -720,7 +720,7 @@ void out_hex (fmt, x) const char *fmt; unsigned int x; { - printf (fmt, x); + fprintf (stdout, fmt, x); out_line_count (fmt); } @@ -737,7 +737,7 @@ void out_line_count (str) void out_str (fmt, str) const char *fmt, str[]; { - printf (fmt, str); + fprintf (stdout,fmt, str); out_line_count (fmt); out_line_count (str); } @@ -745,7 +745,7 @@ void out_str (fmt, str) void out_str3 (fmt, s1, s2, s3) const char *fmt, s1[], s2[], s3[]; { - printf (fmt, s1, s2, s3); + fprintf (stdout,fmt, s1, s2, s3); out_line_count (fmt); out_line_count (s1); out_line_count (s2); @@ -756,7 +756,7 @@ void out_str_dec (fmt, str, n) const char *fmt, str[]; int n; { - printf (fmt, str, n); + fprintf (stdout,fmt, str, n); out_line_count (fmt); out_line_count (str); } @@ -764,7 +764,7 @@ void out_str_dec (fmt, str, n) void outc (c) int c; { - putc (c, stdout); + fputc (c, stdout); if (c == '\n') ++out_linenum; @@ -773,7 +773,8 @@ void outc (c) void outn (str) const char *str; { - puts (str); + fputs (str,stdout); + fputc('\n',stdout); out_line_count (str); ++out_linenum; }