]> granicus.if.org Git - php/commitdiff
for those without re2c
authorGeorge Schlossnagle <gschlossnagle@php.net>
Tue, 18 May 2004 15:38:25 +0000 (15:38 +0000)
committerGeorge Schlossnagle <gschlossnagle@php.net>
Tue, 18 May 2004 15:38:25 +0000 (15:38 +0000)
ext/pdo/pdo_sql_parser.c [new file with mode: 0644]

diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c
new file mode 100644 (file)
index 0000000..a124df0
--- /dev/null
@@ -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**)&param)) {
+                       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 **)&param))  
+                           ||
+                          (SUCCESS == zend_hash_index_find(params, bindno, (void **)&param))) 
+                       {
+                               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), &quotedstr, &quotedstrlen 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
+ */