summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillaway <millaway>2003-03-14 19:25:54 +0000
committermillaway <millaway>2003-03-14 19:25:54 +0000
commit3393d15698b935f2e3442754ab22cfa50bf8c971 (patch)
tree163451dfcc4b9c5882c3141d26448e7b7e5814e8
parent9b5403e466ef1c6b1e3714380d2dc26ebd70bcfa (diff)
downloadflex-3393d15698b935f2e3442754ab22cfa50bf8c971.tar.gz
Filters are now direct children of main process.
Header file now generated through m4.
-rw-r--r--filter.c135
-rw-r--r--flex.skl6
-rw-r--r--flexdef.h5
-rw-r--r--gen.c8
-rw-r--r--main.c4
-rw-r--r--scan.l2
-rw-r--r--tests/test-reject/scanner.l11
7 files changed, 124 insertions, 47 deletions
diff --git a/filter.c b/filter.c
index 7a93a4e..34659b3 100644
--- a/filter.c
+++ b/filter.c
@@ -102,7 +102,8 @@ struct filter *filter_create_ext (struct filter *chain, const char *cmd,
* @return newest filter in chain
*/
struct filter *filter_create_int (struct filter *chain,
- int (*filter_func) (struct filter *), void *extra)
+ int (*filter_func) (struct filter *),
+ void *extra)
{
struct filter *f;
@@ -134,8 +135,17 @@ bool filter_apply_chain (struct filter * chain)
{
int pid, pipes[2];
- if (chain == NULL)
- return true;
+ /* Tricky recursion, since we want to begin the chain
+ * at the END. Why? Because we need all the forked processes
+ * to be children of the main flex process.
+ */
+ if (chain)
+ filter_apply_chain(chain->next);
+ else
+ return true;
+
+ /* Now we are the right-most unprocessed link in the chain.
+ */
fflush (stdout);
fflush (stderr);
@@ -152,27 +162,27 @@ bool filter_apply_chain (struct filter * chain)
if (dup2 (pipes[0], 0) == -1)
flexfatal (_("dup2(pipes[0],0)"));
close (pipes[0]);
- if ((stdin = fdopen (0, "r")) == NULL)
- flexfatal (_("fdopen(0) failed"));
-
- /* recursively apply rest of chain. */
- filter_apply_chain (chain->next);
-
- /* run this filter, either internally or by execvp */
- if (chain->filter_func){
- int r = chain->filter_func(chain);
- if (r == -1)
- flexfatal (_("filter_func failed"));
- else{
- close(0);
- close(1);
- exit(0);
- }
- }
- else{
- execvp (chain->argv[0], (char **const) (chain->argv));
+
+ /* run as a filter, either internally or by exec */
+ if (chain->filter_func) {
+ int r;
+
+ /* setup streams again */
+ if ((stdin = fdopen (0, "r")) == NULL)
+ flexfatal (_("fdopen(0) failed"));
+ if ((stdout = fdopen (1, "w")) == NULL)
+ flexfatal (_("fdopen(1) failed"));
+
+ if((r = chain->filter_func (chain)) == -1)
+ flexfatal (_("filter_func failed"));
+ exit(0);
+ }
+ else {
+ execvp (chain->argv[0],
+ (char **const) (chain->argv));
flexfatal (_("exec failed"));
- }
+ }
+
exit (1);
}
@@ -211,17 +221,80 @@ int filter_truncate (struct filter *chain, int max_len)
/** Splits the chain in order to write to a header file.
* Similar in spirit to the 'tee' program.
* The header file name is in extra.
+ * @return 0 (zero) on success, and -1 on failure.
*/
-int filter_tee (struct filter *chain)
+int filter_tee_header (struct filter *chain)
{
- const int readsz = 512;
- char * buf;
-
- buf = (char*)flex_alloc(readsz);
- header_out = fopen (headerfilename, "w");
-
- execlp("cat","cat",NULL);
+ /* This function reads from stdin and writes to both the C file and the
+ * header file at the same time.
+ */
+
+ const int readsz = 512;
+ char *buf;
+ int to_cfd;
+ FILE *to_c, *to_h;
+
+ fprintf(stderr,"filter_tee()\n");fflush(stderr);
+
+ if (!chain->extra) {
+ /* No header file was specified, so we become a transparent
+ * filter.
+ */
+ fprintf(stderr,"\texeclp(cat)\n");fflush(stderr);
+ execlp ("cat", "cat", NULL);
+ flexfatal (_("exec failed"));
+ }
+
+ /* Store a copy of the stdout pipe, which is already piped to C file
+ * through the running chain. Then create a new pipe to the H file as
+ * stdout, and fork the rest of the chain again.
+ */
+
+ if ((to_cfd = dup (1)) == -1)
+ flexfatal (_("dup(1) failed"));
+
+ if (freopen ((char *) chain->extra, "w", stdout) == NULL)
+ flexfatal (_("freopen(headerfilename) failed"));
+
+ filter_apply_chain (chain->next);
+
+ to_c = fdopen (to_cfd, "w");
+ to_h = stdout;
+
+ /* Now to_c is a pipe to the C branch, and to_h is a pipe to the H branch.
+ */
+
+ fprintf(stderr,"\tpid(%d): to_c=%d, to_h=%d\n",
+ getpid(),fileno(to_c),fileno(to_h)); fflush(stderr);
+
+ fputs ("m4_changequote`'m4_dnl\n", to_h);
+ fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_h);
+ fputs ("m4_define( [[M4_YY_IN_HEADER]],[[]])m4_dnl\n", to_h);
+ fprintf (to_h, "#ifndef %sHEADER_H\n", prefix);
+ fprintf (to_h, "#define %sHEADER_H 1\n", prefix);
+ fprintf (to_h, "#define %sIN_HEADER 1\n\n", prefix);
+
+ buf = (char *) flex_alloc (readsz);
+ while (fgets (buf, readsz, stdin)) {
+ fputs (buf, to_c);
+ fputs (buf, to_h);
+ }
+
+ fprintf (to_h, "\n");
+ fprintf (to_h, "#undef %sIN_HEADER\n", prefix);
+ fprintf (to_h, "#endif /* %sHEADER_H */\n", prefix);
+ fputs ("m4_undefine( [[M4_YY_IN_HEADER]])m4_dnl\n", to_h);
+
+ fflush (to_c);
+ fclose (to_c);
+
+ fflush (to_h);
+ fclose (to_h);
+
+ while(wait(0) > 0)
+ ;
+ exit(0);
return 0;
}
diff --git a/flex.skl b/flex.skl
index 82c7fe1..8c9baf9 100644
--- a/flex.skl
+++ b/flex.skl
@@ -1486,7 +1486,8 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
%if-c-only
-#ifndef YY_NO_UNPUT
+m4_ifdef( [[M4_YY_NO_UNPUT]],,
+[[
static void yyunput YYFARGS2( int,c, register char *,yy_bp)
%endif
%if-c++-only
@@ -1534,7 +1535,7 @@ m4_ifdef( [[M4_YY_USE_LINENO]],
YY_G(yy_c_buf_p) = yy_cp;
}
%if-c-only
-#endif /* ifndef YY_NO_UNPUT */
+]])
%endif
%if-c-only
@@ -2397,7 +2398,6 @@ int yylex_init( ptr_yy_globals )
/* yylex_destroy is for both reentrant and non-reentrant scanners. */
int yylex_destroy YYFARGS0(void)
{
- int i;
M4_YY_DECL_GUTS_VAR();
/* Pop the buffer stack, destroying each element. */
diff --git a/flexdef.h b/flexdef.h
index f7aa8d4..585ea49 100644
--- a/flexdef.h
+++ b/flexdef.h
@@ -1102,8 +1102,8 @@ extern struct Buf yydmap_buf;
extern struct Buf m4defs_buf;
/* For blocking out code from the header file. */
-#define OUT_BEGIN_CODE() out_str("#ifndef %sIN_HEADER /* YY-DISCARD-FROM-HEADER */\n",prefix)
-#define OUT_END_CODE() out_str("#endif /* !%sIN_HEADER YY-END-DISCARD-FROM-HEADER */\n",prefix);
+#define OUT_BEGIN_CODE() outn("m4_ifdef( [[M4_YY_IN_HEADER]],,[[")
+#define OUT_END_CODE() outn("]])")
/* For setjmp/longjmp (instead of calling exit(2)). Linkage in main.c */
extern jmp_buf flex_main_jmp_buf;
@@ -1161,5 +1161,6 @@ struct filter *filter_create_int PROTO((struct filter *chain,
void *extra));
extern bool filter_apply_chain PROTO((struct filter * chain));
extern int filter_truncate (struct filter * chain, int max_len);
+extern int filter_tee_header PROTO((struct filter *chain));
#endif /* not defined FLEXDEF_H */
diff --git a/gen.c b/gen.c
index 7c7dfa0..73fa5d3 100644
--- a/gen.c
+++ b/gen.c
@@ -762,19 +762,19 @@ void gen_next_match ()
* gen_NUL_trans().
*/
char *char_map = useecs ?
- "yy_ec[YY_SC_TO_UI(*yy_cp)]" : "YY_SC_TO_UI(*yy_cp)";
+ "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)";
char *char_map_2 = useecs ?
- "yy_ec[YY_SC_TO_UI(*++yy_cp)]" : "YY_SC_TO_UI(*++yy_cp)";
+ "yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)";
if (fulltbl) {
if (gentables)
indent_put2s
- ("while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
+ ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )",
char_map);
else
indent_put2s
- ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s]) > 0 )",
+ ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s ]) > 0 )",
char_map);
indent_up ();
diff --git a/main.c b/main.c
index 1c2b787..4cd3f29 100644
--- a/main.c
+++ b/main.c
@@ -341,7 +341,7 @@ void check_options ()
}
/* Setup the filter chain. */
- output_chain = filter_create_int(NULL, filter_tee, headerfilename);
+ output_chain = filter_create_int(NULL, filter_tee_header, headerfilename);
filter_create_ext(output_chain,"m4","-P",0);
/* For debugging, only run the requested number of filters. */
@@ -599,7 +599,7 @@ void flexend (exit_status)
* reason we currently can't provide a mechanism to allow the user
* to inject arbitrary class members into the generated C++ scanner. - JM
*/
- if (headerfilename && exit_status == 0 && outfile_created
+ if (false && headerfilename && exit_status == 0 && outfile_created
&& !ferror (stdout)) {
/* Copy the file we just wrote to a header file. */
#define LINE_SZ 512
diff --git a/scan.l b/scan.l
index 7bcec3b..0e5b1eb 100644
--- a/scan.l
+++ b/scan.l
@@ -307,7 +307,7 @@ LEXOPT [aceknopr]
stdinit do_stdinit = option_sense;
stdout use_stdout = option_sense;
unistd ACTION_IFDEF("YY_NO_UNISTD_H", ! option_sense);
- unput ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);
+ unput ACTION_M4_IFDEF("M4_YY_NO_UNPUT", ! option_sense);
verbose printstats = option_sense;
warn nowarn = ! option_sense;
yylineno do_yylineno = option_sense; ACTION_M4_IFDEF("M4_YY_USE_LINENO", option_sense);
diff --git a/tests/test-reject/scanner.l b/tests/test-reject/scanner.l
index a561bd7..a90a1fa 100644
--- a/tests/test-reject/scanner.l
+++ b/tests/test-reject/scanner.l
@@ -50,7 +50,9 @@ m4_ifdef( [[M4_YY_REENTRANT]],
[[
yylex_init(&yyscanner);
]])
-#ifdef YY_TABLES_EXTERNAL
+
+m4_ifdef( [[M4_YY_TABLES_EXTERNAL]],
+[[
if((fp = fopen(argv[1],"r"))== NULL)
yy_fatal_error("could not open tables file for reading" M4_YY_CALL_LAST_ARG);
@@ -58,7 +60,7 @@ m4_ifdef( [[M4_YY_REENTRANT]],
yy_fatal_error("yytables_fload returned < 0" M4_YY_CALL_LAST_ARG);
if(M4_YY_TABLES_VERIFY)
exit(0);
-#endif
+]])
if(argc > 2){
if((fp = fopen(argv[2],"r"))== NULL)
@@ -68,9 +70,10 @@ m4_ifdef( [[M4_YY_REENTRANT]],
while(yylex(M4_YY_CALL_ONLY_ARG) != 0)
;
-#ifdef YY_TABLES_EXTERNAL
+m4_ifdef( [[M4_YY_TABLES_EXTERNAL]],
+[[
yytables_destroy(M4_YY_CALL_ONLY_ARG);
-#endif
+]])
yylex_destroy(M4_YY_CALL_ONLY_ARG);
if(argc < 0) /* silence the compiler */