+diff -urN -X ./diff-exclude flex-2.5.31/flex.skl flex/flex.skl
--- flex-2.5.31/flex.skl 2003-04-01 04:51:38.000000000 +0300
-+++ flex/flex.skl 2003-10-24 21:47:10.000000000 +0300
-@@ -27,6 +27,11 @@
++++ flex/flex.skl 2004-01-02 12:22:33.000000000 +0200
+@@ -27,6 +27,13 @@
%# Macros for runtime processing stage.
m4_changecom
m4_changequote
+
-+%# Let user use our quoting strings
++%# Support for m4 quote escaping
+m4_changequote({, })
+m4_define( {m4_userquote_start}, {m4_changequote(<, >)[[m4_changequote([[, ]])})
+m4_define( {m4_userquote_end}, {m4_changequote(<, >)]]m4_changequote([[, ]])})
++
++%# Setup quoting
m4_changequote([[, ]])
%#
+diff -urN -X ./diff-exclude flex-2.5.31/flexdef.h flex/flexdef.h
+--- flex-2.5.31/flexdef.h 2003-04-01 04:51:38.000000000 +0300
++++ flex/flexdef.h 2004-01-02 12:14:49.000000000 +0200
+@@ -373,6 +373,7 @@
+ * yymore_really_used - whether to treat yymore() as really used, regardless
+ * of what we think based on references to it in the user's actions.
+ * reject_really_used - same for REJECT
++ * keep_m4 - dont quote m4 quotes "[[", "]]" - so user can use m4
+ */
+
+ extern int printstats, syntaxerror, eofseen, ddebug, trace, nowarn,
+@@ -387,7 +388,7 @@
+ extern int yymore_used, reject, real_reject, continued_action, in_rule;
+
+ extern int yymore_really_used, reject_really_used;
+-
++extern int keep_m4;
+
+ /* Variables used in the flex input routines:
+ * datapos - characters on current output line
+diff -urN -X ./diff-exclude flex-2.5.31/main.c flex/main.c
+--- flex-2.5.31/main.c 2003-04-01 04:51:38.000000000 +0300
++++ flex/main.c 2004-01-02 12:13:07.000000000 +0200
+@@ -106,6 +106,7 @@
+ bool *rule_has_nl, *ccl_has_nl;
+ int nlch = '\n';
+ bool ansi_func_defs, ansi_func_protos;
++int keep_m4;
+
+ bool tablesext, tablesverify, gentables;
+ char *tablesfilename=0,*tablesname=0;
+@@ -999,6 +1000,10 @@
+ case OPT_DONOTHING:
+ break;
+
++ case OPT_KEEP_M4:
++ keep_m4 = true;
++ break;
++
+ case OPT_COMPRESSION:
+ if (!sawcmpflag) {
+ useecs = false;
+diff -urN -X ./diff-exclude flex-2.5.31/options.c flex/options.c
+--- flex-2.5.31/options.c 2003-03-25 18:39:08.000000000 +0200
++++ flex/options.c 2004-01-02 12:16:07.000000000 +0200
+@@ -42,6 +42,10 @@
+ /* The command-line options, passed to scanopt_init() */
+ optspec_t flexopts[] = {
+
++ {"-4", OPT_KEEP_M4, 0}
++ ,
++ {"--keep-m4", OPT_KEEP_M4, 0}
++ , /* dont try to quote m4 */
+ {"-7", OPT_7BIT, 0}
+ ,
+ {"--7bit", OPT_7BIT, 0}
+diff -urN -X ./diff-exclude flex-2.5.31/options.h flex/options.h
+--- flex-2.5.31/options.h 2003-03-25 18:39:08.000000000 +0200
++++ flex/options.h 2004-01-02 12:15:30.000000000 +0200
+@@ -61,6 +61,7 @@
+ OPT_HEADER_FILE,
+ OPT_HELP,
+ OPT_INTERACTIVE,
++ OPT_KEEP_M4,
+ OPT_LEX_COMPAT,
+ OPT_POSIX_COMPAT,
+ OPT_MAIN,
+diff -urN -X ./diff-exclude flex-2.5.31/scan.l flex/scan.l
--- flex-2.5.31/scan.l 2003-04-01 04:51:38.000000000 +0300
-+++ flex/scan.l 2003-10-24 21:51:20.000000000 +0300
-@@ -194,8 +194,14 @@
++++ flex/scan.l 2004-01-02 12:00:21.000000000 +0200
+@@ -88,6 +88,29 @@
+ if ( getenv("POSIXLY_CORRECT") ) \
+ posix_compat = true;
+
++/* Macros need to be clearly separated from surrounding text
++ and this file needs to go through (unpatched) flex untouched. */
++static char *userquote_start = "[" "[]" "]m4_" "userquote_start()";
++static char *userquote_end = "[" "[]" "]m4_" "userquote_end()";
++
++#define QUOTE4_START \
++ do { \
++ if (keep_m4) { \
++ ACTION_ECHO; \
++ } else { \
++ add_action(userquote_start); \
++ } \
++ } while (0)
++
++#define QUOTE4_END \
++ do { \
++ if (keep_m4) { \
++ ACTION_ECHO; \
++ } else { \
++ add_action(userquote_end); \
++ } \
++ } while (0)
++
+ %}
+
+ %option caseless nodefault stack noyy_top_state
+@@ -95,7 +118,7 @@
+
+ %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
+ %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
+-%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE
++%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE PROLOGLINE
+
+ WS [[:blank:]]+
+ OPTWS [[:blank:]]*
+@@ -194,8 +217,11 @@
<COMMENT>{
"*/" ACTION_ECHO; yy_pop_state();
"*" ACTION_ECHO;
+ [\[\]] ACTION_ECHO;
+ [^*\[\]\n]+ ACTION_ECHO;
+ [^*\[\]\n]*{NL} ++linenum; ACTION_ECHO;
-+ \[\[ add_action("[" "[]" "]m4_" "userquote_start()");
-+ \]\] add_action("[" "[]" "]m4_" "userquote_end()");
-+ /* Macros need to be clearly separated from surrounding
-+ * text and this file needs to go through flex untouched.
-+ */
++ \[\[ QUOTE4_START;
++ \]\] QUOTE4_END;
}
<LINEDIR>{
+@@ -213,7 +239,11 @@
+ <CODEBLOCK>{
+ ^"%}".*{NL} ++linenum; BEGIN(INITIAL);
+
+- {NAME}|{NOT_NAME}|. ACTION_ECHO;
++ \[\[ QUOTE4_START;
++ \]\] QUOTE4_END;
++
++ [^\n\]\[]+ ACTION_ECHO;
++ [\]\[] ACTION_ECHO;
+
+ {NL} {
+ ++linenum;
+@@ -242,10 +272,25 @@
+ buf_strnappend(&top_buf, yytext, yyleng);
+ }
+
+- [^{}\r\n]+ {
++ [^{}\[\]\r\n]+ {
+ buf_strnappend(&top_buf, yytext, yyleng);
+ }
+
++ [\]\[] buf_strnappend(&top_buf, yytext, yyleng);
++
++ \[\[ {
++ if (keep_m4)
++ buf_strnappend(&top_buf, yytext, yyleng);
++ else
++ buf_strappend(&top_buf, userquote_start);
++ }
++ \]\] {
++ if (keep_m4)
++ buf_strnappend(&top_buf, yytext, yyleng);
++ else
++ buf_strappend(&top_buf, userquote_end);
++ }
++
+ <<EOF>> {
+ linenum = brace_start_line;
+ synerr(_("Unmatched '{'"));
+@@ -424,33 +469,48 @@
+
+
+ <SECT2PROLOG>{
+- ^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */
+- ^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */
+-
+- ^{WS}.* ACTION_ECHO; /* indented code in prolog */
++ ^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */
++ ^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */
+
++ ^{WS}.* { /* indented code in prolog */
++ yyless(0);
++ BEGIN(PROLOGLINE);
++ }
+ ^{NOT_WS}.* { /* non-indented code */
++ yyless( 0 ); /* put it all back */
+ if ( bracelevel <= 0 )
+ { /* not in %{ ... %} */
+- yyless( 0 ); /* put it all back */
+ yy_set_bol( 1 );
+ mark_prolog();
+ BEGIN(SECT2);
+ }
+ else
+- ACTION_ECHO;
++ BEGIN(PROLOGLINE);
+ }
+
+- .* ACTION_ECHO;
+- {NL} ++linenum; ACTION_ECHO;
++ .* yyless(0); BEGIN(PROLOGLINE);
+
+- <<EOF>> {
+- mark_prolog();
+- sectnum = 0;
+- yyterminate(); /* to stop the parser */
++ {NL} ++linenum; ACTION_ECHO;
++}
++
++<PROLOGLINE>{
++ [^\]\[\n\r]* ACTION_ECHO;
++ \[\[ QUOTE4_START;
++ \]\] QUOTE4_END;
++ [\]\[] ACTION_ECHO;
++ {NL} {
++ ++linenum;
++ ACTION_ECHO;
++ BEGIN(SECT2PROLOG);
+ }
+ }
+
++<PROLOGLINE,SECT2PROLOG><<EOF>> {
++ mark_prolog();
++ sectnum = 0;
++ yyterminate();
++ }
++
+ <SECT2>{
+ ^{OPTWS}{NL} ++linenum; /* allow blank lines in section 2 */
+
+@@ -768,10 +828,15 @@
+ <ACTION>{
+ "{" ACTION_ECHO; ++bracelevel;
+ "}" ACTION_ECHO; --bracelevel;
+- [^[:alpha:]_{}"'/\n]+ ACTION_ECHO;
++ [^[:alpha:]_{}\[\]"'/\n]+ ACTION_ECHO;
+ {NAME} ACTION_ECHO;
+ "'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
+ \" ACTION_ECHO; BEGIN(ACTION_STRING);
++
++ \[\[ QUOTE4_START;
++ \]\] QUOTE4_END;
++ [\]\[] ACTION_ECHO;
++
+ {NL} {
+ ++linenum;
+ ACTION_ECHO;
+@@ -788,7 +853,10 @@
+ }
+
+ <ACTION_STRING>{
+- [^"\\\n]+ ACTION_ECHO;
++ [^"\]\[\\\n]+ ACTION_ECHO;
++ \[\[ QUOTE4_START;
++ \]\] QUOTE4_END;
++ [\]\[] ACTION_ECHO;
+ \\. ACTION_ECHO;
+ {NL} ++linenum; ACTION_ECHO; BEGIN(ACTION);
+ \" ACTION_ECHO; BEGIN(ACTION);
+@@ -812,7 +880,21 @@
+
+
+ <SECT3>{
+- .*(\n?) ECHO;
++ [^\]\[\n\r]*({NL})? ECHO;
++
++ \[\[ if (keep_m4) {
++ ECHO;
++ } else {
++ fputs(userquote_start, yyout);
++ }
++ \]\] if (keep_m4) {
++ ECHO;
++ } else {
++ fputs(userquote_end, yyout);
++ }
++
++ [\]\[] ECHO;
++
+ <<EOF>> sectnum = 0; yyterminate();
+ }
+
+diff -urN -X ./diff-exclude flex-2.5.31/tests/Makefile.am flex/tests/Makefile.am
+--- flex-2.5.31/tests/Makefile.am 2003-03-27 20:02:59.000000000 +0200
++++ flex/tests/Makefile.am 2004-01-02 11:48:17.000000000 +0200
+@@ -40,6 +40,7 @@
+ test-c++-basic \
+ test-posixly-correct \
+ test-posix \
++ test-m4-quotes \
+ test-mem-r \
+ test-mem-nr \
+ test-debug-nr \
+@@ -81,6 +82,7 @@
+ test-c++-basic \
+ test-posixly-correct \
+ test-posix \
++ test-m4-quotes \
+ test-mem-r \
+ test-mem-nr \
+ test-debug-nr \
+diff -urN -X ./diff-exclude flex-2.5.31/tests/test-m4-quotes/Makefile.am flex/tests/test-m4-quotes/Makefile.am
+--- flex-2.5.31/tests/test-m4-quotes/Makefile.am 1970-01-01 03:00:00.000000000 +0300
++++ flex/tests/test-m4-quotes/Makefile.am 2004-01-02 11:49:06.000000000 +0200
+@@ -0,0 +1,44 @@
++# 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.
++
++FLEX = $(top_builddir)/flex
++
++builddir = @builddir@
++
++EXTRA_DIST = scanner.l test.input
++CLEANFILES = scanner.c scanner.h TEMPLATE OUTPUT $(OBJS)
++OBJS = scanner.o
++
++AM_CPPFLAGS = -I$(srcdir) -I$(builddir) -I$(top_srcdir) -I$(top_builddir)
++
++testname = TEMPLATE
++
++scanner.c: $(srcdir)/scanner.l
++ $(FLEX) $(LFLAGS) $<
++
++$(testname)$(EXEEXT): $(OBJS)
++ $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LOADLIBES)
++
++test: $(testname)$(EXEEXT)
++ ./$(testname)$(EXEEXT) < $(srcdir)/test.input
++
++.c.o:
++ $(CC) -c -o $@ $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $<
+diff -urN -X ./diff-exclude flex-2.5.31/tests/test-m4-quotes/scanner.l flex/tests/test-m4-quotes/scanner.l
+--- flex-2.5.31/tests/test-m4-quotes/scanner.l 1970-01-01 03:00:00.000000000 +0300
++++ flex/tests/test-m4-quotes/scanner.l 2004-01-02 11:49:33.000000000 +0200
+@@ -0,0 +1,93 @@
++/*
++ * 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.
++ */
++
++/* [[ grep qtest scanner.c ]] */
++
++%{
++
++#include <stdio.h>
++#include <stdlib.h>
++#include "config.h"
++
++/* qtest: ]] */
++
++static int a[10];
++static int b[10];
++static char *p = "]]"; /* qtest */
++
++#define fx1(x) a[b[0]] /* qtest */
++
++static void xerror(char *msg);
++
++%}
++
++%option 8bit outfile="scanner.c" prefix="test"
++%option nounput nomain noyywrap
++%option warn
++
++/* qtest: ]] [[ ]] */
++
++%%
++
++%{
++ /* qtest [[ ]] */
++ if (a[a[0]]) ; /* qtest */
++ p = "[["; /* qtest */
++%}
++ if (a[a[0]]) ; /* qtest */
++ p = "[["; /* qtest */
++
++[^a-e]* { }
++a if (a[a[0]]) ; /* qtest */
++b {
++ if (a[a[0]]) ; /* qtest */
++ p = "[["; /* qtest */
++ }
++c /* qtest: ]] [[ ]] */
++ /* qtest: ]] [[ ]] */
++d if (strlen(p) != 2) xerror("qtest [[ ]]\n");
++e if (strcmp(p, "[[")) xerror("qtest\n");
++
++
++%%
++
++/* qtest: ]] [[ ]] */
++
++int main(void);
++
++static void xerror(char *msg)
++{
++ fprintf(stderr, "error: %s\n", msg);
++ exit(1);
++}
++
++int
++main ()
++{
++ yyin = stdin;
++ yyout = stdout;
++ yylex();
++ if (a[a[0]]) ; /* qtest */
++ printf("TEST RETURNING OK.\n");
++ return 0;
++}
+diff -urN -X ./diff-exclude flex-2.5.31/tests/test-m4-quotes/test.input flex/tests/test-m4-quotes/test.input
+--- flex-2.5.31/tests/test-m4-quotes/test.input 1970-01-01 03:00:00.000000000 +0300
++++ flex/tests/test-m4-quotes/test.input 2004-01-02 11:49:49.000000000 +0200
+@@ -0,0 +1,7 @@
++a
++b
++c
++d
++e
++f
++g
+diff -urN -X ./diff-exclude flex-2.5.31/tests/test-reject/Makefile.am flex/tests/test-reject/Makefile.am
+--- flex-2.5.31/tests/test-reject/Makefile.am 2002-10-11 18:26:43.000000000 +0300
++++ flex/tests/test-reject/Makefile.am 2003-12-28 04:56:02.000000000 +0200
+@@ -20,7 +20,7 @@
+ # PURPOSE.
+
+
+-FLEX = $(top_builddir)/flex
++FLEX = $(top_builddir)/flex -4
+
+ EXTRA_DIST = scanner.l test.input
+ CLEANFILES = scanner.c test-reject-* OUTPUT $(OBJS)
+diff -urN -X ./diff-exclude flex-2.5.31/tests/test-table-opts/Makefile.am flex/tests/test-table-opts/Makefile.am
+--- flex-2.5.31/tests/test-table-opts/Makefile.am 2002-10-11 18:26:43.000000000 +0300
++++ flex/tests/test-table-opts/Makefile.am 2003-12-28 04:54:00.000000000 +0200
+@@ -29,7 +29,7 @@
+ # ------------------------------------------------
+
+
+-FLEX = $(top_builddir)/flex
++FLEX = $(top_builddir)/flex -4
+
+ testname := test-table-opts
+ allopts := -Ca -Ce -Cf -CF -Cm -Cem -Cae -Caef -CaeF -Cam -Caem