From: George Schlossnagle Date: Tue, 18 May 2004 15:38:25 +0000 (+0000) Subject: for those without re2c X-Git-Tag: RELEASE_0_1~148 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=85e3a1bc3b28c2f83258cc6e1c166ddd31145a6b;p=php for those without re2c --- diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c new file mode 100644 index 0000000000..a124df0000 --- /dev/null +++ b/ext/pdo/pdo_sql_parser.c @@ -0,0 +1,223 @@ +/* Generated by re2c 0.5 on Tue May 18 10:23:55 2004 */ +#line 1 "/home/george/src/pecl/pdo/pdo_sql_parser.re" +#include "php.h" +#include "php_pdo_driver.h" + +#define TEXT 1 +#define BIND 2 +#define EOI 3 + +#define RET(i) {s->cur = cursor; return i; } + +#define YYCTYPE char +#define YYCURSOR cursor +#define YYLIMIT s->lim +#define YYMARKER s->ptr +#define YYFILL(n) + +typedef struct Scanner { + char *lim, *ptr, *cur, *tok; +} Scanner; + +static int scan(Scanner *s) +{ + char *cursor = s->cur; + std: + s->tok = cursor; + #line 31 + + + { + YYCTYPE yych; + unsigned int yyaccept; + static unsigned char yybm[] = { + 0, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 0, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 128, 160, 160, 160, 160, 160, + 160, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 160, 32, 160, 160, 160, + 160, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + }; + goto yy0; +yy1: ++YYCURSOR; +yy0: + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yybm[0+yych] & 32) goto yy5; + if(yych <= '\000') goto yy8; + if(yych >= ':') goto yy4; +yy2: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yych >= '\001') goto yy14; +yy3: +#line 36 + { RET(TEXT); } +yy4: yych = *++YYCURSOR; + if(yybm[0+yych] & 64) goto yy10; + goto yy3; +yy5: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy6: if(yybm[0+yych] & 32) goto yy5; +yy7: +#line 37 + { RET(TEXT); } +yy8: yych = *++YYCURSOR; +yy9: +#line 38 + { RET(EOI); } +yy10: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy11: if(yybm[0+yych] & 64) goto yy10; +yy12: +#line 35 + { RET(BIND); } +yy13: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy14: if(yybm[0+yych] & 128) goto yy13; + if(yych <= '\000') goto yy15; + if(yych <= '[') goto yy17; + goto yy16; +yy15: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy3; + } +yy16: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == '"') goto yy13; + goto yy15; +yy17: yych = *++YYCURSOR; +yy18: +#line 34 + { RET(TEXT); } +} +#line 39 + +} + +int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, + int *outquery_len) +{ + Scanner s; + char *ptr; + int t; + int bindno = 0; + int newbuffer_len; + HashTable *params = stmt->bound_params; + struct pdo_bound_param_data *param; + + /* allocate buffer for query with expanded binds, ptr is our writing pointer */ + newbuffer_len = inquery_len; + if(params) { + zend_hash_internal_pointer_reset(params); + while (SUCCESS == zend_hash_get_current_data(params, (void**)¶m)) { + if(param->parameter) { + convert_to_string(param->parameter); + /* accomodate a string that needs to be fully quoted + bind placeholders are at least 2 characters, so + the accomodate their own "'s + */ + newbuffer_len += 2 * Z_STRLEN_P(param->parameter); + } + zend_hash_move_forward(params); + } + } + *outquery = (char *) emalloc(newbuffer_len + 1); + *outquery_len = 0; + + ptr = *outquery; + s.cur = inquery; + s.lim = inquery + inquery_len; + while((t = scan(&s)) != EOI) { + if(t == TEXT) { + memcpy(ptr, s.tok, s.cur - s.tok); + ptr += (s.cur - s.tok); + *outquery_len += (s.cur - s.tok); + } + else if(t == BIND) { + if(!params) { + /* error */ + efree(*outquery); + return 0; + } + /* lookup bind first via hash and then index */ + if((SUCCESS == zend_hash_find(params, s.tok+1, s.cur-s.tok,(void **)¶m)) + || + (SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m))) + { + char *quotedstr; + int quotedstrlen; + /* currently everything is a string here */ + + /* add leading quote */ + *ptr = '"'; + ptr++; + (*outquery_len)++; + + /* quote the bind value if necessary */ + if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), + Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC)) + { + memcpy(ptr, quotedstr, quotedstrlen); + ptr += quotedstrlen; + *outquery_len += quotedstrlen; + efree(quotedstr); + } else { + memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); + ptr += Z_STRLEN_P(param->parameter); + *outquery_len += (Z_STRLEN_P(param->parameter)); + } + /* add trailing quote */ + *ptr = '"'; + ptr++; + (*outquery_len)++; + } + else { + /* error and cleanup */ + efree(*outquery); + return 0; + } + bindno++; + } + } + *ptr = '\0'; + return 1; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */