]> granicus.if.org Git - flex/commitdiff
Added filter.c
authorJohn Millaway <john43@users.sourceforge.net>
Mon, 10 Mar 2003 20:00:55 +0000 (20:00 +0000)
committerJohn Millaway <john43@users.sourceforge.net>
Mon, 10 Mar 2003 20:00:55 +0000 (20:00 +0000)
Added filter.c rules to Makefile.am
Added filter prototypes to flexdef.h
Flex now filters output through m4.

Makefile.am
filter.c [new file with mode: 0644]
flex.skl
flexdef.h
main.c
misc.c

index abe912e0645fe45f2887cdb6aaa95ee257e45365..bed7d74f48f11924269c8744ca0aab17cf0ce1c0 100644 (file)
@@ -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 (file)
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: */
index 06f745679409627d5a98912784548ceecbf73db8..c7bd5564a8b1773dbac944d2474aab3ddda0064e 100644 (file)
--- 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
index e83422ba26044cfda2e3aa4571b2da250426bda5..5a1af81d2009408e82b8db6c74b65d1cedd3c606 100644 (file)
--- a/flexdef.h
+++ b/flexdef.h
@@ -42,6 +42,7 @@
 #ifdef STDC_HEADERS
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <setjmp.h>
 #include <ctype.h>
 #include <string.h>
@@ -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 9df72696b8d9af146d5f51e80fb921653d4f53a7..4440edf22b9c2ee2db111968efa54178bda7f435 100644 (file)
--- 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 0ef04be889524728790ce05ed929c1eba5a1fcae..9ff31d4e759a45bd200c280b3066ba29e6b9effe 100644 (file)
--- 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;
 }