libidav/davqlparser.c

changeset 365
f04ab0420512
parent 359
bacb54502b24
child 374
38ae05d46f9a
--- a/libidav/davqlparser.c	Thu Feb 01 16:31:24 2018 +0100
+++ b/libidav/davqlparser.c	Thu Feb 01 18:25:23 2018 +0100
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2016 Olaf Wintermann. All rights reserved.
+ * Copyright 2018 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -731,6 +731,23 @@
     return total_consumed;
 }
 
+static void dav_add_fmt_args(DavQLStatement *stmt, sstr_t str) {
+    int placeholder = 0;
+    for (size_t i=0;i<str.length;i++) {
+        char c = str.ptr[i];
+        if (placeholder) {
+            if (c != '%') {
+                stmt->args = ucx_list_append(
+                        stmt->args,
+                        (void*)(intptr_t)c);
+            }
+            placeholder = 0;
+        } else if (c == '%') {
+            placeholder = 1;
+        }
+    }
+}
+
 static int dav_parse_literal(DavQLStatement* stmt, UcxList* token,
         DavQLExpression* expr) {
     
@@ -739,6 +756,8 @@
         expr->type = DAVQL_NUMBER;
     } else if (token_is(token, DAVQL_TOKEN_STRING)) {
         expr->type = DAVQL_STRING;
+        // check for format specifiers and add args
+        dav_add_fmt_args(stmt, expr->srctext);
     } else if (token_is(token, DAVQL_TOKEN_TIMESTAMP)) {
         expr->type = DAVQL_TIMESTAMP;
     } else if (token_is(token, DAVQL_TOKEN_FMTSPEC)
@@ -752,6 +771,8 @@
                 _error_invalid_fmtspec, stmt, token);
             return 0;
         }
+        // add fmtspec type to query arg list
+        stmt->args = ucx_list_append(stmt->args, (void*)(intptr_t)expr->srctext.ptr[1]);
     } else {
         return 0;
     }
@@ -1152,6 +1173,9 @@
             expr->right->srctext = token_sstr(token);
             expr->srctext.length = expr->right->srctext.ptr -
                 expr->srctext.ptr + expr->right->srctext.length;
+            
+            // fmt args
+            dav_add_fmt_args(stmt, expr->right->srctext);
 
             return total_consumed + 1;
         } else {
@@ -1379,6 +1403,9 @@
                     if (depthexpr->type == DAVQL_NUMBER) {
                         if (depthexpr->srctext.ptr[0] == '%') {
                             stmt->depth = DAV_DEPTH_PLACEHOLDER;
+                            stmt->args = ucx_list_append(
+                                    stmt->args,
+                                    (void*)(intptr_t)depthexpr->srctext.ptr[1]);
                         } else {
                             sstr_t depthstr = depthexpr->srctext;
                             char *conv = malloc(depthstr.length+1);
@@ -1558,6 +1585,7 @@
             tokenvalue_is(tokens, "%s")) {
         stmt->path = token_sstr(tokens);
         tokens = tokens->next;
+        stmt->args = ucx_list_append(stmt->args, (void*)(intptr_t)'s');
         return 1;
     } else {
         dav_error_in_context(DAVQL_ERROR_MISSING_TOKEN,
@@ -1595,6 +1623,7 @@
     if (stmt->errorcode) {
         return;
     }
+    dav_add_fmt_args(stmt, stmt->path); // add possible path args
     
     // Consume with clause (if any)
     if (token_is(tokens, DAVQL_TOKEN_KEYWORD)
@@ -1786,5 +1815,6 @@
         dav_free_order_criterion(crit->data);
     }
     ucx_list_free(stmt->orderby);
+    ucx_list_free(stmt->args);
     free(stmt);
 }

mercurial