88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.59 1999/10/09 01:32:38 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.60 1999/10/18 02:42:31 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414*/
2020#include < errno.h>
2121
2222#include " postgres.h"
23+
2324#include " miscadmin.h"
2425#include " nodes/parsenodes.h"
2526#include " nodes/pg_list.h"
2930#include " parser/scansup.h"
3031#include " utils/builtins.h"
3132
32- #ifdef YY_READ_BUF_SIZE
33- #undef YY_READ_BUF_SIZE
34- #endif
35- #define YY_READ_BUF_SIZE MAX_PARSE_BUFFER
36-
37- #ifdef YY_READ_BUF_SIZE
38- #undef YY_READ_BUF_SIZE
39- #endif
40- #define YY_READ_BUF_SIZE MAX_PARSE_BUFFER
41-
4233extern char *parseString;
4334static char *parseCh;
4435
@@ -47,9 +38,8 @@ static char *parseCh;
4738#undef yywrap
4839#endif /* yywrap*/
4940
41+ /* set up my input handler --- need one flavor for flex, one for lex*/
5042#if defined(FLEX_SCANNER)
51- /* MAX_PARSE_BUFFER is defined in miscadmin.h */
52- #define YYLMAX MAX_PARSE_BUFFER
5343#define YY_NO_UNPUT
5444static int myinput (char * buf,int max);
5545#undef YY_INPUT
@@ -63,8 +53,18 @@ void unput(char);
6353
6454extern YYSTYPE yylval;
6555
66- int llen;
67- char literal[MAX_PARSE_BUFFER];
56+ /*
57+ * literalbuf is used to accumulate literal values when multiple rules
58+ * are needed to parse a single literal. Call startlit to reset buffer
59+ * to empty, addlit to add text. Note that the buffer is palloc'd and
60+ * starts life afresh on every parse cycle.
61+ */
62+ static char *literalbuf;/* expandable buffer*/
63+ static int literallen;/* actual current length*/
64+ static int literalalloc;/* current allocated buffer size*/
65+
66+ #define startlit () (literalbuf[0 ] =' \0 ' , literallen =0 )
67+ static void addlit (char *ytext,int yleng);
6868
6969%}
7070/* OK, here is a short description of lex/flex rules behavior.
@@ -153,17 +153,14 @@ self[,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|]
153153op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\= ]
154154operator {op_and_self }+
155155
156- /* wedo not allow unary minus in numbers.
157- * instead we pass itverbatim to parser. there it gets
156+ /* weno longer allow unary minus in numbers.
157+ * instead we pass itseparately to parser. there it gets
158158 * coerced via doNegate() -- Leon aug 20 1999
159159 */
160160
161161integer {digit }+
162162decimal (({digit }* \. {digit }+ )| ({digit }+ \. {digit }* ))
163163real ((({digit }* \. {digit }+ )| ({digit }+ \. {digit }* )| ({digit }+ ))([Ee ][-+ ]? {digit }+ ))
164- /*
165- real(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
166- */
167164
168165param \$ {integer }
169166
@@ -199,88 +196,77 @@ other.
199196
200197{xbstart }{
201198BEGIN (xb);
202- llen =0 ;
203- *literal =' \0 ' ;
199+ startlit ();
204200}
205201<xb >{xbstop }{
206202char * endptr;
207203
208204BEGIN (INITIAL);
209205errno =0 ;
210- yylval.ival =strtol (( char *)literal, &endptr,2 );
206+ yylval.ival =strtol (literalbuf, &endptr,2 );
211207if (*endptr !=' \0 ' || errno == ERANGE)
212- elog (ERROR," Bad binary integer input '%s'" ,literal);
208+ elog (ERROR," Bad binary integer input '%s'" ,
209+ literalbuf);
213210return ICONST;
214211}
215212<xh >{xhinside }|
216213<xb >{xbinside }{
217- if ((llen+yyleng) > (MAX_PARSE_BUFFER -1 ))
218- elog (ERROR," quoted string parse buffer of %d chars exceeded" ,MAX_PARSE_BUFFER);
219- memcpy (literal+llen, yytext, yyleng+1 );
220- llen += yyleng;
214+ addlit (yytext, yyleng);
221215}
222216<xh >{xhcat }|
223217<xb >{xbcat }{
224218}
225219
226220{xhstart }{
227221BEGIN (xh);
228- llen =0 ;
229- *literal =' \0 ' ;
222+ startlit ();
230223}
231224<xh >{xhstop }{
232225char * endptr;
233226
234227BEGIN (INITIAL);
235228errno =0 ;
236- yylval.ival =strtol (( char *)literal, &endptr,16 );
229+ yylval.ival =strtol (literalbuf, &endptr,16 );
237230if (*endptr !=' \0 ' || errno == ERANGE)
238- elog (ERROR," Bad hexadecimal integer input '%s'" ,literal);
231+ elog (ERROR," Bad hexadecimal integer input '%s'" ,
232+ literalbuf);
239233return ICONST;
240234}
241235
242236{xqstart }{
243237BEGIN (xq);
244- llen =0 ;
245- *literal =' \0 ' ;
238+ startlit ();
246239}
247240<xq >{xqstop }{
248241BEGIN (INITIAL);
249- yylval.str =scanstr (literal );
242+ yylval.str =scanstr (literalbuf );
250243return SCONST;
251244}
252245<xq >{xqdouble }|
253246<xq >{xqinside }|
254247<xq >{xqliteral } {
255- if ((llen+yyleng) > (MAX_PARSE_BUFFER -1 ))
256- elog (ERROR," quoted string parse buffer of %d chars exceeded" ,MAX_PARSE_BUFFER);
257- memcpy (literal+llen, yytext, yyleng+1 );
258- llen += yyleng;
248+ addlit (yytext, yyleng);
259249}
260250<xq >{xqcat }{
261251}
262252
263253
264254{xdstart }{
265255BEGIN (xd);
266- llen =0 ;
267- *literal =' \0 ' ;
256+ startlit ();
268257}
269258<xd >{xdstop }{
270259BEGIN (INITIAL);
271- yylval.str =pstrdup (literal );
260+ yylval.str =pstrdup (literalbuf );
272261return IDENT;
273262}
274263<xd >{xdinside }{
275- if ((llen+yyleng) > (MAX_PARSE_BUFFER -1 ))
276- elog (ERROR," quoted string parse buffer of %d chars exceeded" ,MAX_PARSE_BUFFER);
277- memcpy (literal+llen, yytext, yyleng+1 );
278- llen += yyleng;
264+ addlit (yytext, yyleng);
279265}
280266
281267{typecast }{return TYPECAST; }
282268
283- {self }{return yytext[0 ]; }
269+ {self }{return yytext[0 ]; }
284270
285271{operator }{
286272if (strcmp ((char *)yytext," !=" ) ==0 )
@@ -391,14 +377,37 @@ init_io()
391377 because input()/myinput() checks the non-nullness of parseCh
392378 to know when to pass the string to lex/flex */
393379parseCh =NULL ;
380+
381+ /* initialize literal buffer to a reasonable but expansible size */
382+ literalalloc =128 ;
383+ literalbuf = (char *)palloc (literalalloc);
384+ startlit ();
385+
394386#if defined(FLEX_SCANNER)
395387if (YY_CURRENT_BUFFER)
396388yy_flush_buffer (YY_CURRENT_BUFFER);
397389#endif /* FLEX_SCANNER */
398390BEGIN INITIAL;
399391}
400392
393+ static void
394+ addlit (char *ytext,int yleng)
395+ {
396+ /* enlarge buffer if needed */
397+ if ((literallen+yleng) >= literalalloc)
398+ {
399+ do {
400+ literalalloc *=2 ;
401+ }while ((literallen+yleng) >= literalalloc);
402+ literalbuf = (char *)repalloc (literalbuf, literalalloc);
403+ }
404+ /* append data --- note we assume ytext is null-terminated */
405+ memcpy (literalbuf+literallen, ytext, yleng+1 );
406+ literallen += yleng;
407+ }
408+
401409#if !defined(FLEX_SCANNER)
410+
402411/* get lex input from a string instead of from stdin */
403412int
404413input ()
@@ -420,27 +429,31 @@ unput(char c)
420429else if (c !=0 )
421430*--parseCh = c;
422431}
432+
423433#endif /* !defined(FLEX_SCANNER) */
424434
425435#ifdef FLEX_SCANNER
436+
426437/* input routine for flex to read input from a string instead of a file */
427438static int
428439myinput (char * buf,int max)
429440{
430- int len, copylen ;
441+ int len;
431442
432443if (parseCh ==NULL )
433444parseCh = parseString;
434445len =strlen (parseCh);/* remaining data available */
435- if (len >= max)
436- copylen = max -1 ;
437- else
438- copylen = len;
439- if (copylen >0 )
440- memcpy (buf, parseCh, copylen);
441- buf[copylen] =' \0 ' ;
442- parseCh += copylen;
443- return copylen;
446+ /* Note: this code used to think that flex wants a null-terminated
447+ * string. It does NOT, and returning 1 less character than it asks
448+ * for will cause failure under the right boundary conditions. So
449+ * shut up and fill the buffer to the limit, you hear?
450+ */
451+ if (len > max)
452+ len = max;
453+ if (len >0 )
454+ memcpy (buf, parseCh, len);
455+ parseCh += len;
456+ return len;
444457}
445- #endif /* FLEX_SCANNER */
446458
459+ #endif /* FLEX_SCANNER */