417 lp, prev.ptr, |
417 lp, prev.ptr, |
418 sfmtarg(tokenstr), |
418 sfmtarg(tokenstr), |
419 ln, pn).ptr; |
419 ln, pn).ptr; |
420 } |
420 } |
421 |
421 |
|
422 #define dqlsec_alloc_failed(ptr, stmt) \ |
|
423 if (!(ptr)) { \ |
|
424 (stmt)->errorcode = DAVQL_ERROR_OUT_OF_MEMORY; \ |
|
425 return 0; \ |
|
426 } |
|
427 #define dqlsec_malloc(stmt, ptr, type) ptr = malloc(sizeof(type)); \ |
|
428 dqlsec_alloc_failed(ptr, stmt); |
|
429 #define dqlsec_mallocz(stmt, ptr, type) ptr = calloc(1, sizeof(type)); \ |
|
430 dqlsec_alloc_failed(ptr, stmt); |
|
431 |
|
432 |
422 // special symbols are single tokens - the % sign MUST NOT be a special symbol |
433 // special symbols are single tokens - the % sign MUST NOT be a special symbol |
423 static const char *special_token_symbols = ",()+-*/&|^~=!<>"; |
434 static const char *special_token_symbols = ",()+-*/&|^~=!<>"; |
424 |
435 |
425 static _Bool iskeyword(DavQLToken *token) { |
436 static _Bool iskeyword(DavQLToken *token) { |
426 sstr_t keywords[] = {ST("get"), ST("set"), ST("from"), ST("at"), ST("as"), |
437 sstr_t keywords[] = {ST("get"), ST("set"), ST("from"), ST("at"), ST("as"), |
492 |
503 |
493 return ucx_list_append(tokenlist, token); |
504 return ucx_list_append(tokenlist, token); |
494 } |
505 } |
495 |
506 |
496 static UcxList* dav_parse_tokenize(sstr_t src) { |
507 static UcxList* dav_parse_tokenize(sstr_t src) { |
|
508 #define alloc_token token = malloc(sizeof(DavQLToken));\ |
|
509 if(!token) {ucx_list_free(tokens); return NULL;} |
497 UcxList *tokens = NULL; |
510 UcxList *tokens = NULL; |
498 |
511 |
499 DavQLToken *token = NULL; |
512 DavQLToken *token = NULL; |
500 char insequence = '\0'; |
513 char insequence = '\0'; |
501 for (size_t i = 0 ; i < src.length ; i++) { |
514 for (size_t i = 0 ; i < src.length ; i++) { |
511 insequence = src.ptr[i]; |
524 insequence = src.ptr[i]; |
512 // always create new token for quoted strings |
525 // always create new token for quoted strings |
513 if (token) { |
526 if (token) { |
514 tokens = dav_parse_add_token(tokens, token); |
527 tokens = dav_parse_add_token(tokens, token); |
515 } |
528 } |
516 token = malloc(sizeof(DavQLToken)); |
529 alloc_token |
517 token->value.ptr = src.ptr + i; |
530 token->value.ptr = src.ptr + i; |
518 token->value.length = 1; |
531 token->value.length = 1; |
519 } else { |
532 } else { |
520 // add other kind of quotes to token |
533 // add other kind of quotes to token |
521 token->value.length++; |
534 token->value.length++; |
533 if (token) { |
546 if (token) { |
534 tokens = dav_parse_add_token(tokens, token); |
547 tokens = dav_parse_add_token(tokens, token); |
535 token = NULL; |
548 token = NULL; |
536 } |
549 } |
537 // add special symbol as single token to list |
550 // add special symbol as single token to list |
538 token = malloc(sizeof(DavQLToken)); |
551 alloc_token |
539 token->value.ptr = src.ptr + i; |
552 token->value.ptr = src.ptr + i; |
540 token->value.length = 1; |
553 token->value.length = 1; |
541 tokens = dav_parse_add_token(tokens, token); |
554 tokens = dav_parse_add_token(tokens, token); |
542 // set tokenizer ready to read more tokens |
555 // set tokenizer ready to read more tokens |
543 token = NULL; |
556 token = NULL; |
544 } else { |
557 } else { |
545 // if this is a new token, create memory for it |
558 // if this is a new token, create memory for it |
546 if (!token) { |
559 if (!token) { |
547 token = malloc(sizeof(DavQLToken)); |
560 alloc_token |
548 token->value.ptr = src.ptr + i; |
561 token->value.ptr = src.ptr + i; |
549 token->value.length = 0; |
562 token->value.length = 0; |
550 } |
563 } |
551 // extend token length when reading more bytes |
564 // extend token length when reading more bytes |
552 token->value.length++; |
565 token->value.length++; |
555 |
568 |
556 if (token) { |
569 if (token) { |
557 tokens = dav_parse_add_token(tokens, token); |
570 tokens = dav_parse_add_token(tokens, token); |
558 } |
571 } |
559 |
572 |
560 DavQLToken *endtoken = malloc(sizeof(DavQLToken)); |
573 alloc_token |
561 endtoken->tokenclass = DAVQL_TOKEN_END; |
574 token->tokenclass = DAVQL_TOKEN_END; |
562 endtoken->value = S(""); |
575 token->value = S(""); |
563 return ucx_list_append(tokens, endtoken); |
576 return ucx_list_append(tokens, token); |
|
577 #undef alloc_token |
564 } |
578 } |
565 |
579 |
566 static void dav_free_expression(DavQLExpression *expr) { |
580 static void dav_free_expression(DavQLExpression *expr) { |
567 if (expr) { |
581 if (expr) { |
568 if (expr->left) { |
582 if (expr->left) { |
638 } |
652 } |
639 |
653 |
640 if (expr->op == DAVQL_NOOP) { |
654 if (expr->op == DAVQL_NOOP) { |
641 memcpy(expr, &left, sizeof(DavQLExpression)); |
655 memcpy(expr, &left, sizeof(DavQLExpression)); |
642 } else { |
656 } else { |
643 expr->left = malloc(sizeof(DavQLExpression)); |
657 dqlsec_malloc(stmt, expr->left, DavQLExpression); |
644 memcpy(expr->left, &left, sizeof(DavQLExpression)); |
658 memcpy(expr->left, &left, sizeof(DavQLExpression)); |
645 expr->right = malloc(sizeof(DavQLExpression)); |
659 dqlsec_malloc(stmt, expr->right, DavQLExpression); |
646 memcpy(expr->right, &right, sizeof(DavQLExpression)); |
660 memcpy(expr->right, &right, sizeof(DavQLExpression)); |
647 |
661 |
648 expr->srctext.ptr = expr->left->srctext.ptr; |
662 expr->srctext.ptr = expr->left->srctext.ptr; |
649 expr->srctext.length = |
663 expr->srctext.length = |
650 expr->right->srctext.ptr - |
664 expr->right->srctext.ptr - |
712 total_consumed++; |
726 total_consumed++; |
713 token = token->next; |
727 token = token->next; |
714 /* we have more arguments, so put the current argument to the |
728 /* we have more arguments, so put the current argument to the |
715 * left subtree and create a new node to the right |
729 * left subtree and create a new node to the right |
716 */ |
730 */ |
717 arglist->left = malloc(sizeof(DavQLExpression)); |
731 dqlsec_malloc(stmt, arglist->left, DavQLExpression); |
718 memcpy(arglist->left, &arg, sizeof(DavQLExpression)); |
732 memcpy(arglist->left, &arg, sizeof(DavQLExpression)); |
719 arglist->srctext.ptr = arg.srctext.ptr; |
733 arglist->srctext.ptr = arg.srctext.ptr; |
720 arglist->op = DAVQL_ARGLIST; |
734 arglist->op = DAVQL_ARGLIST; |
721 arglist->type = DAVQL_FUNCCALL; |
735 arglist->type = DAVQL_FUNCCALL; |
722 arglist->right = calloc(1, sizeof(DavQLExpression)); |
736 dqlsec_mallocz(stmt, arglist->right, DavQLExpression); |
723 arglist = arglist->right; |
737 arglist = arglist->right; |
724 } else { |
738 } else { |
725 // this was the last argument, so write it to the current node |
739 // this was the last argument, so write it to the current node |
726 memcpy(arglist, &arg, sizeof(DavQLExpression)); |
740 memcpy(arglist, &arg, sizeof(DavQLExpression)); |
727 consumed = 0; |
741 consumed = 0; |
747 token_is(token->next, DAVQL_TOKEN_OPENP)) { |
761 token_is(token->next, DAVQL_TOKEN_OPENP)) { |
748 |
762 |
749 expr->type = DAVQL_FUNCCALL; |
763 expr->type = DAVQL_FUNCCALL; |
750 expr->op = DAVQL_CALL; |
764 expr->op = DAVQL_CALL; |
751 |
765 |
752 expr->left = calloc(1, sizeof(DavQLExpression)); |
766 dqlsec_mallocz(stmt, expr->left, DavQLExpression); |
753 expr->left->type = DAVQL_IDENTIFIER; |
767 expr->left->type = DAVQL_IDENTIFIER; |
754 expr->left->srctext = token_sstr(token); |
768 expr->left->srctext = token_sstr(token); |
755 expr->right = NULL; |
769 expr->right = NULL; |
756 |
770 |
757 token = token->next->next; |
771 token = token->next->next; |
762 // if an error occurred while parsing the arglist, return now |
776 // if an error occurred while parsing the arglist, return now |
763 return 2; |
777 return 2; |
764 } |
778 } |
765 if (argtokens) { |
779 if (argtokens) { |
766 token = ucx_list_get(token, argtokens); |
780 token = ucx_list_get(token, argtokens); |
767 expr->right = malloc(sizeof(DavQLExpression)); |
781 dqlsec_malloc(stmt, expr->right, DavQLExpression); |
768 memcpy(expr->right, &arg, sizeof(DavQLExpression)); |
782 memcpy(expr->right, &arg, sizeof(DavQLExpression)); |
769 } else { |
783 } else { |
770 // arg list may be empty |
784 // arg list may be empty |
771 expr->right = NULL; |
785 expr->right = NULL; |
772 } |
786 } |
799 switch (*op) { |
813 switch (*op) { |
800 case '+': expr->op = DAVQL_ADD; break; |
814 case '+': expr->op = DAVQL_ADD; break; |
801 case '-': expr->op = DAVQL_SUB; break; |
815 case '-': expr->op = DAVQL_SUB; break; |
802 case '~': expr->op = DAVQL_NEG; break; |
816 case '~': expr->op = DAVQL_NEG; break; |
803 } |
817 } |
804 expr->left = calloc(1, sizeof(DavQLExpression)); |
818 dqlsec_mallocz(stmt, expr->left, DavQLExpression); |
805 atom = expr->left; |
819 atom = expr->left; |
806 total_consumed++; |
820 total_consumed++; |
807 token = token->next; |
821 token = token->next; |
808 } else { |
822 } else { |
809 dav_error_in_context(DAVQL_ERROR_INVALID_UNARY_OP, |
823 dav_error_in_context(DAVQL_ERROR_INVALID_UNARY_OP, |
896 static int dav_parse_named_field(DavQLStatement *stmt, UcxList *token, |
910 static int dav_parse_named_field(DavQLStatement *stmt, UcxList *token, |
897 DavQLField *field) { |
911 DavQLField *field) { |
898 int total_consumed = 0, consumed; |
912 int total_consumed = 0, consumed; |
899 |
913 |
900 // RULE: Expression, " as ", Identifier; |
914 // RULE: Expression, " as ", Identifier; |
901 DavQLExpression *expr = calloc(1, sizeof(DavQLExpression)); |
915 DavQLExpression *expr; |
|
916 dqlsec_mallocz(stmt, expr, DavQLExpression); |
902 consumed = dav_parse_expression(stmt, token, expr); |
917 consumed = dav_parse_expression(stmt, token, expr); |
903 if (stmt->errorcode) { |
918 if (stmt->errorcode) { |
904 dav_free_expression(expr); |
919 dav_free_expression(expr); |
905 return 0; |
920 return 0; |
906 } |
921 } |
937 |
952 |
938 static int dav_parse_fieldlist(DavQLStatement *stmt, UcxList *token) { |
953 static int dav_parse_fieldlist(DavQLStatement *stmt, UcxList *token) { |
939 |
954 |
940 // RULE: "-" |
955 // RULE: "-" |
941 if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "-")) { |
956 if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "-")) { |
942 DavQLField *field = malloc(sizeof(DavQLField)); |
957 DavQLField *field; |
943 field->expr = calloc(1, sizeof(DavQLExpression)); |
958 dqlsec_malloc(stmt, field, DavQLField); |
|
959 dqlsec_mallocz(stmt, field->expr, DavQLExpression); |
944 field->expr->type = DAVQL_IDENTIFIER; |
960 field->expr->type = DAVQL_IDENTIFIER; |
945 field->expr->srctext = field->name = token_sstr(token); |
961 field->expr->srctext = field->name = token_sstr(token); |
946 stmt->fields = ucx_list_append(stmt->fields, field); |
962 stmt->fields = ucx_list_append(stmt->fields, field); |
947 return 1; |
963 return 1; |
948 } |
964 } |
949 |
965 |
950 // RULE: "*", {",", NamedExpression} |
966 // RULE: "*", {",", NamedExpression} |
951 if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "*")) { |
967 if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "*")) { |
952 DavQLField *field = malloc(sizeof(DavQLField)); |
968 DavQLField *field; |
953 field->expr = calloc(1, sizeof(DavQLExpression)); |
969 dqlsec_malloc(stmt, field, DavQLField); |
|
970 dqlsec_mallocz(stmt, field->expr, DavQLExpression); |
954 field->expr->type = DAVQL_IDENTIFIER; |
971 field->expr->type = DAVQL_IDENTIFIER; |
955 field->expr->srctext = field->name = token_sstr(token); |
972 field->expr->srctext = field->name = token_sstr(token); |
956 stmt->fields = ucx_list_append(stmt->fields, field); |
973 stmt->fields = ucx_list_append(stmt->fields, field); |
957 |
974 |
958 int total_consumed = 0; |
975 int total_consumed = 0; |
965 if (token_is(token, DAVQL_TOKEN_COMMA)) { |
982 if (token_is(token, DAVQL_TOKEN_COMMA)) { |
966 total_consumed++; token = token->next; |
983 total_consumed++; token = token->next; |
967 DavQLField localfield; |
984 DavQLField localfield; |
968 consumed = dav_parse_named_field(stmt, token, &localfield); |
985 consumed = dav_parse_named_field(stmt, token, &localfield); |
969 if (!stmt->errorcode && consumed) { |
986 if (!stmt->errorcode && consumed) { |
970 DavQLField *field = malloc(sizeof(DavQLField)); |
987 DavQLField *field; |
|
988 dqlsec_malloc(stmt, field, DavQLField); |
971 memcpy(field, &localfield, sizeof(DavQLField)); |
989 memcpy(field, &localfield, sizeof(DavQLField)); |
972 stmt->fields = ucx_list_append(stmt->fields, field); |
990 stmt->fields = ucx_list_append(stmt->fields, field); |
973 } |
991 } |
974 } else { |
992 } else { |
975 consumed = 0; |
993 consumed = 0; |
985 do { |
1003 do { |
986 // RULE: NamedField | Identifier |
1004 // RULE: NamedField | Identifier |
987 DavQLField localfield; |
1005 DavQLField localfield; |
988 consumed = dav_parse_named_field(stmt, token, &localfield); |
1006 consumed = dav_parse_named_field(stmt, token, &localfield); |
989 if (consumed) { |
1007 if (consumed) { |
990 DavQLField *field = malloc(sizeof(DavQLField)); |
1008 DavQLField *field; |
|
1009 dqlsec_malloc(stmt, field, DavQLField); |
991 memcpy(field, &localfield, sizeof(DavQLField)); |
1010 memcpy(field, &localfield, sizeof(DavQLField)); |
992 stmt->fields = ucx_list_append(stmt->fields, field); |
1011 stmt->fields = ucx_list_append(stmt->fields, field); |
993 token = ucx_list_get(token, consumed); |
1012 token = ucx_list_get(token, consumed); |
994 total_consumed += consumed; |
1013 total_consumed += consumed; |
995 } else if (token_is(token, DAVQL_TOKEN_IDENTIFIER) |
1014 } else if (token_is(token, DAVQL_TOKEN_IDENTIFIER) |
996 // look ahead, if the field is JUST the identifier |
1015 // look ahead, if the field is JUST the identifier |
997 && (token_is(token->next, DAVQL_TOKEN_COMMA) || |
1016 && (token_is(token->next, DAVQL_TOKEN_COMMA) || |
998 tokenvalue_is(token->next, "from"))) { |
1017 tokenvalue_is(token->next, "from"))) { |
999 |
1018 |
1000 DavQLField *field = malloc(sizeof(DavQLField)); |
1019 DavQLField *field; |
1001 field->expr = calloc(1, sizeof(DavQLExpression)); |
1020 dqlsec_malloc(stmt, field, DavQLField); |
|
1021 dqlsec_mallocz(stmt, field->expr, DavQLExpression); |
1002 field->expr->type = DAVQL_IDENTIFIER; |
1022 field->expr->type = DAVQL_IDENTIFIER; |
1003 field->expr->srctext = field->name = token_sstr(token); |
1023 field->expr->srctext = field->name = token_sstr(token); |
1004 stmt->fields = ucx_list_append(stmt->fields, field); |
1024 stmt->fields = ucx_list_append(stmt->fields, field); |
1005 |
1025 |
1006 consumed = 1; |
1026 consumed = 1; |
1059 total_consumed++; |
1079 total_consumed++; |
1060 token = token->next; |
1080 token = token->next; |
1061 if (token_is(token, DAVQL_TOKEN_STRING)) { |
1081 if (token_is(token, DAVQL_TOKEN_STRING)) { |
1062 expr->op = tokenvalue_is(optok, "like") ? |
1082 expr->op = tokenvalue_is(optok, "like") ? |
1063 DAVQL_LIKE : DAVQL_UNLIKE; |
1083 DAVQL_LIKE : DAVQL_UNLIKE; |
1064 expr->left = malloc(sizeof(DavQLExpression)); |
1084 dqlsec_malloc(stmt, expr->left, DavQLExpression); |
1065 memcpy(expr->left, &bexpr, sizeof(DavQLExpression)); |
1085 memcpy(expr->left, &bexpr, sizeof(DavQLExpression)); |
1066 expr->right = calloc(1, sizeof(DavQLExpression)); |
1086 dqlsec_mallocz(stmt, expr->right, DavQLExpression); |
1067 expr->right->type = DAVQL_STRING; |
1087 expr->right->type = DAVQL_STRING; |
1068 expr->right->srctext = token_sstr(token); |
1088 expr->right->srctext = token_sstr(token); |
1069 |
1089 |
1070 return total_consumed + 1; |
1090 return total_consumed + 1; |
1071 } else { |
1091 } else { |
1116 stmt, token); |
1136 stmt, token); |
1117 return 0; |
1137 return 0; |
1118 } |
1138 } |
1119 |
1139 |
1120 total_consumed += consumed; |
1140 total_consumed += consumed; |
1121 expr->left = malloc(sizeof(DavQLExpression)); |
1141 dqlsec_malloc(stmt, expr->left, DavQLExpression); |
1122 memcpy(expr->left, &bexpr, sizeof(DavQLExpression)); |
1142 memcpy(expr->left, &bexpr, sizeof(DavQLExpression)); |
1123 expr->right = malloc(sizeof(DavQLExpression)); |
1143 dqlsec_malloc(stmt, expr->right, DavQLExpression); |
1124 memcpy(expr->right, &rexpr, sizeof(DavQLExpression)); |
1144 memcpy(expr->right, &rexpr, sizeof(DavQLExpression)); |
1125 |
1145 |
1126 return total_consumed; |
1146 return total_consumed; |
1127 } |
1147 } |
1128 // RULE: FunctionCall | Identifier; |
1148 // RULE: FunctionCall | Identifier; |
1140 |
1160 |
1141 // RULE: "not ", LogicalExpression |
1161 // RULE: "not ", LogicalExpression |
1142 if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "not")) { |
1162 if (token_is(token, DAVQL_TOKEN_OPERATOR) && tokenvalue_is(token, "not")) { |
1143 expr->type = DAVQL_LOGICAL; |
1163 expr->type = DAVQL_LOGICAL; |
1144 expr->op = DAVQL_NOT; |
1164 expr->op = DAVQL_NOT; |
1145 expr->left = calloc(1, sizeof(DavQLExpression)); |
1165 dqlsec_mallocz(stmt, expr->left, DavQLExpression); |
1146 expr->srctext = token_sstr(token); |
1166 expr->srctext = token_sstr(token); |
1147 |
1167 |
1148 token = token->next; |
1168 token = token->next; |
1149 int consumed = dav_parse_bool_expr(stmt, token, expr->left); |
1169 int consumed = dav_parse_bool_expr(stmt, token, expr->left); |
1150 if (stmt->errorcode) { |
1170 if (stmt->errorcode) { |
1241 return 0; |
1261 return 0; |
1242 } |
1262 } |
1243 total_consumed += consumed; |
1263 total_consumed += consumed; |
1244 token = ucx_list_get(token, consumed); |
1264 token = ucx_list_get(token, consumed); |
1245 |
1265 |
1246 expr->left = malloc(sizeof(DavQLExpression)); |
1266 dqlsec_malloc(stmt, expr->left, DavQLExpression); |
1247 memcpy(expr->left, &left, sizeof(DavQLExpression)); |
1267 memcpy(expr->left, &left, sizeof(DavQLExpression)); |
1248 expr->right = malloc(sizeof(DavQLExpression)); |
1268 dqlsec_malloc(stmt, expr->right, DavQLExpression); |
1249 memcpy(expr->right, &right, sizeof(DavQLExpression)); |
1269 memcpy(expr->right, &right, sizeof(DavQLExpression)); |
1250 } |
1270 } |
1251 } else { |
1271 } else { |
1252 memcpy(expr, &left, sizeof(DavQLExpression)); |
1272 memcpy(expr, &left, sizeof(DavQLExpression)); |
1253 } |
1273 } |
1261 |
1281 |
1262 return total_consumed; |
1282 return total_consumed; |
1263 } |
1283 } |
1264 |
1284 |
1265 static int dav_parse_where_clause(DavQLStatement *stmt, UcxList *token) { |
1285 static int dav_parse_where_clause(DavQLStatement *stmt, UcxList *token) { |
1266 stmt->where = calloc(1, sizeof(DavQLExpression)); |
1286 dqlsec_mallocz(stmt, stmt->where, DavQLExpression); |
1267 |
1287 |
1268 return dav_parse_logical_expr(stmt, token, stmt->where); |
1288 return dav_parse_logical_expr(stmt, token, stmt->where); |
1269 } |
1289 } |
1270 |
1290 |
1271 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) { |
1291 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) { |
1279 token = token->next; total_consumed++; |
1299 token = token->next; total_consumed++; |
1280 if (tokenvalue_is(token, "infinity")) { |
1300 if (tokenvalue_is(token, "infinity")) { |
1281 stmt->depth = DAV_DEPTH_INFINITY; |
1301 stmt->depth = DAV_DEPTH_INFINITY; |
1282 token = token->next; total_consumed++; |
1302 token = token->next; total_consumed++; |
1283 } else { |
1303 } else { |
1284 DavQLExpression *depthexpr = calloc(1, sizeof(DavQLExpression)); |
1304 DavQLExpression *depthexpr; |
|
1305 dqlsec_mallocz(stmt, depthexpr, DavQLExpression); |
1285 |
1306 |
1286 int consumed = dav_parse_expression(stmt, token, depthexpr); |
1307 int consumed = dav_parse_expression(stmt, token, depthexpr); |
1287 |
1308 |
1288 if (consumed) { |
1309 if (consumed) { |
1289 if (depthexpr->type == DAVQL_NUMBER) { |
1310 if (depthexpr->type == DAVQL_NUMBER) { |
1290 if (depthexpr->srctext.ptr[0] == '%') { |
1311 if (depthexpr->srctext.ptr[0] == '%') { |
1291 stmt->depth = DAV_DEPTH_PLACEHOLDER; |
1312 stmt->depth = DAV_DEPTH_PLACEHOLDER; |
1292 } else { |
1313 } else { |
1293 sstr_t depthstr = depthexpr->srctext; |
1314 sstr_t depthstr = depthexpr->srctext; |
1294 char *conv = malloc(depthstr.length+1); |
1315 char *conv = malloc(depthstr.length+1); |
|
1316 if (!conv) { |
|
1317 dav_free_expression(depthexpr); |
|
1318 stmt->errorcode = DAVQL_ERROR_OUT_OF_MEMORY; |
|
1319 return 0; |
|
1320 } |
1295 char *chk; |
1321 char *chk; |
1296 memcpy(conv, depthstr.ptr, depthstr.length); |
1322 memcpy(conv, depthstr.ptr, depthstr.length); |
1297 conv[depthstr.length] = '\0'; |
1323 conv[depthstr.length] = '\0'; |
1298 stmt->depth = strtol(conv, &chk, 10); |
1324 stmt->depth = strtol(conv, &chk, 10); |
1299 if (*chk || stmt->depth < -1) { |
1325 if (*chk || stmt->depth < -1) { |
1332 dav_error_in_context(DAVQL_ERROR_INVALID_ORDER_CRITERION, |
1358 dav_error_in_context(DAVQL_ERROR_INVALID_ORDER_CRITERION, |
1333 _error_invalid_order_criterion, stmt, token); |
1359 _error_invalid_order_criterion, stmt, token); |
1334 return 0; |
1360 return 0; |
1335 } |
1361 } |
1336 |
1362 |
1337 crit->column = malloc(sizeof(DavQLExpression)); |
1363 dqlsec_malloc(stmt, crit->column, DavQLExpression); |
1338 memcpy(crit->column, &expr, sizeof(DavQLExpression)); |
1364 memcpy(crit->column, &expr, sizeof(DavQLExpression)); |
1339 |
1365 |
1340 token = ucx_list_get(token, consumed); |
1366 token = ucx_list_get(token, consumed); |
1341 if (token_is(token, DAVQL_TOKEN_KEYWORD) && ( |
1367 if (token_is(token, DAVQL_TOKEN_KEYWORD) && ( |
1342 tokenvalue_is(token, "asc") || tokenvalue_is(token, "desc"))) { |
1368 tokenvalue_is(token, "asc") || tokenvalue_is(token, "desc"))) { |
1368 return 0; |
1394 return 0; |
1369 } |
1395 } |
1370 token = ucx_list_get(token, consumed); |
1396 token = ucx_list_get(token, consumed); |
1371 total_consumed += consumed; |
1397 total_consumed += consumed; |
1372 |
1398 |
1373 DavQLOrderCriterion *criterion = malloc(sizeof(DavQLOrderCriterion)); |
1399 DavQLOrderCriterion *criterion; |
|
1400 dqlsec_malloc(stmt, criterion, DavQLOrderCriterion); |
1374 memcpy(criterion, &crit, sizeof(DavQLOrderCriterion)); |
1401 memcpy(criterion, &crit, sizeof(DavQLOrderCriterion)); |
1375 stmt->orderby = ucx_list_append(stmt->orderby, criterion); |
1402 stmt->orderby = ucx_list_append(stmt->orderby, criterion); |
1376 |
1403 |
1377 if (token_is(token, DAVQL_TOKEN_COMMA)) { |
1404 if (token_is(token, DAVQL_TOKEN_COMMA)) { |
1378 total_consumed++; |
1405 total_consumed++; |
1538 stmt->type = DAVQL_ERROR; |
1565 stmt->type = DAVQL_ERROR; |
1539 stmt->errorcode = DAVQL_ERROR_INVALID; |
1566 stmt->errorcode = DAVQL_ERROR_INVALID; |
1540 stmt->errormessage = strdup(_error_invalid); |
1567 stmt->errormessage = strdup(_error_invalid); |
1541 } |
1568 } |
1542 |
1569 |
1543 if (stmt->errorcode = DAVQL_ERROR_OUT_OF_MEMORY) { |
1570 if (stmt->errorcode == DAVQL_ERROR_OUT_OF_MEMORY) { |
1544 stmt->type = DAVQL_ERROR; |
1571 stmt->type = DAVQL_ERROR; |
1545 stmt->errormessage = oommsg; |
1572 stmt->errormessage = oommsg; |
1546 } else { |
1573 } else { |
1547 free(oommsg); |
1574 free(oommsg); |
1548 } |
1575 } |