1-
2- /* This is a modified version of src/backend/parser/scan.l */
31%{
2+ /* -------------------------------------------------------------------------
3+ *
4+ * pgc.l
5+ * lexical scanner for ecpg
6+ *
7+ * This is a modified version of src/backend/parser/scan.l
8+ *
9+ *
10+ * Copyright (c) 1994, Regents of the University of California
11+ *
12+ *
13+ * IDENTIFICATION
14+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.45 1999/10/22 23:14:50 tgl Exp $
15+ *
16+ *-------------------------------------------------------------------------
17+ */
418#include < ctype.h>
519#include < sys/types.h>
620#include < limits.h>
721#include < errno.h>
822
923#include " postgres.h"
24+
1025#ifndef PATH_MAX
1126#include < sys/param.h>
1227#define PATH_MAX MAXPATHLEN
1328#endif
29+
1430#include " miscadmin.h"
15- #include " nodes/pg_list.h"
1631#include " nodes/parsenodes.h"
32+ #include " nodes/pg_list.h"
1733#include " parser/gramparse.h"
1834#include " parser/scansup.h"
1935#include " extern.h"
2036#include " preproc.h"
2137#include " utils/builtins.h"
2238
23- #ifdef YY_READ_BUF_SIZE
24- #undef YY_READ_BUF_SIZE
25- #endif
26- #define YY_READ_BUF_SIZE MAX_PARSE_BUFFER
27-
2839/* some versions of lex define this as a macro */
2940#if defined(yywrap)
3041#undef yywrap
3142#endif /* yywrap */
3243
3344extern YYSTYPE yylval;
34- int llen;
35- char literal[MAX_PARSE_BUFFER];
45+
46+ /*
47+ * literalbuf is used to accumulate literal values when multiple rules
48+ * are needed to parse a single literal. Call startlit to reset buffer
49+ * to empty, addlit to add text. Note that the buffer is permanently
50+ * malloc'd to the largest size needed so far in the current run.
51+ */
52+ static char *literalbuf = NULL ; /* expandable buffer */
53+ static int literallen; /* actual current length */
54+ static int literalalloc; /* current allocated buffer size */
55+
56+ #define startlit () (literalbuf[0 ] = ' \0 ' , literallen = 0 )
57+ static void addlit (char *ytext, int yleng);
58+
3659int before_comment;
3760
3861struct _yy_buffer { YY_BUFFER_STATE buffer;
@@ -142,16 +165,14 @@ self [,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|]
142165op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\= ]
143166operator {op_and_self }+
144167
145- /* we do not allow unary minus in numbers.
146- * instead we pass it verbatim to parser. there it gets
147- * coerced via doNegate() -- Leon aug 20 1999
168+ /* we no longer allow unary minus in numbers.
169+ * instead we pass it separately to parser. there it gets
170+ * coerced via doNegate() -- Leon aug 20 1999
148171 */
172+
149173integer {digit }+
150174decimal (({digit }* \. {digit }+ )| ({digit }+ \. {digit }* ))
151- real ((({digit }* \. {digit }+ )| ({digit }+ \. {digit }* )| ({digit }+ ))([Ee ][-+ ]? {digit }+ ))
152- /*
153- real (((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
154- */
175+ real ((({digit }* \. {digit }+ )| ({digit }+ \. {digit }* )| ({digit }+ ))([Ee ][-+ ]? {digit }+ ))
155176
156177param \$ {integer }
157178
@@ -200,99 +221,82 @@ cppline {space}*#.*(\\{space}*\n)*\n*
200221
201222<SQL >{xbstart } {
202223 BEGIN (xb);
203- llen = 0 ;
204- *literal = ' \0 ' ;
224+ startlit ();
205225 }
206226<xb >{xbstop } {
207227 char * endptr;
208228
209229 BEGIN (SQL);
210230 errno = 0 ;
211- yylval.ival = strtol (( char *)literal, &endptr,2 );
231+ yylval.ival = strtol (literalbuf, &endptr, 2 );
212232 if (*endptr != ' \0 ' || errno == ERANGE)
213233 yyerror (" ERROR: Bad binary integer input!" );
214234 return ICONST;
215235 }
216236<xh >{xhinside } |
217237<xb >{xbinside } {
218- if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1 ))
219- yyerror (" ERROR: quoted string parse buffer exceeded" );
220- memcpy (literal+llen, yytext, yyleng+1 );
221- llen += yyleng;
238+ addlit (yytext, yyleng);
222239 }
223240<xh >{xhcat } |
224241<xb >{xbcat } {
225242 }
226243
227244<SQL >{xhstart } {
228245 BEGIN (xh);
229- llen = 0 ;
230- *literal = ' \0 ' ;
246+ startlit ();
231247 }
232248<xh >{xhstop } {
233249 char * endptr;
234250
235251 BEGIN (SQL);
236252 errno = 0 ;
237- yylval.ival = strtol (( char *)literal, &endptr,16 );
253+ yylval.ival = strtol (literalbuf, &endptr, 16 );
238254 if (*endptr != ' \0 ' || errno == ERANGE)
239255 yyerror (" ERROR: Bad hexadecimal integer input" );
240256 return ICONST;
241257 }
242258
243259<SQL >{xqstart } {
244260 BEGIN (xq);
245- llen = 0 ;
246- *literal = ' \0 ' ;
261+ startlit ();
247262 }
248263<xq >{xqstop } {
249264 BEGIN (SQL);
250- yylval.str = mm_strdup (literal );
265+ yylval.str = mm_strdup (literalbuf );
251266 return SCONST;
252267 }
253268<xq >{xqdouble } |
254- <xq >{xqinside } |
269+ <xq >{xqinside } |
255270<xq >{xqliteral } {
256- if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1 ))
257- yyerror (" ERROR: quoted string parse buffer exceeded" );
258- memcpy (literal+llen, yytext, yyleng+1 );
259- llen += yyleng;
271+ addlit (yytext, yyleng);
260272 }
261273<xq >{xqcat } {
262274 }
263275
264276
265277<SQL >{xdstart } {
266278 BEGIN (xd);
267- llen = 0 ;
268- *literal = ' \0 ' ;
279+ startlit ();
269280 }
270281<xd >{xdstop } {
271282 BEGIN (SQL);
272- yylval.str = mm_strdup (literal );
283+ yylval.str = mm_strdup (literalbuf );
273284 return CSTRING;
274285 }
275286<xd >{xdinside } {
276- if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1 ))
277- yyerror (" ERROR: quoted string parse buffer exceeded" );
278- memcpy (literal+llen, yytext, yyleng+1 );
279- llen += yyleng;
287+ addlit (yytext, yyleng);
280288 }
281289{xdstart } {
282290 BEGIN (xdc);
283- llen = 0 ;
284- *literal = ' \0 ' ;
291+ startlit ();
285292 }
286293<xdc >{xdstop } {
287294 BEGIN (C);
288- yylval.str = mm_strdup (literal );
295+ yylval.str = mm_strdup (literalbuf );
289296 return CSTRING;
290297 }
291298<xdc >{xdcinside } {
292- if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1 ))
293- yyerror (" ERROR: quoted string parse buffer exceeded" );
294- memcpy (literal+llen, yytext, yyleng+1 );
295- llen += yyleng;
299+ addlit (yytext, yyleng);
296300 }
297301<SQL >{typecast } { return TYPECAST; }
298302<SQL >{self } { /*
@@ -324,24 +328,24 @@ cppline {space}*#.*(\\{space}*\n)*\n*
324328 {
325329 errno = 0 ;
326330 yylval.str = mm_strdup ((char *)yytext);
327- return SCONST;
331+ return SCONST;
328332 }
329333 return ICONST;
330334 }
331- {decimal } {
332- char * endptr;
335+ {decimal } {
336+ char * endptr;
333337
334- if (strlen ((char *)yytext) <= 17 )
335- {
336- errno = 0 ;
337- yylval.dval = strtod ((char *)yytext,&endptr);
338+ if (strlen ((char *)yytext) <= 17 )
339+ {
340+ errno = 0 ;
341+ yylval.dval = strtod ((char *)yytext,&endptr);
338342 if (*endptr != ' \0 ' || errno == ERANGE)
339343 yyerror (" ERROR: Bad float8 input" );
340344 return FCONST;
341- }
342- yylval.str = mm_strdup ((char *)yytext);
343- return SCONST;
344- }
345+ }
346+ yylval.str = mm_strdup ((char *)yytext);
347+ return SCONST;
348+ }
345349<C ,SQL >{real } {
346350 char * endptr;
347351
@@ -420,7 +424,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
420424 {
421425 errno = 0 ;
422426 yylval.str = mm_strdup ((char *)yytext);
423- return SCONST;
427+ return SCONST;
424428 }
425429 return ICONST;
426430 }
@@ -486,8 +490,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
486490<def_ident >{identifier } {
487491 old = mm_strdup (yytext);
488492 BEGIN (def);
489- llen = 0 ;
490- *literal = ' \0 ' ;
493+ startlit ();
491494 }
492495<def >{space } /* eat the whitespace */
493496<def >" ;" {
@@ -498,8 +501,8 @@ cppline {space}*#.*(\\{space}*\n)*\n*
498501 if (strcmp (old, ptr->old ) == 0 )
499502 {
500503 free (ptr->new );
501- /* ptr->new = mm_strdup(scanstr(literal ));*/
502- ptr->new = mm_strdup (literal );
504+ /* ptr->new = mm_strdup(scanstr(literalbuf ));*/
505+ ptr->new = mm_strdup (literalbuf );
503506 }
504507 }
505508 if (ptr == NULL )
@@ -508,19 +511,16 @@ cppline {space}*#.*(\\{space}*\n)*\n*
508511
509512 /* initial definition */
510513 this ->old = old;
511- /* this->new = mm_strdup(scanstr(literal ));*/
512- this ->new = mm_strdup (literal );
514+ /* this->new = mm_strdup(scanstr(literalbuf ));*/
515+ this ->new = mm_strdup (literalbuf );
513516 this ->next = defines;
514517 defines = this ;
515518 }
516519
517520 BEGIN (C);
518521 }
519522<def >[^ ";" ] {
520- if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1 ))
521- yyerror (" ERROR: define statement parse buffer exceeded" );
522- memcpy (literal+llen, yytext, yyleng+1 );
523- llen += yyleng;
523+ addlit (yytext, yyleng);
524524 }
525525<C >{exec }{space }{sql }{space }{include } { BEGIN (incl); }
526526<incl >{space } /* eat the whitespace */
@@ -602,9 +602,34 @@ void
602602lex_init (void )
603603{
604604 braces_open = 0 ;
605+
606+ /* initialize literal buffer to a reasonable but expansible size */
607+ if (literalbuf == NULL )
608+ {
609+ literalalloc = 128 ;
610+ literalbuf = (char *) malloc (literalalloc);
611+ }
612+ startlit ();
613+
605614 BEGIN C;
606615}
607616
617+ static void
618+ addlit (char *ytext, int yleng)
619+ {
620+ /* enlarge buffer if needed */
621+ if ((literallen+yleng) >= literalalloc)
622+ {
623+ do {
624+ literalalloc *= 2 ;
625+ } while ((literallen+yleng) >= literalalloc);
626+ literalbuf = (char *) realloc (literalbuf, literalalloc);
627+ }
628+ /* append data --- note we assume ytext is null-terminated */
629+ memcpy (literalbuf+literallen, ytext, yleng+1 );
630+ literallen += yleng;
631+ }
632+
608633int yywrap (void )
609634{
610635 return 1 ;
0 commit comments