1228072Sbapt/* scan.l - scanner for flex input -*-C-*- */
2228072Sbapt
3228072Sbapt%{
4228072Sbapt/*  Copyright (c) 1990 The Regents of the University of California. */
5228072Sbapt/*  All rights reserved. */
6228072Sbapt
7228072Sbapt/*  This code is derived from software contributed to Berkeley by */
8228072Sbapt/*  Vern Paxson. */
9228072Sbapt
10228072Sbapt/*  The United States Government has rights in this work pursuant */
11228072Sbapt/*  to contract no. DE-AC03-76SF00098 between the United States */
12228072Sbapt/*  Department of Energy and the University of California. */
13228072Sbapt
14228072Sbapt/*  This file is part of flex. */
15228072Sbapt
16228072Sbapt/*  Redistribution and use in source and binary forms, with or without */
17228072Sbapt/*  modification, are permitted provided that the following conditions */
18228072Sbapt/*  are met: */
19228072Sbapt
20228072Sbapt/*  1. Redistributions of source code must retain the above copyright */
21228072Sbapt/*     notice, this list of conditions and the following disclaimer. */
22228072Sbapt/*  2. Redistributions in binary form must reproduce the above copyright */
23228072Sbapt/*     notice, this list of conditions and the following disclaimer in the */
24228072Sbapt/*     documentation and/or other materials provided with the distribution. */
25228072Sbapt
26228072Sbapt/*  Neither the name of the University nor the names of its contributors */
27228072Sbapt/*  may be used to endorse or promote products derived from this software */
28228072Sbapt/*  without specific prior written permission. */
29228072Sbapt
30228072Sbapt/*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
31228072Sbapt/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
32228072Sbapt/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
33228072Sbapt/*  PURPOSE. */
34228072Sbapt
35228072Sbapt#include "flexdef.h"
36228072Sbapt#include "parse.h"
37228072Sbaptextern bool tablesverify, tablesext;
38228072Sbaptextern int trlcontxt; /* Set in  parse.y for each rule. */
39228072Sbaptextern const char *escaped_qstart, *escaped_qend;
40228072Sbapt
41228072Sbapt#define ACTION_ECHO add_action( yytext )
42228072Sbapt#define ACTION_IFDEF(def, should_define) \
43228072Sbapt	{ \
44228072Sbapt	if ( should_define ) \
45228072Sbapt		action_define( def, 1 ); \
46228072Sbapt	}
47228072Sbapt
48228072Sbapt#define ACTION_ECHO_QSTART add_action (escaped_qstart)
49228072Sbapt#define ACTION_ECHO_QEND   add_action (escaped_qend)
50228072Sbapt
51228072Sbapt#define ACTION_M4_IFDEF(def, should_define) \
52228072Sbapt    do{ \
53228072Sbapt        if ( should_define ) \
54228072Sbapt            buf_m4_define( &m4defs_buf, def, NULL);\
55228072Sbapt        else \
56228072Sbapt            buf_m4_undefine( &m4defs_buf, def);\
57228072Sbapt    } while(0)
58228072Sbapt
59228072Sbapt#define MARK_END_OF_PROLOG mark_prolog();
60228072Sbapt
61228072Sbapt#define YY_DECL \
62228072Sbapt	int flexscan()
63228072Sbapt
64228072Sbapt#define RETURNCHAR \
65228072Sbapt	yylval = (unsigned char) yytext[0]; \
66228072Sbapt	return CHAR;
67228072Sbapt
68228072Sbapt#define RETURNNAME \
69228072Sbapt	if(yyleng < MAXLINE) \
70228072Sbapt         { \
71228072Sbapt	strcpy( nmstr, yytext ); \
72228072Sbapt	 } \
73228072Sbapt	else \
74228072Sbapt	 { \
75228072Sbapt	   synerr(_("Input line too long\n")); \
76228072Sbapt	   FLEX_EXIT(EXIT_FAILURE);  \
77228072Sbapt	 }  \
78228072Sbapt	return NAME;
79228072Sbapt
80228072Sbapt#define PUT_BACK_STRING(str, start) \
81228072Sbapt	for ( i = strlen( str ) - 1; i >= start; --i ) \
82228072Sbapt		unput((str)[i])
83228072Sbapt
84228072Sbapt#define CHECK_REJECT(str) \
85228072Sbapt	if ( all_upper( str ) ) \
86228072Sbapt		reject = true;
87228072Sbapt
88228072Sbapt#define CHECK_YYMORE(str) \
89228072Sbapt	if ( all_lower( str ) ) \
90228072Sbapt		yymore_used = true;
91228072Sbapt
92228072Sbapt#define YY_USER_INIT \
93228072Sbapt	if ( getenv("POSIXLY_CORRECT") ) \
94228072Sbapt		posix_compat = true;
95228072Sbapt
96228072Sbapt%}
97228072Sbapt
98228072Sbapt%option caseless nodefault stack noyy_top_state
99228072Sbapt%option nostdinit
100228072Sbapt
101228072Sbapt%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
102228072Sbapt%x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
103228072Sbapt%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE
104228072Sbapt%x GROUP_WITH_PARAMS
105228072Sbapt%x GROUP_MINUS_PARAMS
106228072Sbapt%x EXTENDED_COMMENT
107228072Sbapt%x COMMENT_DISCARD
108228072Sbapt
109228072SbaptWS		[[:blank:]]+
110228072SbaptOPTWS		[[:blank:]]*
111228072SbaptNOT_WS		[^[:blank:]\r\n]
112228072Sbapt
113228072SbaptNL		\r?\n
114228072Sbapt
115228072SbaptNAME		([[:alpha:]_][[:alnum:]_-]*)
116228072SbaptNOT_NAME	[^[:alpha:]_*\n]+
117228072Sbapt
118228072SbaptSCNAME		{NAME}
119228072Sbapt
120228072SbaptESCSEQ		(\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
121228072Sbapt
122228072SbaptFIRST_CCL_CHAR	([^\\\n]|{ESCSEQ})
123228072SbaptCCL_CHAR	([^\\\n\]]|{ESCSEQ})
124228072SbaptCCL_EXPR	("[:"^?[[:alpha:]]+":]")
125228072Sbapt
126228072SbaptLEXOPT		[aceknopr]
127228072Sbapt
128228072SbaptM4QSTART    "[["
129228072SbaptM4QEND      "]]"
130228072Sbapt
131228072Sbapt%%
132228072Sbapt	static int bracelevel, didadef, indented_code;
133228072Sbapt	static int doing_rule_action = false;
134228072Sbapt	static int option_sense;
135228072Sbapt
136228072Sbapt	int doing_codeblock = false;
137228072Sbapt	int i, brace_depth=0, brace_start_line=0;
138228072Sbapt	Char nmdef[MAXLINE];
139228072Sbapt
140228072Sbapt
141228072Sbapt<INITIAL>{
142228072Sbapt	^{WS}		indented_code = true; BEGIN(CODEBLOCK);
143228072Sbapt	^"/*"		ACTION_ECHO; yy_push_state( COMMENT );
144228072Sbapt	^#{OPTWS}line{WS}	yy_push_state( LINEDIR );
145228072Sbapt	^"%s"{NAME}?	return SCDECL;
146228072Sbapt	^"%x"{NAME}?	return XSCDECL;
147228072Sbapt	^"%{".*{NL}	{
148228072Sbapt			++linenum;
149228072Sbapt			line_directive_out( (FILE *) 0, 1 );
150228072Sbapt			indented_code = false;
151228072Sbapt			BEGIN(CODEBLOCK);
152228072Sbapt			}
153228072Sbapt    ^"%top"[[:blank:]]*"{"[[:blank:]]*{NL}    {
154228072Sbapt                brace_start_line = linenum;
155228072Sbapt                ++linenum;
156228072Sbapt                buf_linedir( &top_buf, infilename?infilename:"<stdin>", linenum);
157228072Sbapt                brace_depth = 1;
158228072Sbapt                yy_push_state(CODEBLOCK_MATCH_BRACE);
159228072Sbapt            }
160228072Sbapt
161228072Sbapt    ^"%top".*   synerr( _("malformed '%top' directive") );
162228072Sbapt
163228072Sbapt	{WS}		/* discard */
164228072Sbapt
165228072Sbapt	^"%%".*		{
166228072Sbapt			sectnum = 2;
167228072Sbapt			bracelevel = 0;
168228072Sbapt			mark_defs1();
169228072Sbapt			line_directive_out( (FILE *) 0, 1 );
170228072Sbapt			BEGIN(SECT2PROLOG);
171228072Sbapt			return SECTEND;
172228072Sbapt			}
173228072Sbapt
174228072Sbapt	^"%pointer".*{NL}	yytext_is_array = false; ++linenum;
175228072Sbapt	^"%array".*{NL}		yytext_is_array = true; ++linenum;
176228072Sbapt
177228072Sbapt	^"%option"	BEGIN(OPTION); return OPTION_OP;
178228072Sbapt
179228072Sbapt	^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL}	++linenum; /* ignore */
180228072Sbapt	^"%"{LEXOPT}{WS}.*{NL}	++linenum;	/* ignore */
181228072Sbapt
182228072Sbapt	/* xgettext: no-c-format */
183228072Sbapt	^"%"[^sxaceknopr{}].*	synerr( _( "unrecognized '%' directive" ) );
184228072Sbapt
185228072Sbapt	^{NAME}		{
186228072Sbapt			if(yyleng < MAXLINE)
187228072Sbapt        		 {
188228072Sbapt			strcpy( nmstr, yytext );
189228072Sbapt			 }
190228072Sbapt			else
191228072Sbapt			 {
192250125Sjkim			   synerr( _("Definition name too long\n"));
193228072Sbapt			   FLEX_EXIT(EXIT_FAILURE);
194228072Sbapt			 }
195228072Sbapt
196228072Sbapt			didadef = false;
197228072Sbapt			BEGIN(PICKUPDEF);
198228072Sbapt			}
199228072Sbapt
200228072Sbapt	{SCNAME}	RETURNNAME;
201228072Sbapt	^{OPTWS}{NL}	++linenum; /* allows blank lines in section 1 */
202228072Sbapt	{OPTWS}{NL}	ACTION_ECHO; ++linenum; /* maybe end of comment line */
203228072Sbapt}
204228072Sbapt
205228072Sbapt
206228072Sbapt<COMMENT>{
207228072Sbapt	"*/"		ACTION_ECHO; yy_pop_state();
208228072Sbapt	"*"		ACTION_ECHO;
209228072Sbapt    {M4QSTART}  ACTION_ECHO_QSTART;
210228072Sbapt    {M4QEND}    ACTION_ECHO_QEND;
211228072Sbapt	[^*\n]      ACTION_ECHO;
212228072Sbapt	{NL}	    ++linenum; ACTION_ECHO;
213228072Sbapt}
214228072Sbapt
215228072Sbapt<COMMENT_DISCARD>{
216228072Sbapt        /* This is the same as COMMENT, but is discarded rather than output. */
217228072Sbapt	"*/"		yy_pop_state();
218228072Sbapt    "*"         ;
219228072Sbapt	[^*\n]      ;
220228072Sbapt	{NL}	    ++linenum;
221228072Sbapt}
222228072Sbapt
223228072Sbapt<EXTENDED_COMMENT>{
224228072Sbapt    ")"         yy_pop_state();
225228072Sbapt    [^\n\)]+      ;
226228072Sbapt    {NL}        ++linenum;
227228072Sbapt}
228228072Sbapt
229228072Sbapt<LINEDIR>{
230228072Sbapt	\n		yy_pop_state();
231228072Sbapt	[[:digit:]]+	linenum = myctoi( yytext );
232228072Sbapt
233228072Sbapt	\"[^"\n]*\"	{
234228072Sbapt			flex_free( (void *) infilename );
235228072Sbapt			infilename = copy_string( yytext + 1 );
236228072Sbapt			infilename[strlen( infilename ) - 1] = '\0';
237228072Sbapt			}
238228072Sbapt	.		/* ignore spurious characters */
239228072Sbapt}
240228072Sbapt
241228072Sbapt<CODEBLOCK>{
242228072Sbapt	^"%}".*{NL}	++linenum; BEGIN(INITIAL);
243228072Sbapt
244228072Sbapt    {M4QSTART}  ACTION_ECHO_QSTART;
245228072Sbapt    {M4QEND}    ACTION_ECHO_QEND;
246228072Sbapt	.	        ACTION_ECHO;
247228072Sbapt
248228072Sbapt	{NL}		{
249228072Sbapt			++linenum;
250228072Sbapt			ACTION_ECHO;
251228072Sbapt			if ( indented_code )
252228072Sbapt				BEGIN(INITIAL);
253228072Sbapt			}
254228072Sbapt}
255228072Sbapt
256228072Sbapt<CODEBLOCK_MATCH_BRACE>{
257228072Sbapt    "}"     {
258228072Sbapt                if( --brace_depth == 0){
259228072Sbapt                    /* TODO: Matched. */
260228072Sbapt                    yy_pop_state();
261228072Sbapt                }else
262228072Sbapt                    buf_strnappend(&top_buf, yytext, yyleng);
263228072Sbapt            }
264228072Sbapt
265228072Sbapt    "{"     {
266228072Sbapt                brace_depth++;
267228072Sbapt                buf_strnappend(&top_buf, yytext, yyleng);
268228072Sbapt            }
269228072Sbapt
270228072Sbapt    {NL}    {
271228072Sbapt                ++linenum;
272228072Sbapt                buf_strnappend(&top_buf, yytext, yyleng);
273228072Sbapt            }
274228072Sbapt
275228072Sbapt    {M4QSTART}  buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart));
276228072Sbapt    {M4QEND}    buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend));
277228072Sbapt
278228072Sbapt    [^{}\r\n]  {
279228072Sbapt                buf_strnappend(&top_buf, yytext, yyleng);
280228072Sbapt               }
281228072Sbapt
282228072Sbapt    <<EOF>>     {
283228072Sbapt                linenum = brace_start_line;
284228072Sbapt                synerr(_("Unmatched '{'"));
285228072Sbapt                yyterminate();
286228072Sbapt                }
287228072Sbapt}
288228072Sbapt
289228072Sbapt
290228072Sbapt<PICKUPDEF>{
291228072Sbapt	{WS}		/* separates name and definition */
292228072Sbapt
293228072Sbapt	{NOT_WS}[^\r\n]*	{
294228072Sbapt 		        if(yyleng < MAXLINE)
295228072Sbapt 		         {
296228072Sbapt			strcpy( (char *) nmdef, yytext );
297228072Sbapt 		         }
298228072Sbapt 		        else
299228072Sbapt 		         {
300250125Sjkim 		           format_synerr( _("Definition value for {%s} too long\n"), nmstr);
301228072Sbapt 		           FLEX_EXIT(EXIT_FAILURE);
302228072Sbapt			 }
303228072Sbapt			/* Skip trailing whitespace. */
304228072Sbapt			for ( i = strlen( (char *) nmdef ) - 1;
305228072Sbapt			      i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
306228072Sbapt			      --i )
307228072Sbapt				;
308228072Sbapt
309228072Sbapt			nmdef[i + 1] = '\0';
310228072Sbapt
311228072Sbapt			ndinstal( nmstr, nmdef );
312228072Sbapt			didadef = true;
313228072Sbapt			}
314228072Sbapt
315228072Sbapt	{NL}		{
316228072Sbapt			if ( ! didadef )
317228072Sbapt				synerr( _( "incomplete name definition" ) );
318228072Sbapt			BEGIN(INITIAL);
319228072Sbapt			++linenum;
320228072Sbapt			}
321228072Sbapt}
322228072Sbapt
323228072Sbapt
324228072Sbapt<OPTION>{
325228072Sbapt	{NL}		++linenum; BEGIN(INITIAL);
326228072Sbapt	{WS}		option_sense = true;
327228072Sbapt
328228072Sbapt	"="		return '=';
329228072Sbapt
330228072Sbapt	no		option_sense = ! option_sense;
331228072Sbapt
332228072Sbapt	7bit		csize = option_sense ? 128 : 256;
333228072Sbapt	8bit		csize = option_sense ? 256 : 128;
334228072Sbapt
335228072Sbapt	align		long_align = option_sense;
336228072Sbapt	always-interactive	{
337228072Sbapt			ACTION_M4_IFDEF( "M4""_YY_ALWAYS_INTERACTIVE", option_sense );
338228072Sbapt            interactive = option_sense;
339228072Sbapt			}
340228072Sbapt	array		yytext_is_array = option_sense;
341228072Sbapt    ansi-definitions ansi_func_defs = option_sense;
342228072Sbapt    ansi-prototypes  ansi_func_protos = option_sense;
343228072Sbapt	backup		backing_up_report = option_sense;
344228072Sbapt	batch		interactive = ! option_sense;
345228072Sbapt    bison-bridge     bison_bridge_lval = option_sense;
346228072Sbapt    bison-locations  { if((bison_bridge_lloc = option_sense))
347228072Sbapt                            bison_bridge_lval = true;
348228072Sbapt                     }
349228072Sbapt	"c++"		C_plus_plus = option_sense;
350228072Sbapt	caseful|case-sensitive		sf_set_case_ins(!option_sense);
351228072Sbapt	caseless|case-insensitive	sf_set_case_ins(option_sense);
352228072Sbapt	debug		ddebug = option_sense;
353228072Sbapt	default		spprdflt = ! option_sense;
354228072Sbapt	ecs		useecs = option_sense;
355228072Sbapt	fast		{
356228072Sbapt			useecs = usemecs = false;
357228072Sbapt			use_read = fullspd = true;
358228072Sbapt			}
359228072Sbapt	full		{
360228072Sbapt			useecs = usemecs = false;
361228072Sbapt			use_read = fulltbl = true;
362228072Sbapt			}
363228072Sbapt	input		ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
364228072Sbapt	interactive	interactive = option_sense;
365228072Sbapt	lex-compat	lex_compat = option_sense;
366228072Sbapt	posix-compat	posix_compat = option_sense;
367228072Sbapt	main		{
368228072Sbapt			ACTION_M4_IFDEF( "M4""_YY_MAIN", option_sense);
369228072Sbapt            /* Override yywrap */
370228072Sbapt            if( option_sense == true )
371228072Sbapt                do_yywrap = false;
372228072Sbapt			}
373228072Sbapt	meta-ecs	usemecs = option_sense;
374228072Sbapt	never-interactive	{
375228072Sbapt			ACTION_M4_IFDEF( "M4""_YY_NEVER_INTERACTIVE", option_sense );
376228072Sbapt            interactive = !option_sense;
377228072Sbapt			}
378228072Sbapt	perf-report	performance_report += option_sense ? 1 : -1;
379228072Sbapt	pointer		yytext_is_array = ! option_sense;
380228072Sbapt	read		use_read = option_sense;
381228072Sbapt    reentrant   reentrant = option_sense;
382228072Sbapt	reject		reject_really_used = option_sense;
383228072Sbapt	stack		ACTION_M4_IFDEF( "M4""_YY_STACK_USED", option_sense );
384228072Sbapt	stdinit		do_stdinit = option_sense;
385228072Sbapt	stdout		use_stdout = option_sense;
386228072Sbapt    unistd      ACTION_IFDEF("YY_NO_UNISTD_H", ! option_sense);
387228072Sbapt	unput		ACTION_M4_IFDEF("M4""_YY_NO_UNPUT", ! option_sense);
388228072Sbapt	verbose		printstats = option_sense;
389228072Sbapt	warn		nowarn = ! option_sense;
390228072Sbapt	yylineno	do_yylineno = option_sense; ACTION_M4_IFDEF("M4""_YY_USE_LINENO", option_sense);
391228072Sbapt	yymore		yymore_really_used = option_sense;
392228072Sbapt	yywrap      do_yywrap = option_sense;
393228072Sbapt
394228072Sbapt	yy_push_state	ACTION_M4_IFDEF("M4""_YY_NO_PUSH_STATE", ! option_sense);
395228072Sbapt	yy_pop_state	ACTION_M4_IFDEF("M4""_YY_NO_POP_STATE", ! option_sense);
396228072Sbapt	yy_top_state	ACTION_M4_IFDEF("M4""_YY_NO_TOP_STATE", ! option_sense);
397228072Sbapt
398228072Sbapt	yy_scan_buffer	ACTION_M4_IFDEF("M4""_YY_NO_SCAN_BUFFER", ! option_sense);
399228072Sbapt	yy_scan_bytes	ACTION_M4_IFDEF("M4""_YY_NO_SCAN_BYTES", ! option_sense);
400228072Sbapt	yy_scan_string	ACTION_M4_IFDEF("M4""_YY_NO_SCAN_STRING", ! option_sense);
401228072Sbapt
402228072Sbapt    yyalloc         ACTION_M4_IFDEF("M4""_YY_NO_FLEX_ALLOC", ! option_sense);
403228072Sbapt    yyrealloc       ACTION_M4_IFDEF("M4""_YY_NO_FLEX_REALLOC", ! option_sense);
404228072Sbapt    yyfree          ACTION_M4_IFDEF("M4""_YY_NO_FLEX_FREE", ! option_sense);
405228072Sbapt
406228072Sbapt    yyget_debug     ACTION_M4_IFDEF("M4""_YY_NO_GET_DEBUG", ! option_sense);
407228072Sbapt    yyset_debug     ACTION_M4_IFDEF("M4""_YY_NO_SET_DEBUG", ! option_sense);
408228072Sbapt    yyget_extra     ACTION_M4_IFDEF("M4""_YY_NO_GET_EXTRA", ! option_sense);
409228072Sbapt    yyset_extra     ACTION_M4_IFDEF("M4""_YY_NO_SET_EXTRA", ! option_sense);
410228072Sbapt    yyget_leng      ACTION_M4_IFDEF("M4""_YY_NO_GET_LENG", ! option_sense);
411228072Sbapt    yyget_text      ACTION_M4_IFDEF("M4""_YY_NO_GET_TEXT", ! option_sense);
412228072Sbapt    yyget_lineno    ACTION_M4_IFDEF("M4""_YY_NO_GET_LINENO", ! option_sense);
413228072Sbapt    yyset_lineno    ACTION_M4_IFDEF("M4""_YY_NO_SET_LINENO", ! option_sense);
414228072Sbapt    yyget_in        ACTION_M4_IFDEF("M4""_YY_NO_GET_IN", ! option_sense);
415228072Sbapt    yyset_in        ACTION_M4_IFDEF("M4""_YY_NO_SET_IN", ! option_sense);
416228072Sbapt    yyget_out       ACTION_M4_IFDEF("M4""_YY_NO_GET_OUT", ! option_sense);
417228072Sbapt    yyset_out       ACTION_M4_IFDEF("M4""_YY_NO_SET_OUT", ! option_sense);
418228072Sbapt    yyget_lval      ACTION_M4_IFDEF("M4""_YY_NO_GET_LVAL", ! option_sense);
419228072Sbapt    yyset_lval      ACTION_M4_IFDEF("M4""_YY_NO_SET_LVAL", ! option_sense);
420228072Sbapt    yyget_lloc      ACTION_M4_IFDEF("M4""_YY_NO_GET_LLOC", ! option_sense);
421228072Sbapt    yyset_lloc      ACTION_M4_IFDEF("M4""_YY_NO_SET_LLOC", ! option_sense);
422228072Sbapt
423228072Sbapt	extra-type	return OPT_EXTRA_TYPE;
424228072Sbapt	outfile		return OPT_OUTFILE;
425228072Sbapt	prefix		return OPT_PREFIX;
426228072Sbapt	yyclass		return OPT_YYCLASS;
427228072Sbapt	header(-file)?      return OPT_HEADER;
428228072Sbapt	tables-file         return OPT_TABLES;
429228072Sbapt	tables-verify   {
430228072Sbapt                    tablesverify = option_sense;
431228072Sbapt                    if(!tablesext && option_sense)
432228072Sbapt                        tablesext = true;
433228072Sbapt                    }
434228072Sbapt
435228072Sbapt
436228072Sbapt	\"[^"\n]*\"	{
437228072Sbapt			if(yyleng-1 < MAXLINE)
438228072Sbapt        		 {
439228072Sbapt			strcpy( nmstr, yytext + 1 );
440228072Sbapt			 }
441228072Sbapt			else
442228072Sbapt			 {
443250125Sjkim			   synerr( _("Option line too long\n"));
444228072Sbapt			   FLEX_EXIT(EXIT_FAILURE);
445228072Sbapt			 }
446228072Sbapt			nmstr[strlen( nmstr ) - 1] = '\0';
447228072Sbapt			return NAME;
448228072Sbapt			}
449228072Sbapt
450228072Sbapt	(([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|.	{
451228072Sbapt			format_synerr( _( "unrecognized %%option: %s" ),
452228072Sbapt				yytext );
453228072Sbapt			BEGIN(RECOVER);
454228072Sbapt			}
455228072Sbapt}
456228072Sbapt
457228072Sbapt<RECOVER>.*{NL}		++linenum; BEGIN(INITIAL);
458228072Sbapt
459228072Sbapt
460228072Sbapt<SECT2PROLOG>{
461228072Sbapt	^"%{".*	++bracelevel; yyless( 2 );	/* eat only %{ */
462228072Sbapt	^"%}".*	--bracelevel; yyless( 2 );	/* eat only %} */
463228072Sbapt
464228072Sbapt	^{WS}.*	ACTION_ECHO;	/* indented code in prolog */
465228072Sbapt
466228072Sbapt	^{NOT_WS}.*	{	/* non-indented code */
467228072Sbapt			if ( bracelevel <= 0 )
468228072Sbapt				{ /* not in %{ ... %} */
469228072Sbapt				yyless( 0 );	/* put it all back */
470228072Sbapt				yy_set_bol( 1 );
471228072Sbapt				mark_prolog();
472228072Sbapt				BEGIN(SECT2);
473228072Sbapt				}
474228072Sbapt			else
475228072Sbapt				ACTION_ECHO;
476228072Sbapt			}
477228072Sbapt
478228072Sbapt	.		ACTION_ECHO;
479228072Sbapt	{NL}	++linenum; ACTION_ECHO;
480228072Sbapt
481228072Sbapt	<<EOF>>		{
482228072Sbapt			mark_prolog();
483228072Sbapt			sectnum = 0;
484228072Sbapt			yyterminate(); /* to stop the parser */
485228072Sbapt			}
486228072Sbapt}
487228072Sbapt
488228072Sbapt<SECT2>{
489228072Sbapt	^{OPTWS}{NL}	++linenum; /* allow blank lines in section 2 */
490228072Sbapt
491228072Sbapt	^{OPTWS}"%{"	{
492228072Sbapt			indented_code = false;
493228072Sbapt			doing_codeblock = true;
494228072Sbapt			bracelevel = 1;
495228072Sbapt			BEGIN(PERCENT_BRACE_ACTION);
496228072Sbapt			}
497228072Sbapt
498228072Sbapt	^{OPTWS}"<"	    {
499228072Sbapt                        /* Allow "<" to appear in (?x) patterns. */
500228072Sbapt                        if (!sf_skip_ws())
501228072Sbapt                            BEGIN(SC);
502228072Sbapt                        return '<';
503228072Sbapt                    }
504228072Sbapt	^{OPTWS}"^"	return '^';
505228072Sbapt	\"		BEGIN(QUOTE); return '"';
506228072Sbapt	"{"/[[:digit:]]	{
507228072Sbapt			BEGIN(NUM);
508228072Sbapt			if ( lex_compat || posix_compat )
509228072Sbapt				return BEGIN_REPEAT_POSIX;
510228072Sbapt			else
511228072Sbapt				return BEGIN_REPEAT_FLEX;
512228072Sbapt			}
513228072Sbapt	"$"/([[:blank:]]|{NL})	return '$';
514228072Sbapt
515228072Sbapt	{WS}"%{"		{
516228072Sbapt			bracelevel = 1;
517228072Sbapt			BEGIN(PERCENT_BRACE_ACTION);
518228072Sbapt
519228072Sbapt			if ( in_rule )
520228072Sbapt				{
521228072Sbapt				doing_rule_action = true;
522228072Sbapt				in_rule = false;
523228072Sbapt				return '\n';
524228072Sbapt				}
525228072Sbapt			}
526228072Sbapt	{WS}"|".*{NL}	{
527228072Sbapt                        if (sf_skip_ws()){
528228072Sbapt                            /* We're in the middle of a (?x: ) pattern. */
529228072Sbapt                            /* Push back everything starting at the "|" */
530228072Sbapt                            size_t amt;
531228072Sbapt                            amt = strchr (yytext, '|') - yytext;
532228072Sbapt                            yyless(amt);
533228072Sbapt                        }
534228072Sbapt                        else {
535228072Sbapt                            continued_action = true;
536228072Sbapt                            ++linenum;
537228072Sbapt                            return '\n';
538228072Sbapt                        }
539228072Sbapt                    }
540228072Sbapt
541228072Sbapt	^{WS}"/*"	{
542228072Sbapt
543228072Sbapt                if (sf_skip_ws()){
544228072Sbapt                    /* We're in the middle of a (?x: ) pattern. */
545228072Sbapt                    yy_push_state(COMMENT_DISCARD);
546228072Sbapt                }
547228072Sbapt                else{
548228072Sbapt                    yyless( yyleng - 2 );	/* put back '/', '*' */
549228072Sbapt                    bracelevel = 0;
550228072Sbapt                    continued_action = false;
551228072Sbapt                    BEGIN(ACTION);
552228072Sbapt                }
553228072Sbapt			}
554228072Sbapt
555228072Sbapt	^{WS}		/* allow indented rules */ ;
556228072Sbapt
557228072Sbapt	{WS}		{
558228072Sbapt            if (sf_skip_ws()){
559228072Sbapt                /* We're in the middle of a (?x: ) pattern. */
560228072Sbapt            }
561228072Sbapt            else{
562228072Sbapt                /* This rule is separate from the one below because
563228072Sbapt                 * otherwise we get variable trailing context, so
564228072Sbapt                 * we can't build the scanner using -{f,F}.
565228072Sbapt                 */
566228072Sbapt                bracelevel = 0;
567228072Sbapt                continued_action = false;
568228072Sbapt                BEGIN(ACTION);
569228072Sbapt
570228072Sbapt                if ( in_rule )
571228072Sbapt                    {
572228072Sbapt                    doing_rule_action = true;
573228072Sbapt                    in_rule = false;
574228072Sbapt                    return '\n';
575228072Sbapt                    }
576228072Sbapt            }
577228072Sbapt			}
578228072Sbapt
579228072Sbapt	{OPTWS}{NL}	{
580228072Sbapt            if (sf_skip_ws()){
581228072Sbapt                /* We're in the middle of a (?x: ) pattern. */
582228072Sbapt                ++linenum;
583228072Sbapt            }
584228072Sbapt            else{
585228072Sbapt                bracelevel = 0;
586228072Sbapt                continued_action = false;
587228072Sbapt                BEGIN(ACTION);
588228072Sbapt                unput( '\n' );	/* so <ACTION> sees it */
589228072Sbapt
590228072Sbapt                if ( in_rule )
591228072Sbapt                    {
592228072Sbapt                    doing_rule_action = true;
593228072Sbapt                    in_rule = false;
594228072Sbapt                    return '\n';
595228072Sbapt                    }
596228072Sbapt            }
597228072Sbapt			}
598228072Sbapt
599228072Sbapt	^{OPTWS}"<<EOF>>"	|
600228072Sbapt	"<<EOF>>"	return EOF_OP;
601228072Sbapt
602228072Sbapt	^"%%".*		{
603228072Sbapt			sectnum = 3;
604228072Sbapt			BEGIN(SECT3);
605228072Sbapt			outn("/* Begin user sect3 */");
606228072Sbapt			yyterminate(); /* to stop the parser */
607228072Sbapt			}
608228072Sbapt
609228072Sbapt	"["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})*	{
610228072Sbapt			int cclval;
611228072Sbapt
612228072Sbapt			if(yyleng < MAXLINE)
613228072Sbapt        		 {
614228072Sbapt			strcpy( nmstr, yytext );
615228072Sbapt			 }
616228072Sbapt			else
617228072Sbapt			 {
618228072Sbapt			   synerr( _("Input line too long\n"));
619228072Sbapt			   FLEX_EXIT(EXIT_FAILURE);
620228072Sbapt			 }
621228072Sbapt
622228072Sbapt			/* Check to see if we've already encountered this
623228072Sbapt			 * ccl.
624228072Sbapt			 */
625228072Sbapt			if (0 /* <--- This "0" effectively disables the reuse of a
626228072Sbapt                   * character class (purely based on its source text).
627228072Sbapt                   * The reason it was disabled is so yacc/bison can parse
628228072Sbapt                   * ccl operations, such as ccl difference and union.
629228072Sbapt                   */
630228072Sbapt                &&  (cclval = ccllookup( (Char *) nmstr )) != 0 )
631228072Sbapt				{
632228072Sbapt				if ( input() != ']' )
633228072Sbapt					synerr( _( "bad character class" ) );
634228072Sbapt
635228072Sbapt				yylval = cclval;
636228072Sbapt				++cclreuse;
637228072Sbapt				return PREVCCL;
638228072Sbapt				}
639228072Sbapt			else
640228072Sbapt				{
641228072Sbapt				/* We fudge a bit.  We know that this ccl will
642228072Sbapt				 * soon be numbered as lastccl + 1 by cclinit.
643228072Sbapt				 */
644228072Sbapt				cclinstal( (Char *) nmstr, lastccl + 1 );
645228072Sbapt
646228072Sbapt				/* Push back everything but the leading bracket
647228072Sbapt				 * so the ccl can be rescanned.
648228072Sbapt				 */
649228072Sbapt				yyless( 1 );
650228072Sbapt
651228072Sbapt				BEGIN(FIRSTCCL);
652228072Sbapt				return '[';
653228072Sbapt				}
654228072Sbapt			}
655228072Sbapt    "{-}"       return CCL_OP_DIFF;
656228072Sbapt    "{+}"       return CCL_OP_UNION;
657228072Sbapt
658228072Sbapt
659228072Sbapt    /* Check for :space: at the end of the rule so we don't
660228072Sbapt     * wrap the expanded regex in '(' ')' -- breaking trailing
661228072Sbapt     * context.
662228072Sbapt     */
663228072Sbapt	"{"{NAME}"}"[[:space:]]?	 {
664250874Sjkim			Char *nmdefptr;
665228072Sbapt            int end_is_ws, end_ch;
666228072Sbapt
667228072Sbapt            end_ch = yytext[yyleng-1];
668228072Sbapt            end_is_ws = end_ch != '}' ? 1 : 0;
669228072Sbapt
670228072Sbapt 			if(yyleng-1 < MAXLINE)
671228072Sbapt         		 {
672228072Sbapt			strcpy( nmstr, yytext + 1 );
673228072Sbapt 			 }
674228072Sbapt 			else
675228072Sbapt 			 {
676228072Sbapt 			   synerr( _("Input line too long\n"));
677228072Sbapt 			   FLEX_EXIT(EXIT_FAILURE);
678228072Sbapt 			 }
679228072Sbaptnmstr[yyleng - 2 - end_is_ws] = '\0';  /* chop trailing brace */
680228072Sbapt
681228072Sbapt			if ( (nmdefptr = ndlookup( nmstr )) == 0 )
682228072Sbapt				format_synerr(
683228072Sbapt					_( "undefined definition {%s}" ),
684228072Sbapt						nmstr );
685228072Sbapt
686228072Sbapt			else
687228072Sbapt				{ /* push back name surrounded by ()'s */
688228072Sbapt				int len = strlen( (char *) nmdefptr );
689228072Sbapt                if (end_is_ws)
690228072Sbapt                    unput(end_ch);
691228072Sbapt
692228072Sbapt				if ( lex_compat || nmdefptr[0] == '^' ||
693228072Sbapt				     (len > 0 && nmdefptr[len - 1] == '$')
694228072Sbapt                     || (end_is_ws && trlcontxt && !sf_skip_ws()))
695228072Sbapt					{ /* don't use ()'s after all */
696228072Sbapt					PUT_BACK_STRING((char *) nmdefptr, 0);
697228072Sbapt
698228072Sbapt					if ( nmdefptr[0] == '^' )
699228072Sbapt						BEGIN(CARETISBOL);
700228072Sbapt					}
701228072Sbapt
702228072Sbapt				else
703228072Sbapt					{
704228072Sbapt					unput(')');
705228072Sbapt					PUT_BACK_STRING((char *) nmdefptr, 0);
706228072Sbapt					unput('(');
707228072Sbapt					}
708228072Sbapt				}
709228072Sbapt			}
710228072Sbapt
711228072Sbapt    "/*"        {
712228072Sbapt                    if (sf_skip_ws())
713228072Sbapt                        yy_push_state(COMMENT_DISCARD);
714228072Sbapt                    else{
715228072Sbapt                        /* Push back the "*" and return "/" as usual. */
716228072Sbapt                        yyless(1);
717228072Sbapt                        return '/';
718228072Sbapt                    }
719228072Sbapt                }
720228072Sbapt
721228072Sbapt    "(?#"       {
722228072Sbapt                    if (lex_compat || posix_compat){
723228072Sbapt                        /* Push back the "?#" and treat it like a normal parens. */
724228072Sbapt                        yyless(1);
725228072Sbapt                        sf_push();
726228072Sbapt                        return '(';
727228072Sbapt                    }
728228072Sbapt                    else
729228072Sbapt                        yy_push_state(EXTENDED_COMMENT);
730228072Sbapt                }
731228072Sbapt    "(?"        {
732228072Sbapt                    sf_push();
733228072Sbapt                    if (lex_compat || posix_compat)
734228072Sbapt                        /* Push back the "?" and treat it like a normal parens. */
735228072Sbapt                        yyless(1);
736228072Sbapt                    else
737228072Sbapt                        BEGIN(GROUP_WITH_PARAMS);
738228072Sbapt                    return '(';
739228072Sbapt                }
740228072Sbapt    "("         sf_push(); return '(';
741228072Sbapt    ")"         sf_pop(); return ')';
742228072Sbapt
743228072Sbapt	[/|*+?.(){}]	return (unsigned char) yytext[0];
744228072Sbapt	.		RETURNCHAR;
745228072Sbapt}
746228072Sbapt
747228072Sbapt
748228072Sbapt<SC>{
749228072Sbapt	{OPTWS}{NL}{OPTWS}	++linenum;	/* Allow blank lines & continuations */
750228072Sbapt	[,*]		return (unsigned char) yytext[0];
751228072Sbapt	">"		BEGIN(SECT2); return '>';
752228072Sbapt	">"/^		BEGIN(CARETISBOL); return '>';
753228072Sbapt	{SCNAME}	RETURNNAME;
754228072Sbapt	.		{
755228072Sbapt			format_synerr( _( "bad <start condition>: %s" ),
756228072Sbapt				yytext );
757228072Sbapt			}
758228072Sbapt}
759228072Sbapt
760228072Sbapt<CARETISBOL>"^"		BEGIN(SECT2); return '^';
761228072Sbapt
762228072Sbapt
763228072Sbapt<QUOTE>{
764228072Sbapt	[^"\n]		RETURNCHAR;
765228072Sbapt	\"		BEGIN(SECT2); return '"';
766228072Sbapt
767228072Sbapt	{NL}		{
768228072Sbapt			synerr( _( "missing quote" ) );
769228072Sbapt			BEGIN(SECT2);
770228072Sbapt			++linenum;
771228072Sbapt			return '"';
772228072Sbapt			}
773228072Sbapt}
774228072Sbapt
775228072Sbapt<GROUP_WITH_PARAMS>{
776228072Sbapt    ":"     BEGIN(SECT2);
777228072Sbapt    "-"     BEGIN(GROUP_MINUS_PARAMS);
778228072Sbapt    i       sf_set_case_ins(1);
779228072Sbapt    s       sf_set_dot_all(1);
780228072Sbapt    x       sf_set_skip_ws(1);
781228072Sbapt}
782228072Sbapt<GROUP_MINUS_PARAMS>{
783228072Sbapt    ":"     BEGIN(SECT2);
784228072Sbapt    i       sf_set_case_ins(0);
785228072Sbapt    s       sf_set_dot_all(0);
786228072Sbapt    x       sf_set_skip_ws(0);
787228072Sbapt}
788228072Sbapt
789228072Sbapt<FIRSTCCL>{
790228072Sbapt	"^"/[^-\]\n]	BEGIN(CCL); return '^';
791228072Sbapt	"^"/("-"|"]")	return '^';
792228072Sbapt	.		BEGIN(CCL); RETURNCHAR;
793228072Sbapt}
794228072Sbapt
795228072Sbapt<CCL>{
796228072Sbapt	-/[^\]\n]	return '-';
797228072Sbapt	[^\]\n]		RETURNCHAR;
798228072Sbapt	"]"		BEGIN(SECT2); return ']';
799228072Sbapt	.|{NL}		{
800228072Sbapt			synerr( _( "bad character class" ) );
801228072Sbapt			BEGIN(SECT2);
802228072Sbapt			return ']';
803228072Sbapt			}
804228072Sbapt}
805228072Sbapt
806228072Sbapt<FIRSTCCL,CCL>{
807228072Sbapt	"[:alnum:]"	BEGIN(CCL); return CCE_ALNUM;
808228072Sbapt	"[:alpha:]"	BEGIN(CCL); return CCE_ALPHA;
809228072Sbapt	"[:blank:]"	BEGIN(CCL); return CCE_BLANK;
810228072Sbapt	"[:cntrl:]"	BEGIN(CCL); return CCE_CNTRL;
811228072Sbapt	"[:digit:]"	BEGIN(CCL); return CCE_DIGIT;
812228072Sbapt	"[:graph:]"	BEGIN(CCL); return CCE_GRAPH;
813228072Sbapt	"[:lower:]"	BEGIN(CCL); return CCE_LOWER;
814228072Sbapt	"[:print:]"	BEGIN(CCL); return CCE_PRINT;
815228072Sbapt	"[:punct:]"	BEGIN(CCL); return CCE_PUNCT;
816228072Sbapt	"[:space:]"	BEGIN(CCL); return CCE_SPACE;
817228072Sbapt	"[:upper:]"	BEGIN(CCL); return CCE_UPPER;
818228072Sbapt	"[:xdigit:]"	BEGIN(CCL); return CCE_XDIGIT;
819228072Sbapt
820228072Sbapt	"[:^alnum:]"	BEGIN(CCL); return CCE_NEG_ALNUM;
821228072Sbapt	"[:^alpha:]"	BEGIN(CCL); return CCE_NEG_ALPHA;
822228072Sbapt	"[:^blank:]"	BEGIN(CCL); return CCE_NEG_BLANK;
823228072Sbapt	"[:^cntrl:]"	BEGIN(CCL); return CCE_NEG_CNTRL;
824228072Sbapt	"[:^digit:]"	BEGIN(CCL); return CCE_NEG_DIGIT;
825228072Sbapt	"[:^graph:]"	BEGIN(CCL); return CCE_NEG_GRAPH;
826228072Sbapt	"[:^lower:]"	BEGIN(CCL); return CCE_NEG_LOWER;
827228072Sbapt	"[:^print:]"	BEGIN(CCL); return CCE_NEG_PRINT;
828228072Sbapt	"[:^punct:]"	BEGIN(CCL); return CCE_NEG_PUNCT;
829228072Sbapt	"[:^space:]"	BEGIN(CCL); return CCE_NEG_SPACE;
830228072Sbapt	"[:^upper:]"	BEGIN(CCL); return CCE_NEG_UPPER;
831228072Sbapt	"[:^xdigit:]"	BEGIN(CCL); return CCE_NEG_XDIGIT;
832228072Sbapt	{CCL_EXPR}	{
833228072Sbapt			format_synerr(
834228072Sbapt				_( "bad character class expression: %s" ),
835228072Sbapt					yytext );
836228072Sbapt			BEGIN(CCL); return CCE_ALNUM;
837228072Sbapt			}
838228072Sbapt}
839228072Sbapt
840228072Sbapt<NUM>{
841228072Sbapt	[[:digit:]]+	{
842228072Sbapt			yylval = myctoi( yytext );
843228072Sbapt			return NUMBER;
844228072Sbapt			}
845228072Sbapt
846228072Sbapt	","		return ',';
847228072Sbapt	"}"		{
848228072Sbapt			BEGIN(SECT2);
849228072Sbapt			if ( lex_compat || posix_compat )
850228072Sbapt				return END_REPEAT_POSIX;
851228072Sbapt			else
852228072Sbapt				return END_REPEAT_FLEX;
853228072Sbapt			}
854228072Sbapt
855228072Sbapt	.		{
856228072Sbapt			synerr( _( "bad character inside {}'s" ) );
857228072Sbapt			BEGIN(SECT2);
858228072Sbapt			return '}';
859228072Sbapt			}
860228072Sbapt
861228072Sbapt	{NL}		{
862228072Sbapt			synerr( _( "missing }" ) );
863228072Sbapt			BEGIN(SECT2);
864228072Sbapt			++linenum;
865228072Sbapt			return '}';
866228072Sbapt			}
867228072Sbapt}
868228072Sbapt
869228072Sbapt
870228072Sbapt<PERCENT_BRACE_ACTION>{
871228072Sbapt	{OPTWS}"%}".*		bracelevel = 0;
872228072Sbapt
873228072Sbapt	<ACTION>"/*"		ACTION_ECHO; yy_push_state( COMMENT );
874228072Sbapt
875228072Sbapt	<CODEBLOCK,ACTION>{
876228072Sbapt		"reject"	{
877228072Sbapt			ACTION_ECHO;
878228072Sbapt			CHECK_REJECT(yytext);
879228072Sbapt			}
880228072Sbapt		"yymore"	{
881228072Sbapt			ACTION_ECHO;
882228072Sbapt			CHECK_YYMORE(yytext);
883228072Sbapt			}
884228072Sbapt	}
885228072Sbapt
886250125Sjkim    {M4QSTART}  ACTION_ECHO_QSTART;
887228072Sbapt    {M4QEND}    ACTION_ECHO_QEND;
888228072Sbapt    .           ACTION_ECHO;
889228072Sbapt	{NL}		{
890228072Sbapt			++linenum;
891228072Sbapt			ACTION_ECHO;
892228072Sbapt			if ( bracelevel == 0 ||
893228072Sbapt			     (doing_codeblock && indented_code) )
894228072Sbapt				{
895228072Sbapt				if ( doing_rule_action )
896228072Sbapt					add_action( "\tYY_BREAK\n" );
897228072Sbapt
898228072Sbapt				doing_rule_action = doing_codeblock = false;
899228072Sbapt				BEGIN(SECT2);
900228072Sbapt				}
901228072Sbapt			}
902228072Sbapt}
903228072Sbapt
904228072Sbapt
905228072Sbapt	/* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
906228072Sbapt<ACTION>{
907228072Sbapt	"{"		ACTION_ECHO; ++bracelevel;
908228072Sbapt	"}"		ACTION_ECHO; --bracelevel;
909250125Sjkim    {M4QSTART}  ACTION_ECHO_QSTART;
910228072Sbapt    {M4QEND}    ACTION_ECHO_QEND;
911228072Sbapt	[^[:alpha:]_{}"'/\n\[\]]+	ACTION_ECHO;
912228072Sbapt    [\[\]]      ACTION_ECHO;
913228072Sbapt	{NAME}		ACTION_ECHO;
914228072Sbapt	"'"([^'\\\n]|\\.)*"'"	ACTION_ECHO; /* character constant */
915228072Sbapt	\"		ACTION_ECHO; BEGIN(ACTION_STRING);
916228072Sbapt	{NL}		{
917228072Sbapt			++linenum;
918228072Sbapt			ACTION_ECHO;
919228072Sbapt			if ( bracelevel == 0 )
920228072Sbapt				{
921228072Sbapt				if ( doing_rule_action )
922228072Sbapt					add_action( "\tYY_BREAK\n" );
923228072Sbapt
924228072Sbapt				doing_rule_action = false;
925228072Sbapt				BEGIN(SECT2);
926228072Sbapt				}
927228072Sbapt			}
928228072Sbapt	.		ACTION_ECHO;
929228072Sbapt}
930228072Sbapt
931228072Sbapt<ACTION_STRING>{
932228072Sbapt	[^"\\\n]+	ACTION_ECHO;
933228072Sbapt	\\.		ACTION_ECHO;
934228072Sbapt	{NL}		++linenum; ACTION_ECHO; BEGIN(ACTION);
935228072Sbapt	\"		ACTION_ECHO; BEGIN(ACTION);
936228072Sbapt	.		ACTION_ECHO;
937228072Sbapt}
938228072Sbapt
939228072Sbapt<COMMENT,COMMENT_DISCARD,ACTION,ACTION_STRING><<EOF>>	{
940228072Sbapt			synerr( _( "EOF encountered inside an action" ) );
941228072Sbapt			yyterminate();
942228072Sbapt			}
943228072Sbapt
944228072Sbapt<EXTENDED_COMMENT,GROUP_WITH_PARAMS,GROUP_MINUS_PARAMS><<EOF>>	{
945228072Sbapt			synerr( _( "EOF encountered inside pattern" ) );
946228072Sbapt			yyterminate();
947228072Sbapt			}
948228072Sbapt
949228072Sbapt<SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ}	{
950228072Sbapt			yylval = myesc( (Char *) yytext );
951228072Sbapt
952228072Sbapt			if ( YY_START == FIRSTCCL )
953228072Sbapt				BEGIN(CCL);
954228072Sbapt
955228072Sbapt			return CHAR;
956228072Sbapt			}
957228072Sbapt
958228072Sbapt
959228072Sbapt<SECT3>{
960228072Sbapt    {M4QSTART}  fwrite (escaped_qstart, 1, strlen(escaped_qstart), yyout);
961228072Sbapt    {M4QEND}    fwrite (escaped_qend, 1, strlen(escaped_qend), yyout);
962228072Sbapt	[^\[\]\n]*(\n?) ECHO;
963228072Sbapt	(.|\n)      ECHO;
964228072Sbapt	<<EOF>>		sectnum = 0; yyterminate();
965228072Sbapt}
966228072Sbapt
967228072Sbapt<*>.|\n			format_synerr( _( "bad character: %s" ), yytext );
968228072Sbapt
969228072Sbapt%%
970228072Sbapt
971228072Sbapt
972228072Sbaptint yywrap()
973228072Sbapt	{
974228072Sbapt	if ( --num_input_files > 0 )
975228072Sbapt		{
976228072Sbapt		set_input_file( *++input_files );
977228072Sbapt		return 0;
978228072Sbapt		}
979228072Sbapt
980228072Sbapt	else
981228072Sbapt		return 1;
982228072Sbapt	}
983228072Sbapt
984228072Sbapt
985228072Sbapt/* set_input_file - open the given file (if NULL, stdin) for scanning */
986228072Sbapt
987228072Sbaptvoid set_input_file( file )
988228072Sbaptchar *file;
989228072Sbapt	{
990228072Sbapt	if ( file && strcmp( file, "-" ) )
991228072Sbapt		{
992228072Sbapt		infilename = copy_string( file );
993228072Sbapt		yyin = fopen( infilename, "r" );
994228072Sbapt
995228072Sbapt		if ( yyin == NULL )
996228072Sbapt			lerrsf( _( "can't open %s" ), file );
997228072Sbapt		}
998228072Sbapt
999228072Sbapt	else
1000228072Sbapt		{
1001228072Sbapt		yyin = stdin;
1002228072Sbapt		infilename = copy_string( "<stdin>" );
1003228072Sbapt		}
1004228072Sbapt
1005228072Sbapt	linenum = 1;
1006228072Sbapt	}
1007228072Sbapt
1008228072Sbapt
1009228072Sbapt/* Wrapper routines for accessing the scanner's malloc routines. */
1010228072Sbapt
1011228072Sbaptvoid *flex_alloc( size )
1012228072Sbaptsize_t size;
1013228072Sbapt	{
1014228072Sbapt	return (void *) malloc( size );
1015228072Sbapt	}
1016228072Sbapt
1017228072Sbaptvoid *flex_realloc( ptr, size )
1018228072Sbaptvoid *ptr;
1019228072Sbaptsize_t size;
1020228072Sbapt	{
1021228072Sbapt	return (void *) realloc( ptr, size );
1022228072Sbapt	}
1023228072Sbapt
1024228072Sbaptvoid flex_free( ptr )
1025228072Sbaptvoid *ptr;
1026228072Sbapt	{
1027228072Sbapt	if ( ptr )
1028228072Sbapt		free( ptr );
1029228072Sbapt	}
1030