summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter.c83
-rw-r--r--flexdef.h2
-rw-r--r--main.c4
-rw-r--r--scan.l123
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 : "<stdout>");
@@ -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( "<stdin>" );
- }
-
- 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]
<COMMENT>{
"*/" 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;
}
<LINEDIR>{
@@ -214,7 +223,9 @@ LEXOPT [aceknopr]
<CODEBLOCK>{
^"%}".*{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);
- }
+ }
<<EOF>> {
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;
<<EOF>> {
@@ -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 */
<SECT3>{
- .*(\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;
<<EOF>> 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( "<stdin>" );
+ }
+
+ linenum = 1;
+ }
/* Wrapper routines for accessing the scanner's malloc routines. */