8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
20
20
#include < errno.h>
21
21
22
22
#include " postgres.h"
23
+
23
24
#include " miscadmin.h"
24
25
#include " nodes/parsenodes.h"
25
26
#include " nodes/pg_list.h"
29
30
#include " parser/scansup.h"
30
31
#include " utils/builtins.h"
31
32
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
-
42
33
extern char *parseString;
43
34
static char *parseCh;
44
35
@@ -47,9 +38,8 @@ static char *parseCh;
47
38
#undef yywrap
48
39
#endif /* yywrap*/
49
40
41
+ /* set up my input handler --- need one flavor for flex, one for lex*/
50
42
#if defined(FLEX_SCANNER)
51
- /* MAX_PARSE_BUFFER is defined in miscadmin.h */
52
- #define YYLMAX MAX_PARSE_BUFFER
53
43
#define YY_NO_UNPUT
54
44
static int myinput (char * buf,int max);
55
45
#undef YY_INPUT
@@ -63,8 +53,18 @@ void unput(char);
63
53
64
54
extern YYSTYPE yylval;
65
55
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);
68
68
69
69
%}
70
70
/* OK, here is a short description of lex/flex rules behavior.
@@ -153,17 +153,14 @@ self[,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|]
153
153
op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\= ]
154
154
operator {op_and_self }+
155
155
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
158
158
* coerced via doNegate() -- Leon aug 20 1999
159
159
*/
160
160
161
161
integer {digit }+
162
162
decimal (({digit }* \. {digit }+ )| ({digit }+ \. {digit }* ))
163
163
real ((({digit }* \. {digit }+ )| ({digit }+ \. {digit }* )| ({digit }+ ))([Ee ][-+ ]? {digit }+ ))
164
- /*
165
- real(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
166
- */
167
164
168
165
param \$ {integer }
169
166
@@ -199,88 +196,77 @@ other.
199
196
200
197
{xbstart }{
201
198
BEGIN (xb);
202
- llen =0 ;
203
- *literal =' \0 ' ;
199
+ startlit ();
204
200
}
205
201
<xb >{xbstop }{
206
202
char * endptr;
207
203
208
204
BEGIN (INITIAL);
209
205
errno =0 ;
210
- yylval.ival =strtol (( char *)literal, &endptr,2 );
206
+ yylval.ival =strtol (literalbuf, &endptr,2 );
211
207
if (*endptr !=' \0 ' || errno == ERANGE)
212
- elog (ERROR," Bad binary integer input '%s'" ,literal);
208
+ elog (ERROR," Bad binary integer input '%s'" ,
209
+ literalbuf);
213
210
return ICONST;
214
211
}
215
212
<xh >{xhinside }|
216
213
<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);
221
215
}
222
216
<xh >{xhcat }|
223
217
<xb >{xbcat }{
224
218
}
225
219
226
220
{xhstart }{
227
221
BEGIN (xh);
228
- llen =0 ;
229
- *literal =' \0 ' ;
222
+ startlit ();
230
223
}
231
224
<xh >{xhstop }{
232
225
char * endptr;
233
226
234
227
BEGIN (INITIAL);
235
228
errno =0 ;
236
- yylval.ival =strtol (( char *)literal, &endptr,16 );
229
+ yylval.ival =strtol (literalbuf, &endptr,16 );
237
230
if (*endptr !=' \0 ' || errno == ERANGE)
238
- elog (ERROR," Bad hexadecimal integer input '%s'" ,literal);
231
+ elog (ERROR," Bad hexadecimal integer input '%s'" ,
232
+ literalbuf);
239
233
return ICONST;
240
234
}
241
235
242
236
{xqstart }{
243
237
BEGIN (xq);
244
- llen =0 ;
245
- *literal =' \0 ' ;
238
+ startlit ();
246
239
}
247
240
<xq >{xqstop }{
248
241
BEGIN (INITIAL);
249
- yylval.str =scanstr (literal );
242
+ yylval.str =scanstr (literalbuf );
250
243
return SCONST;
251
244
}
252
245
<xq >{xqdouble }|
253
246
<xq >{xqinside }|
254
247
<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);
259
249
}
260
250
<xq >{xqcat }{
261
251
}
262
252
263
253
264
254
{xdstart }{
265
255
BEGIN (xd);
266
- llen =0 ;
267
- *literal =' \0 ' ;
256
+ startlit ();
268
257
}
269
258
<xd >{xdstop }{
270
259
BEGIN (INITIAL);
271
- yylval.str =pstrdup (literal );
260
+ yylval.str =pstrdup (literalbuf );
272
261
return IDENT;
273
262
}
274
263
<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);
279
265
}
280
266
281
267
{typecast }{return TYPECAST; }
282
268
283
- {self }{return yytext[0 ]; }
269
+ {self }{return yytext[0 ]; }
284
270
285
271
{operator }{
286
272
if (strcmp ((char *)yytext," !=" ) ==0 )
@@ -391,14 +377,37 @@ init_io()
391
377
because input()/myinput() checks the non-nullness of parseCh
392
378
to know when to pass the string to lex/flex */
393
379
parseCh =NULL ;
380
+
381
+ /* initialize literal buffer to a reasonable but expansible size */
382
+ literalalloc =128 ;
383
+ literalbuf = (char *)palloc (literalalloc);
384
+ startlit ();
385
+
394
386
#if defined(FLEX_SCANNER)
395
387
if (YY_CURRENT_BUFFER)
396
388
yy_flush_buffer (YY_CURRENT_BUFFER);
397
389
#endif /* FLEX_SCANNER */
398
390
BEGIN INITIAL;
399
391
}
400
392
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
+
401
409
#if !defined(FLEX_SCANNER)
410
+
402
411
/* get lex input from a string instead of from stdin */
403
412
int
404
413
input ()
@@ -420,27 +429,31 @@ unput(char c)
420
429
else if (c !=0 )
421
430
*--parseCh = c;
422
431
}
432
+
423
433
#endif /* !defined(FLEX_SCANNER) */
424
434
425
435
#ifdef FLEX_SCANNER
436
+
426
437
/* input routine for flex to read input from a string instead of a file */
427
438
static int
428
439
myinput (char * buf,int max)
429
440
{
430
- int len, copylen ;
441
+ int len;
431
442
432
443
if (parseCh ==NULL )
433
444
parseCh = parseString;
434
445
len =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;
444
457
}
445
- #endif /* FLEX_SCANNER */
446
458
459
+ #endif /* FLEX_SCANNER */