| 167 } |
167 } |
| 168 } |
168 } |
| 169 |
169 |
| 170 static void dav_debug_ql_expr_print(DavQLExpression *expr) { |
170 static void dav_debug_ql_expr_print(DavQLExpression *expr) { |
| 171 if (dav_debug_ql_expr_selected(expr)) { |
171 if (dav_debug_ql_expr_selected(expr)) { |
| 172 cxstring empty = CX_STR("(empty)"); |
172 cxstring empty = cx_str("(empty)"); |
| 173 printf( |
173 printf( |
| 174 "Text: %.*s\nType: %s\nOperator: %s\n", |
174 "Text: %.*s\nType: %s\nOperator: %s\n", |
| 175 sfmtarg(expr->srctext), |
175 sfmtarg(expr->srctext), |
| 176 _map_exprtype(expr->type), |
176 _map_exprtype(expr->type), |
| 177 _map_operator(expr->op)); |
177 _map_operator(expr->op)); |
| 420 static void dav_error_in_context(int errorcode, const char *errormsg, |
420 static void dav_error_in_context(int errorcode, const char *errormsg, |
| 421 DavQLStatement *stmt, DavQLToken *token) { |
421 DavQLStatement *stmt, DavQLToken *token) { |
| 422 |
422 |
| 423 // we try to achieve two things: get as many information as possible |
423 // we try to achieve two things: get as many information as possible |
| 424 // and recover the concrete source string (and not the token strings) |
424 // and recover the concrete source string (and not the token strings) |
| 425 cxstring emptystring = CX_STR(""); |
425 cxstring emptystring = cx_str(""); |
| 426 cxstring prev = token->prev ? (token->prev->prev ? |
426 cxstring prev = token->prev ? (token->prev->prev ? |
| 427 token_sstr(token->prev->prev) : token_sstr(token->prev)) |
427 token_sstr(token->prev->prev) : token_sstr(token->prev)) |
| 428 : emptystring; |
428 : emptystring; |
| 429 cxstring tokenstr = token_sstr(token); |
429 cxstring tokenstr = token_sstr(token); |
| 430 cxstring next = token->next ? (token->next->next ? |
430 cxstring next = token->next ? (token->next->next ? |
| 455 |
455 |
| 456 // special symbols are single tokens - the % sign MUST NOT be a special symbol |
456 // special symbols are single tokens - the % sign MUST NOT be a special symbol |
| 457 static const char *special_token_symbols = ",()+-*/&|^~=!<>"; |
457 static const char *special_token_symbols = ",()+-*/&|^~=!<>"; |
| 458 |
458 |
| 459 static _Bool iskeyword(DavQLToken *token) { |
459 static _Bool iskeyword(DavQLToken *token) { |
| 460 cxstring keywords[] ={CX_STR("select"), CX_STR("set"), CX_STR("from"), CX_STR("at"), CX_STR("as"), |
460 cxstring keywords[] ={cx_str("select"), cx_str("set"), cx_str("from"), cx_str("at"), cx_str("as"), |
| 461 CX_STR("where"), CX_STR("anywhere"), CX_STR("like"), CX_STR("unlike"), CX_STR("and"), |
461 cx_str("where"), cx_str("anywhere"), cx_str("like"), cx_str("unlike"), cx_str("and"), |
| 462 CX_STR("or"), CX_STR("not"), CX_STR("xor"), CX_STR("with"), CX_STR("infinity"), |
462 cx_str("or"), cx_str("not"), cx_str("xor"), cx_str("with"), cx_str("infinity"), |
| 463 CX_STR("order"), CX_STR("by"), CX_STR("asc"), CX_STR("desc") |
463 cx_str("order"), cx_str("by"), cx_str("asc"), cx_str("desc") |
| 464 }; |
464 }; |
| 465 for (int i = 0 ; i < sizeof(keywords)/sizeof(cxstring) ; i++) { |
465 for (int i = 0 ; i < sizeof(keywords)/sizeof(cxstring) ; i++) { |
| 466 if (!cx_strcasecmp(token->value, keywords[i])) { |
466 if (!cx_strcasecmp(token->value, keywords[i])) { |
| 467 return 1; |
467 return 1; |
| 468 } |
468 } |
| 469 } |
469 } |
| 470 return 0; |
470 return 0; |
| 471 } |
471 } |
| 472 |
472 |
| 473 static _Bool islongoperator(DavQLToken *token) { |
473 static _Bool islongoperator(DavQLToken *token) { |
| 474 cxstring operators[] = {CX_STR("and"), CX_STR("or"), CX_STR("not"), CX_STR("xor"), |
474 cxstring operators[] = {cx_str("and"), cx_str("or"), cx_str("not"), cx_str("xor"), |
| 475 CX_STR("like"), CX_STR("unlike") |
475 cx_str("like"), cx_str("unlike") |
| 476 }; |
476 }; |
| 477 for (int i = 0 ; i < sizeof(operators)/sizeof(cxstring) ; i++) { |
477 for (int i = 0 ; i < sizeof(operators)/sizeof(cxstring) ; i++) { |
| 478 if (!cx_strcasecmp(token->value, operators[i])) { |
478 if (!cx_strcasecmp(token->value, operators[i])) { |
| 479 return 1; |
479 return 1; |
| 480 } |
480 } |
| 643 add_token(); |
643 add_token(); |
| 644 } |
644 } |
| 645 |
645 |
| 646 alloc_token(); |
646 alloc_token(); |
| 647 token->tokenclass = DAVQL_TOKEN_END; |
647 token->tokenclass = DAVQL_TOKEN_END; |
| 648 token->value = CX_STR(""); |
648 token->value = cx_str(""); |
| 649 |
649 |
| 650 cx_linked_list_add((void**)&tokens_begin, (void**)&tokens_end, offsetof(DavQLToken, prev), offsetof(DavQLToken, next), token); |
650 cx_linked_list_add((void**)&tokens_begin, (void**)&tokens_end, offsetof(DavQLToken, prev), offsetof(DavQLToken, next), token); |
| 651 return tokens_begin; |
651 return tokens_begin; |
| 652 #undef alloc_token |
652 #undef alloc_token |
| 653 #undef add_token |
653 #undef add_token |
| 743 return total_consumed; |
743 return total_consumed; |
| 744 } |
744 } |
| 745 |
745 |
| 746 static void fmt_args_add(DavQLStatement *stmt, void *data) { |
746 static void fmt_args_add(DavQLStatement *stmt, void *data) { |
| 747 if(!stmt->args) { |
747 if(!stmt->args) { |
| 748 stmt->args = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
748 stmt->args = cxLinkedListCreate(NULL, CX_STORE_POINTERS); |
| 749 } |
749 } |
| 750 cxListAdd(stmt->args, data); |
750 cxListAdd(stmt->args, data); |
| 751 } |
751 } |
| 752 |
752 |
| 753 static void dav_add_fmt_args(DavQLStatement *stmt, cxstring str) { |
753 static void dav_add_fmt_args(DavQLStatement *stmt, cxstring str) { |