pgc.l 15.3 KB
Newer Older
M
Michael Meskes 已提交
1

M
Marc G. Fournier 已提交
2
/* This is a modified version of src/backend/parser/scan.l */
3
%{
M
Marc G. Fournier 已提交
4
#include <ctype.h>
M
Marc G. Fournier 已提交
5
#include <sys/types.h>
6
#include <limits.h>
7
#include <errno.h>
8

9
#include "postgres.h"
10 11 12 13
#ifndef PATH_MAX
#include <sys/param.h>
#define PATH_MAX MAXPATHLEN
#endif
M
Marc G. Fournier 已提交
14 15 16 17 18
#include "miscadmin.h"
#include "nodes/pg_list.h"
#include "nodes/parsenodes.h"
#include "parser/gramparse.h"
#include "parser/scansup.h"
M
 
Marc G. Fournier 已提交
19
#include "extern.h"
M
 
Marc G. Fournier 已提交
20
#include "preproc.h"
M
Marc G. Fournier 已提交
21
#include "utils/builtins.h"
22

23 24 25 26 27
#ifdef  YY_READ_BUF_SIZE
#undef  YY_READ_BUF_SIZE
#endif
#define YY_READ_BUF_SIZE	MAX_PARSE_BUFFER

M
Marc G. Fournier 已提交
28 29 30 31 32 33 34 35
/* some versions of lex define this as a macro */
#if defined(yywrap)
#undef yywrap
#endif /* yywrap */

extern YYSTYPE yylval;
int llen;
char literal[MAX_PARSE_BUFFER];
36
int before_comment;
M
Marc G. Fournier 已提交
37

38 39 40 41 42 43
struct _yy_buffer { YY_BUFFER_STATE 	buffer;
		    long		lineno;
		    char	      * filename;
		    struct _yy_buffer * next;
		  } *yy_buffer = NULL;

M
 
Marc G. Fournier 已提交
44 45 46
struct _defines *defines = NULL;
static char *old;

47
%}
48
%option yylineno
M
 
Marc G. Fournier 已提交
49
%s C SQL incl def def_ident
M
Marc G. Fournier 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
/* OK, here is a short description of lex/flex rules behavior.
 * The longest pattern which matches an input string is always chosen.
 * For equal-length patterns, the first occurring in the rules list is chosen.
 * INITIAL is the starting condition, to which all non-conditional rules apply.
 * When in an exclusive condition, only those rules defined for that condition apply.
 *
 * Exclusive states change parsing rules while the state is active.
 * There are exclusive states for quoted strings, extended comments,
 *  and to eliminate parsing troubles for numeric strings.
 * Exclusive states:
 *  <xb> binary numeric string - thomas 1997-11-16
 *  <xc> extended C-style comments - tgl 1997-07-12
 *  <xd> delimited identifiers (double-quoted identifiers) - tgl 1997-10-27
 *  <xh> hexadecimal numeric string - thomas 1997-11-16
 *  <xq> quoted strings - tgl 1997-07-30
 *
 * The "extended comment" syntax closely resembles allowable operator syntax.
 * So, when in condition <xc>, only strings which would terminate the
 *  "extended comment" trigger any action other than "ignore".
 * Be sure to match _any_ candidate comment, including those with appended
 *	operator-like symbols. - thomas 1997-07-14
 */

%x xb
%x xc
%x xd
76
%x xdc
M
Marc G. Fournier 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
%x xh
%x xq

/* Binary number
 */
xbstart			[bB]{quote}
xbstop			{quote}
xbinside		[^']*
xbcat			{quote}{space}*\n{space}*{quote}

/* Hexadecimal number
 */
xhstart			[xX]{quote}
xhstop			{quote}
xhinside		[^']*
xhcat			{quote}{space}*\n{space}*{quote}

M
Michael Meskes 已提交
94 95 96 97
/* C version of hex number 
 */
xch			0[xX][0-9A-Fa-f]*

M
Marc G. Fournier 已提交
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/* Extended quote
 * xqdouble implements SQL92 embedded quote
 * xqcat allows strings to cross input lines
 */
quote			'
xqstart			{quote}
xqstop			{quote}
xqdouble		{quote}{quote}
xqinside		[^\\']*
xqliteral		[\\](.|\n)
xqcat			{quote}{space}*\n{space}*{quote}

/* Delimited quote
 * Allows embedded spaces and other special characters into identifiers.
 */
dquote			\"
xdstart			{dquote}
xdstop			{dquote}
xdinside		[^"]*
M
Michael Meskes 已提交
117 118 119 120 121 122

/* special stuff for C strings */
xdcqq			\\\\
xdcqdq			\\\"
xdcother		[^"]
xdcinside		({xdcqq}|{xdcqdq}|{xdcother})
M
Marc G. Fournier 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

/* Comments
 * Ignored by the scanner and parser.
 */
xcline			[\/][\*].*[\*][\/]{space}*\n*
xcstart			[\/][\*]{op_and_self}*
xcstop			{op_and_self}*[\*][\/]({space}*|\n)
xcinside		[^*]*
xcstar			[^/]

digit			[0-9]
letter			[\200-\377_A-Za-z]
letter_or_digit	[\200-\377_A-Za-z0-9]

identifier		{letter}{letter_or_digit}*

typecast		"::"

M
Michael Meskes 已提交
141
self			[,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|]
M
Michael Meskes 已提交
142
op_and_self		[\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\=]
M
Marc G. Fournier 已提交
143 144
operator		{op_and_self}+

M
Michael Meskes 已提交
145 146 147 148 149 150 151
/* we do not allow unary minus in numbers.
 * instead we pass it verbatim to parser. there it gets
 * coerced via doNegate() -- Leon aug 20 1999
 */
integer			{digit}+
decimal			(({digit}*\.{digit}+)|({digit}+\.{digit}*))
real			((({digit}*\.{digit}+)|({digit}+\.{digit}*)|({digit}+))([Ee][-+]?{digit}+))
M
 
Marc G. Fournier 已提交
152
/*
M
Michael Meskes 已提交
153
real			(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
M
Michael Meskes 已提交
154
*/
M
Marc G. Fournier 已提交
155 156 157

param			\${integer}

M
Michael Meskes 已提交
158
comment			("--"|"//").*
M
Michael Meskes 已提交
159
ccomment		"//".*\n
M
Marc G. Fournier 已提交
160

M
Michael Meskes 已提交
161
space			[ \t\n\r\f]
M
Marc G. Fournier 已提交
162 163 164 165
other			.

/* some stuff needed for ecpg */
exec    [eE][xX][eE][cC]
M
 
Marc G. Fournier 已提交
166
define	[dD][eE][fF][iI][nN][eE]
167
include [iI][nN][cC][lL][uU][dD][eE]
M
Marc G. Fournier 已提交
168 169
sql     [sS][qQ][lL]

M
 
Marc G. Fournier 已提交
170 171
cppline		{space}*#.*(\\{space}*\n)*\n*

M
Marc G. Fournier 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184
/* DO NOT PUT ANY COMMENTS IN THE FOLLOWING SECTION.
 * AT&T lex does not properly handle C-style comments in this second lex block.
 * So, put comments here. tgl - 1997-09-08
 *
 * Quoted strings must allow some special characters such as single-quote
 *  and newline.
 * Embedded single-quotes are implemented both in the SQL/92-standard
 *  style of two adjacent single quotes "''" and in the Postgres/Java style
 *  of escaped-quote "\'".
 * Other embedded escaped characters are matched explicitly and the leading
 *  backslash is dropped from the string. - thomas 1997-09-24
 */

185
%%
M
Marc G. Fournier 已提交
186 187
<SQL>{comment}		{ /* ignore */ }

M
Michael Meskes 已提交
188
{xcline}		{ ECHO; }
M
Marc G. Fournier 已提交
189

M
Michael Meskes 已提交
190
<xc>{xcstar}		{ ECHO; }
191 192
{xcstart}		{
				before_comment = YYSTATE;
M
Michael Meskes 已提交
193
				ECHO;
194 195
	 			BEGIN(xc);
			}
M
Marc G. Fournier 已提交
196

M
Michael Meskes 已提交
197
<xc>{xcstop}	{ ECHO; BEGIN(before_comment); }
M
Marc G. Fournier 已提交
198

M
Michael Meskes 已提交
199
<xc>{xcinside}	{ ECHO; }
M
Marc G. Fournier 已提交
200 201 202 203 204 205 206 207 208 209 210 211 212 213

<SQL>{xbstart}		{
					BEGIN(xb);
					llen = 0;
					*literal = '\0';
				}
<xb>{xbstop}	{
					char* endptr;

					BEGIN(SQL);
					errno = 0;
					yylval.ival = strtol((char *)literal,&endptr,2);
					if (*endptr != '\0' || errno == ERANGE)
						yyerror("ERROR: Bad binary integer input!");
214
					return ICONST;
M
Marc G. Fournier 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
				}
<xh>{xhinside}	|
<xb>{xbinside}	{
					if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
						yyerror("ERROR: quoted string parse buffer exceeded");
					memcpy(literal+llen, yytext, yyleng+1);
					llen += yyleng;
				}
<xh>{xhcat}		|
<xb>{xbcat}		{
				}

<SQL>{xhstart}		{
					BEGIN(xh);
					llen = 0;
					*literal = '\0';
				}
<xh>{xhstop}	{
					char* endptr;

					BEGIN(SQL);
					errno = 0;
					yylval.ival = strtol((char *)literal,&endptr,16);
					if (*endptr != '\0' || errno == ERANGE)
						yyerror("ERROR: Bad hexadecimal integer input");
240
					return ICONST;
M
Marc G. Fournier 已提交
241 242 243 244 245 246 247 248 249
				}

<SQL>{xqstart}		{
					BEGIN(xq);
					llen = 0;
					*literal = '\0';
				}
<xq>{xqstop}	{
					BEGIN(SQL);
M
Michael Meskes 已提交
250
					yylval.str = mm_strdup(literal);
251
					return SCONST;
M
Marc G. Fournier 已提交
252 253
				}
<xq>{xqdouble}	|
M
 
Marc G. Fournier 已提交
254
<xq>{xqinside}  |
M
Marc G. Fournier 已提交
255
<xq>{xqliteral} {
M
 
Marc G. Fournier 已提交
256
					if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
M
Marc G. Fournier 已提交
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
						yyerror("ERROR: quoted string parse buffer exceeded");
					memcpy(literal+llen, yytext, yyleng+1);
					llen += yyleng;
				}
<xq>{xqcat}		{
				}


<SQL>{xdstart}		{
					BEGIN(xd);
					llen = 0;
					*literal = '\0';
				}
<xd>{xdstop}	{
					BEGIN(SQL);
M
 
Marc G. Fournier 已提交
272
					yylval.str = mm_strdup(literal);
273
					return CSTRING;
M
Marc G. Fournier 已提交
274 275 276 277 278 279 280
				}
<xd>{xdinside}	{
					if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
						yyerror("ERROR: quoted string parse buffer exceeded");
					memcpy(literal+llen, yytext, yyleng+1);
					llen += yyleng;
				}
M
 
Marc G. Fournier 已提交
281
{xdstart}		{
282 283 284 285 286 287
					BEGIN(xdc);
					llen = 0;
					*literal = '\0';
				}
<xdc>{xdstop}	{
					BEGIN(C);
M
 
Marc G. Fournier 已提交
288
					yylval.str = mm_strdup(literal);
289
					return CSTRING;
290
				}
M
Michael Meskes 已提交
291
<xdc>{xdcinside}	{
292 293 294 295 296
					if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
						yyerror("ERROR: quoted string parse buffer exceeded");
					memcpy(literal+llen, yytext, yyleng+1);
					llen += yyleng;
				}
M
Marc G. Fournier 已提交
297
<SQL>{typecast}			{ 	return TYPECAST; }
M
Michael Meskes 已提交
298 299 300 301 302 303 304 305 306
<SQL>{self}			{ /* 
				   * We may find a ';' inside a structure
				   * definition in a TYPE or VAR statement.
				   * This is not an EOL marker.
				   */
				  if (yytext[0] == ';' && struct_level == 0)
					 BEGIN C;
				  return yytext[0];
				}
M
Marc G. Fournier 已提交
307 308
<SQL>{operator}		{
					if (strcmp((char*)yytext,"!=") == 0)
M
 
Marc G. Fournier 已提交
309
						yylval.str = mm_strdup("<>"); /* compatability */
M
Marc G. Fournier 已提交
310
					else
M
 
Marc G. Fournier 已提交
311
						yylval.str = mm_strdup((char*)yytext);
312
					return Op;
M
Marc G. Fournier 已提交
313 314 315
				}
<SQL>{param}			{
					yylval.ival = atoi((char*)&yytext[1]);
316
					return PARAM;
M
Marc G. Fournier 已提交
317
				}
M
Michael Meskes 已提交
318
<C,SQL>{integer}		{
M
Marc G. Fournier 已提交
319 320 321 322 323 324 325
					char* endptr;

					errno = 0;
					yylval.ival = strtol((char *)yytext,&endptr,10);
					if (*endptr != '\0' || errno == ERANGE)
					{
						errno = 0;
M
Michael Meskes 已提交
326 327
						yylval.str = mm_strdup((char*)yytext);
                                                return SCONST;
M
Marc G. Fournier 已提交
328
					}
329
					return ICONST;
M
Marc G. Fournier 已提交
330
				}
M
Michael Meskes 已提交
331 332 333 334 335 336 337 338 339 340 341 342 343 344
{decimal}   		        {
                                        char* endptr;

                                        if (strlen((char *)yytext) <= 17)
                                        {
                                                errno = 0;
                                                yylval.dval = strtod((char *)yytext,&endptr);
						if (*endptr != '\0' || errno == ERANGE)
							yyerror("ERROR: Bad float8 input");
						return FCONST;
                                        }
                                        yylval.str = mm_strdup((char*)yytext);
                                        return SCONST;
                                }
M
Michael Meskes 已提交
345
<C,SQL>{real}			{
M
Marc G. Fournier 已提交
346 347 348 349 350 351
					char* endptr;

					errno = 0;
					yylval.dval = strtod((char *)yytext,&endptr);
					if (*endptr != '\0' || errno == ERANGE)
						yyerror("ERROR: Bad float input");
352
					return FCONST;
M
Marc G. Fournier 已提交
353
				}
354
<SQL>:{identifier}(("->"|\.){identifier})*	{
M
 
Marc G. Fournier 已提交
355
					yylval.str = mm_strdup((char*)yytext+1);
356 357
					return(CVARIABLE);
			}
M
Marc G. Fournier 已提交
358 359 360
<SQL>{identifier}	{
					int i;
					ScanKeyword		*keyword;
M
 
Marc G. Fournier 已提交
361
					char lower_text[NAMEDATALEN];
M
Marc G. Fournier 已提交
362

M
 
Marc G. Fournier 已提交
363 364 365 366 367
					/* this should leave the last byte set to '\0' */
					strncpy(lower_text, yytext, NAMEDATALEN-1);
					for(i = 0; lower_text[i]; i++)
						if (isascii((unsigned char)lower_text[i]) && isupper(lower_text[i]))
							lower_text[i] = tolower(lower_text[i]);
M
 
Marc G. Fournier 已提交
368

M
 
Marc G. Fournier 已提交
369
					keyword = ScanKeywordLookup((char*)lower_text);
M
Marc G. Fournier 已提交
370
					if (keyword != NULL) {
371
						return keyword->value;
M
Marc G. Fournier 已提交
372 373 374
					}
					else
					{
M
 
Marc G. Fournier 已提交
375
						keyword = ScanECPGKeywordLookup((char*)lower_text);
M
Marc G. Fournier 已提交
376
						if (keyword != NULL) {
377
							return keyword->value;
M
Marc G. Fournier 已提交
378 379 380
						}
						else
						{
M
 
Marc G. Fournier 已提交
381 382 383 384 385 386 387 388 389 390 391 392
							struct _defines *ptr;

							for (ptr = defines; ptr; ptr = ptr->next)
							{
								if (strcmp(yytext, ptr->old) == 0)
								{
									struct _yy_buffer *yb;

									yb = mm_alloc(sizeof(struct _yy_buffer));

						                        yb->buffer =  YY_CURRENT_BUFFER;
						                        yb->lineno = yylineno;
M
 
Marc G. Fournier 已提交
393
						                        yb->filename = mm_strdup(input_filename);
M
 
Marc G. Fournier 已提交
394 395 396 397 398 399 400 401 402 403
						                        yb->next = yy_buffer;

						                        yy_buffer = yb;

 									yy_scan_string(ptr->new);
									break;
								}
							}
							if (ptr == NULL) 
							{
M
 
Marc G. Fournier 已提交
404
								yylval.str = mm_strdup((char*)yytext);
405
								return IDENT;
M
 
Marc G. Fournier 已提交
406
							}
M
Marc G. Fournier 已提交
407 408 409 410
						}
					}
				}
<SQL>{space}			{ /* ignore */ }
411
<SQL>{other}			{ return yytext[0]; }
M
Michael Meskes 已提交
412
<C>{exec}{space}*{sql}		{ BEGIN SQL; return SQL_START; }
413
<C>{ccomment}			{ /* ignore */ } 
M
Michael Meskes 已提交
414 415 416 417 418 419 420 421 422 423 424 425 426
<C>{xch}			{
					char* endptr;

					errno = 0;
					yylval.ival = strtol((char *)yytext,&endptr,16);
					if (*endptr != '\0' || errno == ERANGE)
					{
						errno = 0;
						yylval.str = mm_strdup((char*)yytext);
                                                return SCONST;
					}
					return ICONST;
				}
M
 
Marc G. Fournier 已提交
427
<C>{cppline}			{
M
 
Marc G. Fournier 已提交
428
					yylval.str = mm_strdup((char*)yytext);
M
 
Marc G. Fournier 已提交
429 430
					return(CPP_LINE);
				}
M
Marc G. Fournier 已提交
431 432 433 434 435
<C>{identifier}	{
					ScanKeyword		*keyword;

					keyword = ScanCKeywordLookup((char*)yytext);
					if (keyword != NULL) {
436
						return keyword->value;
M
Marc G. Fournier 已提交
437 438 439
					}
					else
					{
M
 
Marc G. Fournier 已提交
440 441 442 443 444 445 446 447 448 449 450 451
						struct _defines *ptr;

						for (ptr = defines; ptr; ptr = ptr->next)
						{
							if (strcmp(yytext, ptr->old) == 0)
							{
								struct _yy_buffer *yb;

								yb = mm_alloc(sizeof(struct _yy_buffer));

					                        yb->buffer =  YY_CURRENT_BUFFER;
					                        yb->lineno = yylineno;
M
 
Marc G. Fournier 已提交
452
					                        yb->filename = mm_strdup(input_filename);
M
 
Marc G. Fournier 已提交
453 454 455 456 457 458 459 460 461 462
					                        yb->next = yy_buffer;

					                        yy_buffer = yb;

								yy_scan_string(ptr->new);
								break;
							}
						}
						if (ptr == NULL) 
						{
M
 
Marc G. Fournier 已提交
463
							yylval.str = mm_strdup((char*)yytext);
464
							return IDENT;
M
 
Marc G. Fournier 已提交
465
						}
M
Marc G. Fournier 已提交
466 467 468
					}
				}
<C>";"	      	        { return(';'); }
469 470
<C>","	      	        { return(','); }
<C>"*"	      	        { return('*'); }
M
Michael Meskes 已提交
471 472 473 474 475 476
<C>"%"	      	        { return('%'); }
<C>"/"	      	        { return('/'); }
<C>"+"	      	        { return('+'); }
<C>"-"	      	        { return('-'); }
<C>"("	      	        { return('('); }
<C>")"	      	        { return(')'); }
M
Marc G. Fournier 已提交
477
<C>{space}		{ ECHO; }
478 479 480 481 482
<C>\{			{ return('{'); }
<C>\}			{ return('}'); }
<C>\[			{ return('['); }
<C>\]			{ return(']'); }
<C>\=			{ return('='); }
M
Michael Meskes 已提交
483
<C>{other}		{ return S_ANYTHING; }
M
 
Marc G. Fournier 已提交
484 485 486
<C>{exec}{space}{sql}{space}{define}	{BEGIN(def_ident);}
<def_ident>{space}	{}
<def_ident>{identifier}	{
M
 
Marc G. Fournier 已提交
487
				old = mm_strdup(yytext);
M
 
Marc G. Fournier 已提交
488 489 490 491 492 493 494 495 496 497 498 499 500
				BEGIN(def);
				llen = 0;
				*literal = '\0';
			}
<def>{space}		/* eat the whitespace */
<def>";"		{
				struct _defines *ptr, *this;
        
                                for (ptr = defines; ptr != NULL; ptr = ptr->next)
                                {
                                     if (strcmp(old, ptr->old) == 0)
                                     {
					free(ptr->new);
M
Michael Meskes 已提交
501
					/* ptr->new = mm_strdup(scanstr(literal));*/
M
Michael Meskes 已提交
502
					ptr->new = mm_strdup(literal);
M
 
Marc G. Fournier 已提交
503 504 505 506 507 508 509 510
                                     }
                                }
				if (ptr == NULL)
				{                        
                                        this = (struct _defines *) mm_alloc(sizeof(struct _defines));

                                        /* initial definition */
                                        this->old = old;
M
Michael Meskes 已提交
511
                                        /* this->new = mm_strdup(scanstr(literal));*/
M
Michael Meskes 已提交
512
                                        this->new = mm_strdup(literal);
M
 
Marc G. Fournier 已提交
513 514 515 516 517 518 519 520 521 522 523 524
					this->next = defines;
					defines = this;
				}

				BEGIN(C);
			}
<def>[^";"]		{
				if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
					yyerror("ERROR: define statement parse buffer exceeded");
				memcpy(literal+llen, yytext, yyleng+1);
				llen += yyleng;
			}
M
Marc G. Fournier 已提交
525 526
<C>{exec}{space}{sql}{space}{include}	{ BEGIN(incl); }
<incl>{space}		/* eat the whitespace */
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
<incl>[^ \t\n]+ 	{ /* got the include file name */
			  struct _yy_buffer *yb;
			  struct _include_path *ip;
			  char inc_file[PATH_MAX];

			  yb = mm_alloc(sizeof(struct _yy_buffer));

			  yb->buffer =  YY_CURRENT_BUFFER;
			  yb->lineno = yylineno;
			  yb->filename = input_filename;
			  yb->next = yy_buffer;

			  yy_buffer = yb;

			  if (yytext[strlen(yytext) - 1] == ';')
				yytext[strlen(yytext) - 1] = '\0';

			  yyin = NULL;
			  for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next)
			  {
				if (strlen(ip->path) + strlen(yytext) + 3 > PATH_MAX)
				{
M
Marc G. Fournier 已提交
549
					fprintf(stderr, "Error: Path %s/%s is too long in line %d, skipping.\n", ip->path, yytext, yylineno);
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
					continue;
				}
			  	sprintf (inc_file, "%s/%s", ip->path, yytext);
		          	yyin = fopen( inc_file, "r" );
			  	if (!yyin)
				{
					if (strcmp(inc_file + strlen(inc_file) - 2, ".h"))
					{
						strcat(inc_file, ".h");
						yyin = fopen( inc_file, "r" );
					}

				}
			  }
			  if (!yyin)
			  {
M
Marc G. Fournier 已提交
566
				fprintf(stderr, "Error: Cannot open include file %s in line %d\n", yytext, yylineno);
567
				exit(NO_INCLUDE_FILE); 
568 569
			  }

M
 
Marc G. Fournier 已提交
570
			  input_filename = mm_strdup(inc_file);
571 572
			  yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE ));
			  yylineno = 0;
M
Michael Meskes 已提交
573
			  output_line_number();
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596

			  BEGIN C;
			}
<incl>";"		{ BEGIN C; }
<<EOF>>			{ if (yy_buffer == NULL)
				yyterminate();
			  else
			  {
				struct _yy_buffer *yb = yy_buffer;

				if (yyin != NULL)
					fclose(yyin);

				yy_delete_buffer( YY_CURRENT_BUFFER );
				yy_switch_to_buffer(yy_buffer->buffer);

				yylineno = yy_buffer->lineno;

				free(input_filename);
				input_filename = yy_buffer->filename;

				yy_buffer = yy_buffer->next;
				free(yb);
M
Michael Meskes 已提交
597
				output_line_number();
598 599
			  }
			}
600 601
%%
void
602
lex_init(void)
603
{
604
    braces_open = 0;
605 606 607
    BEGIN C;
}

608
int yywrap(void) 
609 610 611
{ 
    return 1;
}