diff options
author | millaway <millaway> | 2003-03-14 19:25:54 +0000 |
---|---|---|
committer | millaway <millaway> | 2003-03-14 19:25:54 +0000 |
commit | 3393d15698b935f2e3442754ab22cfa50bf8c971 (patch) | |
tree | 163451dfcc4b9c5882c3141d26448e7b7e5814e8 | |
parent | 9b5403e466ef1c6b1e3714380d2dc26ebd70bcfa (diff) | |
download | flex-3393d15698b935f2e3442754ab22cfa50bf8c971.tar.gz |
Filters are now direct children of main process.
Header file now generated through m4.
-rw-r--r-- | filter.c | 135 | ||||
-rw-r--r-- | flex.skl | 6 | ||||
-rw-r--r-- | flexdef.h | 5 | ||||
-rw-r--r-- | gen.c | 8 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | scan.l | 2 | ||||
-rw-r--r-- | tests/test-reject/scanner.l | 11 |
7 files changed, 124 insertions, 47 deletions
@@ -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; } @@ -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. */ @@ -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 */ @@ -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 (); @@ -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 @@ -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 */ |