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
- /* we do not allow unary minus in numbers.
157
- * instead we pass it verbatim to parser. there it gets
156
+ /* we no longer allow unary minus in numbers.
157
+ * instead we pass it separately 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 */
0 commit comments