From 84807fceb85ea583aedd2a0701966a484acb0d35 Mon Sep 17 00:00:00 2001 From: John Millaway Date: Tue, 21 Mar 2006 21:22:33 +0000 Subject: [PATCH] Reverted previous input filter changes. Added noop macro to scanner output. Modified scan.l to escape m4 quotes found in user code. --- filter.c | 83 +++++++++--------------------------- flexdef.h | 2 +- main.c | 4 +- scan.l | 123 +++++++++++++++++++++++++++++++++++------------------- 4 files changed, 105 insertions(+), 107 deletions(-) diff --git a/filter.c b/filter.c index 409f044..e60e083 100644 --- a/filter.c +++ b/filter.c @@ -126,7 +126,7 @@ struct filter *filter_create_int (struct filter *chain, * @param chain The head of the chain. * @return true on success. */ -bool filter_apply_chain (struct filter * chain, const bool parent_to_child) +bool filter_apply_chain (struct filter * chain) { int pid, pipes[2]; @@ -135,7 +135,7 @@ bool filter_apply_chain (struct filter * chain, const bool parent_to_child) * to be children of the main flex process. */ if (chain) - filter_apply_chain (chain->next, parent_to_child); + filter_apply_chain (chain->next); else return true; @@ -154,29 +154,17 @@ bool filter_apply_chain (struct filter * chain, const bool parent_to_child) if (pid == 0) { /* child */ - /* For the parent_to_child direction, we need stdin (the FILE* stdin) - * to connect to this new pipe. There is no portable way to set stdin - * to a new file descriptor, as stdin is not an lvalue on some systems - * (BSD). So we dup the new pipe onto the stdin descriptor and use a - * no-op fseek to sync the stream. This is a Hail Mary situation. It - * seems to work. Note that the same concept applies, but opposite, - * for child_to_parent filters. + /* We need stdin (the FILE* stdin) to connect to this new pipe. + * There is no portable way to set stdin to a new file descriptor, + * as stdin is not an lvalue on some systems (BSD). + * So we dup the new pipe onto the stdin descriptor and use a no-op fseek + * to sync the stream. This is a Hail Mary situation. It seems to work. */ - - if (parent_to_child){ - close (pipes[1]); - if (dup2 (pipes[0], fileno (stdin)) == -1) - flexfatal (_("dup2(pipes[0],0)")); - close (pipes[0]); - fseek (stdin, 0, SEEK_CUR); - } - else{ - close (pipes[0]); - if (dup2 (pipes[1], fileno (stdout)) == -1) - flexfatal (_("dup2(pipes[1],1)")); - close (pipes[1]); - fseek (stdout, 0, SEEK_CUR); - } + close (pipes[1]); + if (dup2 (pipes[0], fileno (stdin)) == -1) + flexfatal (_("dup2(pipes[0],0)")); + close (pipes[0]); + fseek (stdin, 0, SEEK_CUR); /* run as a filter, either internally or by exec */ if (chain->filter_func) { @@ -196,20 +184,11 @@ bool filter_apply_chain (struct filter * chain, const bool parent_to_child) } /* Parent */ - if (parent_to_child){ - close (pipes[0]); - if (dup2 (pipes[1], fileno (stdout)) == -1) - flexfatal (_("dup2(pipes[1],1)")); - close (pipes[1]); - fseek (stdout, 0, SEEK_CUR); - } - else{ - close (pipes[1]); - if (dup2 (pipes[0], fileno (stdin)) == -1) - flexfatal (_("dup2(pipes[0],0)")); - close (pipes[0]); - fseek (stdin, 0, SEEK_CUR); - } + close (pipes[0]); + if (dup2 (pipes[1], fileno (stdout)) == -1) + flexfatal (_("dup2(pipes[1],1)")); + close (pipes[1]); + fseek (stdout, 0, SEEK_CUR); return true; } @@ -267,7 +246,7 @@ int filter_tee_header (struct filter *chain) if (freopen ((char *) chain->extra, "w", stdout) == NULL) flexfatal (_("freopen(headerfilename) failed")); - filter_apply_chain (chain->next, true); + filter_apply_chain (chain->next); to_h = stdout; } @@ -279,6 +258,7 @@ int filter_tee_header (struct filter *chain) fputs ("m4_changecom`'m4_dnl\n", to_h); fputs ("m4_changequote`'m4_dnl\n", to_h); fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_h); + fputs ("m4_define([[M4_YY_NOOP]])[[]]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); @@ -294,6 +274,7 @@ int filter_tee_header (struct filter *chain) fputs ("m4_changecom`'m4_dnl\n", to_c); fputs ("m4_changequote`'m4_dnl\n", to_c); fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_c); + fputs ("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_c); fprintf (to_c, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", outfilename ? outfilename : ""); @@ -424,28 +405,4 @@ int filter_fix_linedirs (struct filter *chain) return 0; } -/* set_input_file - open the given file (if NULL, stdin) for scanning */ - -void set_input_file( file ) -char *file; -{ - /* Preprocess the input to quote m4 escapes.*/ - if ( file && strcmp( file, "-" ) ) - { - infilename = copy_string( file ); - yyin = fopen( infilename, "r" ); - - if ( yyin == NULL ) - lerrsf( _( "can't open %s" ), file ); - } - - else - { - yyin = stdin; - infilename = copy_string( "" ); - } - - linenum = 1; -} - /* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ diff --git a/flexdef.h b/flexdef.h index 322b554..8e99bb8 100644 --- a/flexdef.h +++ b/flexdef.h @@ -1160,7 +1160,7 @@ extern struct filter *filter_create_ext PROTO((struct filter * chain, const char struct filter *filter_create_int PROTO((struct filter *chain, int (*filter_func) (struct filter *), void *extra)); -extern bool filter_apply_chain PROTO((struct filter * chain, const bool parent_to_child)); +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)); extern int filter_fix_linedirs PROTO((struct filter *chain)); diff --git a/main.c b/main.c index 8a5d494..0ead73a 100644 --- a/main.c +++ b/main.c @@ -137,6 +137,8 @@ static char outfile_path[MAXLINE]; static int outfile_created = 0; static char *skelname = NULL; static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ +const char *escaped_qstart = "[[]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[[]]"; +const char *escaped_qend = "[[]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[[]]"; /* For debugging. The max number of filters to apply to skeleton. */ static int preproc_level = 1000; @@ -367,7 +369,7 @@ void check_options () /* For debugging, only run the requested number of filters. */ if (preproc_level > 0) { filter_truncate(output_chain, preproc_level); - filter_apply_chain(output_chain, true); + filter_apply_chain(output_chain); } yyout = stdout; diff --git a/scan.l b/scan.l index 831f291..f6cd9d9 100644 --- a/scan.l +++ b/scan.l @@ -36,6 +36,7 @@ #include "parse.h" extern bool tablesverify, tablesext; extern int trlcontxt; /* Set in parse.y for each rule. */ +extern const char *escaped_qstart, *escaped_qend; #define ACTION_ECHO add_action( yytext ) #define ACTION_IFDEF(def, should_define) \ @@ -44,6 +45,9 @@ extern int trlcontxt; /* Set in parse.y for each rule. */ action_define( def, 1 ); \ } +#define ACTION_ECHO_QSTART add_action (escaped_qstart) +#define ACTION_ECHO_QEND add_action (escaped_qend) + #define ACTION_M4_IFDEF(def, should_define) \ do{ \ if ( should_define ) \ @@ -117,6 +121,9 @@ CCL_EXPR ("[:"[[:alpha:]]+":]") LEXOPT [aceknopr] +M4QSTART "[[" +M4QEND "]]" + %% static int bracelevel, didadef, indented_code; static int doing_rule_action = false; @@ -146,7 +153,7 @@ LEXOPT [aceknopr] brace_depth = 1; yy_push_state(CODEBLOCK_MATCH_BRACE); } - + ^"%top".* synerr( _("malformed '%top' directive") ); {WS} /* discard */ @@ -172,14 +179,14 @@ LEXOPT [aceknopr] ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) ); ^{NAME} { - if(yyleng < MAXLINE) - { + if(yyleng < MAXLINE) + { strcpy( nmstr, yytext ); - } - else - { - synerr( _("Input line too long\n")); - FLEX_EXIT(EXIT_FAILURE); + } + else + { + synerr( _("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); } didadef = false; @@ -195,8 +202,10 @@ LEXOPT [aceknopr] { "*/" ACTION_ECHO; yy_pop_state(); "*" ACTION_ECHO; - [^*\n]+ ACTION_ECHO; - [^*\n]*{NL} ++linenum; ACTION_ECHO; + {M4QSTART} ACTION_ECHO_QSTART; + {M4QEND} ACTION_ECHO_QEND; + [^*\n] ACTION_ECHO; + {NL} ++linenum; ACTION_ECHO; } { @@ -214,7 +223,9 @@ LEXOPT [aceknopr] { ^"%}".*{NL} ++linenum; BEGIN(INITIAL); - {NAME}|{NOT_NAME}|. ACTION_ECHO; + {M4QSTART} ACTION_ECHO_QSTART; + {M4QEND} ACTION_ECHO_QEND; + . ACTION_ECHO; {NL} { ++linenum; @@ -233,7 +244,7 @@ LEXOPT [aceknopr] buf_strnappend(&top_buf, yytext, yyleng); } - "{" { + "{" { brace_depth++; buf_strnappend(&top_buf, yytext, yyleng); } @@ -243,9 +254,12 @@ LEXOPT [aceknopr] buf_strnappend(&top_buf, yytext, yyleng); } - [^{}\r\n]+ { + {M4QSTART} buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart)); + {M4QEND} buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend)); + + [^{}\r\n] { buf_strnappend(&top_buf, yytext, yyleng); - } + } <> { linenum = brace_start_line; @@ -262,11 +276,11 @@ LEXOPT [aceknopr] if(yyleng < MAXLINE) { strcpy( (char *) nmdef, yytext ); - } + } else { synerr( _("Input line too long\n")); - FLEX_EXIT(EXIT_FAILURE); + FLEX_EXIT(EXIT_FAILURE); } /* Skip trailing whitespace. */ for ( i = strlen( (char *) nmdef ) - 1; @@ -401,14 +415,14 @@ LEXOPT [aceknopr] \"[^"\n]*\" { - if(yyleng-1 < MAXLINE) - { + if(yyleng-1 < MAXLINE) + { strcpy( nmstr, yytext + 1 ); - } - else - { - synerr( _("Input line too long\n")); - FLEX_EXIT(EXIT_FAILURE); + } + else + { + synerr( _("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); } nmstr[strlen( nmstr ) - 1] = '\0'; return NAME; @@ -442,7 +456,7 @@ LEXOPT [aceknopr] ACTION_ECHO; } - .* ACTION_ECHO; + . ACTION_ECHO; {NL} ++linenum; ACTION_ECHO; <> { @@ -540,15 +554,15 @@ LEXOPT [aceknopr] "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})* { int cclval; - if(yyleng < MAXLINE) - { + if(yyleng < MAXLINE) + { strcpy( nmstr, yytext ); - } - else - { - synerr( _("Input line too long\n")); - FLEX_EXIT(EXIT_FAILURE); - } + } + else + { + synerr( _("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } /* Check to see if we've already encountered this * ccl. @@ -586,19 +600,19 @@ LEXOPT [aceknopr] "{"{NAME}"}"[[:space:]]? { register Char *nmdefptr; int end_is_ws, end_ch; - + end_ch = yytext[yyleng-1]; end_is_ws = end_ch != '}' ? 1 : 0; - if(yyleng-1 < MAXLINE) - { + if(yyleng-1 < MAXLINE) + { strcpy( nmstr, yytext + 1 ); - } - else - { - synerr( _("Input line too long\n")); - FLEX_EXIT(EXIT_FAILURE); - } + } + else + { + synerr( _("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } nmstr[yyleng - 2 - end_is_ws] = '\0'; /* chop trailing brace */ if ( (nmdefptr = ndlookup( nmstr )) == 0 ) @@ -813,7 +827,10 @@ nmstr[yyleng - 2 - end_is_ws] = '\0'; /* chop trailing brace */ { - .*(\n?) ECHO; + {M4QSTART} fwrite (escaped_qstart, 1, strlen(escaped_qstart), yyout); + {M4QEND} fwrite (escaped_qend, 1, strlen(escaped_qend), yyout); + [^\[\]\n]*(\n?) ECHO; + (.|\n) ECHO; <> sectnum = 0; yyterminate(); } @@ -835,6 +852,28 @@ int yywrap() } +/* set_input_file - open the given file (if NULL, stdin) for scanning */ + +void set_input_file( file ) +char *file; + { + if ( file && strcmp( file, "-" ) ) + { + infilename = copy_string( file ); + yyin = fopen( infilename, "r" ); + + if ( yyin == NULL ) + lerrsf( _( "can't open %s" ), file ); + } + + else + { + yyin = stdin; + infilename = copy_string( "" ); + } + + linenum = 1; + } /* Wrapper routines for accessing the scanner's malloc routines. */ -- 2.40.0