summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillaway <millaway>2003-03-10 20:00:55 +0000
committermillaway <millaway>2003-03-10 20:00:55 +0000
commit1953645a2b143bd2852552f90c18181e9c5c4d40 (patch)
treeef939df4828341299581a37246b4e087f81645a3
parentff22f89a3279ca3642c41937303c0445273c130d (diff)
downloadflex-1953645a2b143bd2852552f90c18181e9c5c4d40.tar.gz
Added filter.c
Added filter.c rules to Makefile.am Added filter prototypes to flexdef.h Flex now filters output through m4.
-rw-r--r--Makefile.am4
-rw-r--r--filter.c139
-rw-r--r--flex.skl22
-rw-r--r--flexdef.h28
-rw-r--r--main.c15
-rw-r--r--misc.c17
6 files changed, 213 insertions, 12 deletions
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 <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 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;
}