libidav/davqlparser.c

changeset 122
9a016d5fa9e7
parent 121
eea36bf5ffe2
child 125
5e2576b08680
equal deleted inserted replaced
121:eea36bf5ffe2 122:9a016d5fa9e7
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 }

mercurial