libidav/davqlparser.c

changeset 97
f82cb65a78ec
parent 96
896022673e0e
child 98
237844f263b4
equal deleted inserted replaced
96:896022673e0e 97:f82cb65a78ec
496 } 496 }
497 return _step_FROM_; 497 return _step_FROM_;
498 } 498 }
499 } 499 }
500 500
501 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) { 501 struct with_parser_state {
502 sstr_t tokendata = *token_sstr(token);
503
504 /* 502 /*
505 * 0: key 503 * 0: key
506 * 1: = 504 * 1: =
507 * 2: value 505 * 2: value
508 * 3: comma or new clause 506 * 3: comma or new clause
509 */ 507 */
510 static int parsestate = 0; 508 int step;
511
512 /* 509 /*
513 * 1: depth 510 * 1: depth
514 */ 511 */
515 static int key = 0; 512 int key;
516 static int keymask = 0; 513 int keymask;
517 514 };
518 switch (parsestate) { 515
516 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token,
517 struct with_parser_state *state) {
518 sstr_t tokendata = *token_sstr(token);
519
520 switch (state->step) {
519 case 0: 521 case 0:
520 if (!sstrcasecmp(tokendata, S("depth"))) { 522 if (!sstrcasecmp(tokendata, S("depth"))) {
521 key = 1; 523 state->key = 1;
522 parsestate = 1; 524 state->step = 1;
523 } else { 525 } else {
524 stmt->errorcode = DAVQL_ERROR_UNKNOWN_ATTRIBUTE; 526 stmt->errorcode = DAVQL_ERROR_UNKNOWN_ATTRIBUTE;
525 stmt->errormessage = ucx_sprintf(_unknown_attribute, 527 stmt->errormessage = ucx_sprintf(_unknown_attribute,
526 sfmtarg(tokendata)).ptr; 528 sfmtarg(tokendata)).ptr;
527 break; 529 break;
528 } 530 }
529 if (keymask & key) { 531 if (state->keymask & state->key) {
530 stmt->errorcode = DAVQL_ERROR_DUPLICATED_ATTRIBUTE; 532 stmt->errorcode = DAVQL_ERROR_DUPLICATED_ATTRIBUTE;
531 stmt->errormessage = ucx_sprintf(_duplicated_attribute, 533 stmt->errormessage = ucx_sprintf(_duplicated_attribute,
532 sfmtarg(tokendata)).ptr; 534 sfmtarg(tokendata)).ptr;
533 } else { 535 } else {
534 keymask |= key; 536 state->keymask |= state->key;
535 } 537 }
536 return _step_WITH_; // continue parsing WITH clause 538 return _step_WITH_; // continue parsing WITH clause
537 case 1: 539 case 1:
538 if (sstrcmp(tokendata, S("="))) { 540 if (sstrcmp(tokendata, S("="))) {
539 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN; 541 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
540 stmt->errormessage = ucx_sprintf(_expected_token, 542 stmt->errormessage = ucx_sprintf(_expected_token,
541 "=", sfmtarg(tokendata)).ptr; 543 "=", sfmtarg(tokendata)).ptr;
542 } else { 544 } else {
543 parsestate = 2; 545 state->step = 2;
544 } 546 }
545 return _step_WITH_; // continue parsing WITH clause 547 return _step_WITH_; // continue parsing WITH clause
546 case 2: 548 case 2:
547 switch (key) { 549 switch (state->key) {
548 case 1: /* depth */ 550 case 1: /* depth */
549 if (!sstrcasecmp(tokendata, S("infinity"))) { 551 if (!sstrcasecmp(tokendata, S("infinity"))) {
550 stmt->depth = DAV_DEPTH_INFINITY; 552 stmt->depth = DAV_DEPTH_INFINITY;
551 } else { 553 } else {
552 DavQLExpression *depthexpr = 554 DavQLExpression *depthexpr =
575 577
576 dav_free_expression(depthexpr); 578 dav_free_expression(depthexpr);
577 } 579 }
578 break; 580 break;
579 } 581 }
580 parsestate = 3; 582 state->step = 3;
581 return _step_WITH_; // continue parsing WITH clause 583 return _step_WITH_; // continue parsing WITH clause
582 case 3: 584 case 3:
583 // a with clause may be continued with a comma 585 // a with clause may be continued with a comma
584 // or another clause may follow 586 // or another clause may follow
585 if (!sstrcmp(tokendata, S(","))) { 587 if (!sstrcmp(tokendata, S(","))) {
586 parsestate = 0; // reset clause parser 588 state->step = 0; // reset clause parser
587 return _step_WITH_; 589 return _step_WITH_;
588 } else if (!sstrcasecmp(tokendata, S("where"))) { 590 } else if (!sstrcasecmp(tokendata, S("where"))) {
589 return _step_WHERE_; 591 return _step_WHERE_;
590 } else if (!sstrcasecmp(tokendata, S("order"))) { 592 } else if (!sstrcasecmp(tokendata, S("order"))) {
591 return _step_ORDER_BY_; 593 return _step_ORDER_BY_;
599 stmt->errormessage = strdup(_parser_state); 601 stmt->errormessage = strdup(_parser_state);
600 return 0; 602 return 0;
601 } 603 }
602 } 604 }
603 605
604 static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token) { 606 struct orderby_parser_state {
605
606 sstr_t tokendata = *token_sstr(token);
607 /* 607 /*
608 * 0: expect by keyword 608 * 0: expect by keyword
609 * 1: expect identifier / number 609 * 1: expect identifier / number
610 * 2: expect asc / desc or comma 610 * 2: expect asc / desc or comma
611 * 3: expect comma 611 * 3: expect comma
612 */ 612 */
613 static int state = 0; 613 int step;
614 static DavQLOrderCriterion *crit = NULL; 614 DavQLOrderCriterion *crit;
615 615 };
616 switch (state) { 616
617 static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token,
618 struct orderby_parser_state *state) {
619
620 sstr_t tokendata = *token_sstr(token);
621
622 switch (state->step) {
617 case 0: 623 case 0:
618 if (!sstrcasecmp(tokendata, S("by"))) { 624 if (!sstrcasecmp(tokendata, S("by"))) {
619 state++; 625 state->step++;
620 } else { 626 } else {
621 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN; 627 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
622 stmt->errormessage = ucx_sprintf(_expected_by, 628 stmt->errormessage = ucx_sprintf(_expected_by,
623 sfmtarg(tokendata)).ptr; 629 sfmtarg(tokendata)).ptr;
624 } 630 }
625 return _step_ORDER_BY_; 631 return _step_ORDER_BY_;
626 case 1: 632 case 1:
627 crit = malloc(sizeof(DavQLOrderCriterion)); 633 state->crit = malloc(sizeof(DavQLOrderCriterion));
628 crit->column = dav_parse_expression(stmt, token, 1); 634 state->crit->column = dav_parse_expression(stmt, token, 1);
629 crit->descending = 0; 635 state->crit->descending = 0;
630 636
631 if (!crit->column || ( 637 if (!state->crit->column || (
632 crit->column->type != DAVQL_NUMBER && 638 state->crit->column->type != DAVQL_NUMBER &&
633 crit->column->type != DAVQL_IDENTIFIER)) { 639 state->crit->column->type != DAVQL_IDENTIFIER)) {
634 free(crit); 640 free(state->crit);
635 dav_error_in_context(DAVQL_ERROR_IDORNUM_EXPECTED, 641 dav_error_in_context(DAVQL_ERROR_IDORNUM_EXPECTED,
636 _idornum_expected, stmt, token); 642 _idornum_expected, stmt, token);
637 } else { 643 } else {
638 stmt->orderby = ucx_list_append(stmt->orderby, crit); 644 stmt->orderby = ucx_list_append(stmt->orderby, state->crit);
639 } 645 }
640 646
641 // continue parsing clause, if more tokens available 647 // continue parsing clause, if more tokens available
642 state++; 648 state->step++;
643 return _step_ORDER_BYopt_; 649 return _step_ORDER_BYopt_;
644 case 2: 650 case 2:
645 if (!sstrcasecmp(tokendata, S("desc"))) { 651 if (!sstrcasecmp(tokendata, S("desc"))) {
646 crit->descending = 1; 652 state->crit->descending = 1;
647 } else if (!sstrcasecmp(tokendata, S("asc"))) { 653 } else if (!sstrcasecmp(tokendata, S("asc"))) {
648 crit->descending = 0; 654 state->crit->descending = 0;
649 } else if (!sstrcmp(tokendata, S(","))) { 655 } else if (!sstrcmp(tokendata, S(","))) {
650 state = 1; // reset clause parser 656 state->step = 1; // reset clause parser
651 return _step_ORDER_BY_; // statement must not end now 657 return _step_ORDER_BY_; // statement must not end now
652 } else { 658 } else {
653 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN, 659 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN,
654 _unexpected_token, stmt, token); 660 _unexpected_token, stmt, token);
655 return 0; 661 return 0;
657 // continue parsing clause, if more tokens available 663 // continue parsing clause, if more tokens available
658 state++; 664 state++;
659 return _step_ORDER_BYopt_; 665 return _step_ORDER_BYopt_;
660 case 3: 666 case 3:
661 if (!sstrcmp(tokendata, S(","))) { 667 if (!sstrcmp(tokendata, S(","))) {
662 state = 1; // reset clause parser 668 state->step = 1; // reset clause parser
663 return _step_ORDER_BY_; // statement must not end now 669 return _step_ORDER_BY_; // statement must not end now
664 } else { 670 } else {
665 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN, 671 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN,
666 _unexpected_token, stmt, token); 672 _unexpected_token, stmt, token);
667 return 0; 673 return 0;
680 686
681 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) { 687 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) {
682 stmt->type = DAVQL_GET; 688 stmt->type = DAVQL_GET;
683 689
684 int step = _step_fieldlist_; 690 int step = _step_fieldlist_;
691
692 struct with_parser_state state_with;
693 memset(&state_with, 0, sizeof(struct with_parser_state));
694 struct orderby_parser_state state_orderby;
695 memset(&state_orderby, 0, sizeof(struct orderby_parser_state));
685 696
686 // Variables for token sublists for expressions 697 // Variables for token sublists for expressions
687 // TODO: this is deprecated and won't work with function calls 698 // TODO: this is deprecated and won't work with function calls
688 UcxList *exprstart = NULL; 699 UcxList *exprstart = NULL;
689 size_t exprlen = 0; 700 size_t exprlen = 0;
731 step = dav_parse_from(stmt, token); 742 step = dav_parse_from(stmt, token);
732 break; 743 break;
733 } 744 }
734 // with clause 745 // with clause
735 case _step_WITH_: { 746 case _step_WITH_: {
736 step = dav_parse_with_clause(stmt, token); 747 step = dav_parse_with_clause(stmt, token, &state_with);
737 break; 748 break;
738 } 749 }
739 // where clause 750 // where clause
740 case _step_WHERE_: 751 case _step_WHERE_:
741 // TODO: implement 752 // TODO: implement
742 step = _step_end_; 753 step = _step_end_;
743 break; 754 break;
744 // order by clause 755 // order by clause
745 case _step_ORDER_BY_: 756 case _step_ORDER_BY_:
746 case _step_ORDER_BYopt_: 757 case _step_ORDER_BYopt_:
747 step = dav_parse_orderby_clause(stmt, token); 758 step = dav_parse_orderby_clause(stmt, token, &state_orderby);
748 break; 759 break;
749 default: 760 default:
750 stmt->errorcode = DAVQL_ERROR_INVALID; 761 stmt->errorcode = DAVQL_ERROR_INVALID;
751 stmt->errormessage = strdup(_parser_state); 762 stmt->errormessage = strdup(_parser_state);
752 } 763 }

mercurial