libidav/davqlparser.c

changeset 365
f04ab0420512
parent 359
bacb54502b24
child 374
38ae05d46f9a
equal deleted inserted replaced
364:3769ba002fd1 365:f04ab0420512
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * 3 *
4 * Copyright 2016 Olaf Wintermann. All rights reserved. 4 * Copyright 2018 Olaf Wintermann. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
729 } 729 }
730 730
731 return total_consumed; 731 return total_consumed;
732 } 732 }
733 733
734 static void dav_add_fmt_args(DavQLStatement *stmt, sstr_t str) {
735 int placeholder = 0;
736 for (size_t i=0;i<str.length;i++) {
737 char c = str.ptr[i];
738 if (placeholder) {
739 if (c != '%') {
740 stmt->args = ucx_list_append(
741 stmt->args,
742 (void*)(intptr_t)c);
743 }
744 placeholder = 0;
745 } else if (c == '%') {
746 placeholder = 1;
747 }
748 }
749 }
750
734 static int dav_parse_literal(DavQLStatement* stmt, UcxList* token, 751 static int dav_parse_literal(DavQLStatement* stmt, UcxList* token,
735 DavQLExpression* expr) { 752 DavQLExpression* expr) {
736 753
737 expr->srctext = token_sstr(token); 754 expr->srctext = token_sstr(token);
738 if (token_is(token, DAVQL_TOKEN_NUMBER)) { 755 if (token_is(token, DAVQL_TOKEN_NUMBER)) {
739 expr->type = DAVQL_NUMBER; 756 expr->type = DAVQL_NUMBER;
740 } else if (token_is(token, DAVQL_TOKEN_STRING)) { 757 } else if (token_is(token, DAVQL_TOKEN_STRING)) {
741 expr->type = DAVQL_STRING; 758 expr->type = DAVQL_STRING;
759 // check for format specifiers and add args
760 dav_add_fmt_args(stmt, expr->srctext);
742 } else if (token_is(token, DAVQL_TOKEN_TIMESTAMP)) { 761 } else if (token_is(token, DAVQL_TOKEN_TIMESTAMP)) {
743 expr->type = DAVQL_TIMESTAMP; 762 expr->type = DAVQL_TIMESTAMP;
744 } else if (token_is(token, DAVQL_TOKEN_FMTSPEC) 763 } else if (token_is(token, DAVQL_TOKEN_FMTSPEC)
745 && expr->srctext.length == 2) { 764 && expr->srctext.length == 2) {
746 switch (expr->srctext.ptr[1]) { 765 switch (expr->srctext.ptr[1]) {
750 default: 769 default:
751 dav_error_in_context(DAVQL_ERROR_INVALID_FMTSPEC, 770 dav_error_in_context(DAVQL_ERROR_INVALID_FMTSPEC,
752 _error_invalid_fmtspec, stmt, token); 771 _error_invalid_fmtspec, stmt, token);
753 return 0; 772 return 0;
754 } 773 }
774 // add fmtspec type to query arg list
775 stmt->args = ucx_list_append(stmt->args, (void*)(intptr_t)expr->srctext.ptr[1]);
755 } else { 776 } else {
756 return 0; 777 return 0;
757 } 778 }
758 779
759 return 1; 780 return 1;
1150 dqlsec_mallocz(stmt, expr->right, DavQLExpression); 1171 dqlsec_mallocz(stmt, expr->right, DavQLExpression);
1151 expr->right->type = DAVQL_STRING; 1172 expr->right->type = DAVQL_STRING;
1152 expr->right->srctext = token_sstr(token); 1173 expr->right->srctext = token_sstr(token);
1153 expr->srctext.length = expr->right->srctext.ptr - 1174 expr->srctext.length = expr->right->srctext.ptr -
1154 expr->srctext.ptr + expr->right->srctext.length; 1175 expr->srctext.ptr + expr->right->srctext.length;
1176
1177 // fmt args
1178 dav_add_fmt_args(stmt, expr->right->srctext);
1155 1179
1156 return total_consumed + 1; 1180 return total_consumed + 1;
1157 } else { 1181 } else {
1158 dav_error_in_context(DAVQL_ERROR_INVALID_STRING, 1182 dav_error_in_context(DAVQL_ERROR_INVALID_STRING,
1159 _error_invalid_string, stmt, token); 1183 _error_invalid_string, stmt, token);
1377 1401
1378 if (consumed) { 1402 if (consumed) {
1379 if (depthexpr->type == DAVQL_NUMBER) { 1403 if (depthexpr->type == DAVQL_NUMBER) {
1380 if (depthexpr->srctext.ptr[0] == '%') { 1404 if (depthexpr->srctext.ptr[0] == '%') {
1381 stmt->depth = DAV_DEPTH_PLACEHOLDER; 1405 stmt->depth = DAV_DEPTH_PLACEHOLDER;
1406 stmt->args = ucx_list_append(
1407 stmt->args,
1408 (void*)(intptr_t)depthexpr->srctext.ptr[1]);
1382 } else { 1409 } else {
1383 sstr_t depthstr = depthexpr->srctext; 1410 sstr_t depthstr = depthexpr->srctext;
1384 char *conv = malloc(depthstr.length+1); 1411 char *conv = malloc(depthstr.length+1);
1385 if (!conv) { 1412 if (!conv) {
1386 dav_free_expression(depthexpr); 1413 dav_free_expression(depthexpr);
1556 return consumed; 1583 return consumed;
1557 } else if (token_is(tokens, DAVQL_TOKEN_FMTSPEC) && 1584 } else if (token_is(tokens, DAVQL_TOKEN_FMTSPEC) &&
1558 tokenvalue_is(tokens, "%s")) { 1585 tokenvalue_is(tokens, "%s")) {
1559 stmt->path = token_sstr(tokens); 1586 stmt->path = token_sstr(tokens);
1560 tokens = tokens->next; 1587 tokens = tokens->next;
1588 stmt->args = ucx_list_append(stmt->args, (void*)(intptr_t)'s');
1561 return 1; 1589 return 1;
1562 } else { 1590 } else {
1563 dav_error_in_context(DAVQL_ERROR_MISSING_TOKEN, 1591 dav_error_in_context(DAVQL_ERROR_MISSING_TOKEN,
1564 _error_missing_path, stmt, tokens); 1592 _error_missing_path, stmt, tokens);
1565 return 0; 1593 return 0;
1593 // Consume path 1621 // Consume path
1594 tokens = ucx_list_get(tokens, dav_parse_path(stmt, tokens)); 1622 tokens = ucx_list_get(tokens, dav_parse_path(stmt, tokens));
1595 if (stmt->errorcode) { 1623 if (stmt->errorcode) {
1596 return; 1624 return;
1597 } 1625 }
1626 dav_add_fmt_args(stmt, stmt->path); // add possible path args
1598 1627
1599 // Consume with clause (if any) 1628 // Consume with clause (if any)
1600 if (token_is(tokens, DAVQL_TOKEN_KEYWORD) 1629 if (token_is(tokens, DAVQL_TOKEN_KEYWORD)
1601 && tokenvalue_is(tokens, "with")) { 1630 && tokenvalue_is(tokens, "with")) {
1602 tokens = tokens->next; 1631 tokens = tokens->next;
1784 } 1813 }
1785 UCX_FOREACH(crit, stmt->orderby) { 1814 UCX_FOREACH(crit, stmt->orderby) {
1786 dav_free_order_criterion(crit->data); 1815 dav_free_order_criterion(crit->data);
1787 } 1816 }
1788 ucx_list_free(stmt->orderby); 1817 ucx_list_free(stmt->orderby);
1818 ucx_list_free(stmt->args);
1789 free(stmt); 1819 free(stmt);
1790 } 1820 }

mercurial