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]) { |
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; |