2 static string scanstring;
4 /* No reason to constrain amount of data slurped */
5 /* #define YY_READ_BUF_SIZE 16777216 */
7 /* Handles to the buffer that the lexer uses internally */
8 static YY_BUFFER_STATE scanbufhandle;
10 static int scanbuflen;
12 static void addstring(bool init, char *s, int l);
13 static void addchar(bool init, char s);
14 static int checkSpecialVal(void); /* examine scanstring for the special value */
16 static bool inputJSON = false;
22 %option never-interactive
28 %option prefix="hstore_yy"
34 any [^\,\[\]\{\}\"\=\> \t\n\r\f\\\:]
39 <INITIAL>[\,\{\}\[\]] { return *yytext; }
41 <INITIAL>\=\> { return DELIMITER_P; }
55 <INITIAL>[ \t\n\r\f]+ { /* ignore */ }
63 addchar(true, yytext[0]);
67 addchar(true, yytext[1]);
71 <INITIAL>({any}|\>)+ {
72 addstring(true, yytext, yyleng);
81 <INITIAL>\= { /* =<<EOF>> */
83 yylval->str = scanstring;
87 <xNONQUOTED>({any}|[\>\"\:])+ {
88 addstring(false, yytext, yyleng);
91 <xNONQUOTED>\=/[^\>] { addchar(false, *yytext); }
93 <xNONQUOTED>[ \t\n\r\f]+ {
94 yylval->str = scanstring;
96 return checkSpecialVal();
99 <xNONQUOTED>\= { /* =<<EOF>> */
101 yylval->str = scanstring;
106 <xNONQUOTED>[\,\{\}\[\]] {
107 yylval->str = scanstring;
110 return checkSpecialVal();
113 <xNONQUOTED><<EOF>> {
114 yylval->str = scanstring;
116 return checkSpecialVal();
120 yylval->str = scanstring;
123 return checkSpecialVal();
127 <xNONQUOTED,xQUOTED>\\. { addchar(false, yytext[1]); }
129 <INITIAL,xNONQUOTED,xQUOTED>\\ { yyerror("Unexpected end after backslesh"); }
131 <xQUOTED><<EOF>> { yyerror("Unexpected end of quoted string"); }
134 yylval->str = scanstring;
139 <xQUOTED>[^\\\"]+ { addstring(false, yytext, yyleng); }
141 <INITIAL><<EOF>> { yyterminate(); }
146 yyerror(const char *message)
148 if (*yytext == YY_END_OF_BUFFER_CHAR)
151 (errcode(ERRCODE_SYNTAX_ERROR),
152 errmsg("bad hstore representation"),
153 /* translator: %s is typically "syntax error" */
154 errdetail("%s at end of input", message)));
159 (errcode(ERRCODE_SYNTAX_ERROR),
160 errmsg("bad hstore representation"),
161 /* translator: first %s is typically "syntax error" */
162 errdetail("%s at or near \"%s\"", message, yytext)));
171 if (stringIsNumber(scanstring.val, scanstring.len, inputJSON))
173 /* for numeric_in() call we need to make a correct C-string */
174 addchar(false, '\0');
177 else if (scanstring.len == 1)
179 if (*scanstring.val == 't')
181 else if (*scanstring.val == 'f')
184 else if (scanstring.len == 4)
186 if (pg_strncasecmp("null", scanstring.val, scanstring.len) == 0)
188 else if (pg_strncasecmp("true", scanstring.val, scanstring.len) == 0)
191 else if (scanstring.len == 5)
193 if (pg_strncasecmp("false", scanstring.val, scanstring.len) == 0)
200 * Called before any actual parsing is done
203 hstore_scanner_init(const char *str, int slen)
209 * Might be left over after ereport()
211 if (YY_CURRENT_BUFFER)
212 yy_delete_buffer(YY_CURRENT_BUFFER);
215 * Make a scan buffer with special termination needed by flex.
219 scanbuf = palloc(slen + 2);
220 memcpy(scanbuf, str, slen);
221 scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
222 scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
229 * Called after parsing is done to clean up after hstore_scanner_init()
232 hstore_scanner_finish(void)
234 yy_delete_buffer(scanbufhandle);
239 addstring(bool init, char *s, int l) {
241 scanstring.total = 32;
242 scanstring.val = palloc(scanstring.total);
247 while(scanstring.len + l + 1 >= scanstring.total) {
248 scanstring.total *= 2;
249 scanstring.val = repalloc(scanstring.val, scanstring.total);
252 memcpy(scanstring.val+scanstring.len, s, l);
258 addchar(bool init, char s) {
261 scanstring.total = 32;
262 scanstring.val = palloc(scanstring.total);
265 else if(scanstring.len + 1 >= scanstring.total)
268 scanstring.val=repalloc(scanstring.val, scanstring.total);
271 scanstring.val[ scanstring.len ] = s;
277 parseHStore(const char *str, int len, bool json) {
278 HStoreValue *parseresult;
282 hstore_scanner_init(str, len);
284 if (hstore_yyparse((void*)&parseresult) != 0)
285 hstore_yyerror("bugus input");
287 hstore_scanner_finish();