libidav/davqlparser.c

changeset 89
785f6007a0c1
parent 88
4d6b03bd7034
child 90
46971430650b
equal deleted inserted replaced
88:4d6b03bd7034 89:785f6007a0c1
243 // ------------------------------------------------------------------------ 243 // ------------------------------------------------------------------------
244 244
245 #define _unexpected_end_msg "unexpected end of statement" 245 #define _unexpected_end_msg "unexpected end of statement"
246 #define _invalid_msg "invalid statement" 246 #define _invalid_msg "invalid statement"
247 #define _unexpected_token "unexpected token (%.*s [->]%.*s %.*s)" 247 #define _unexpected_token "unexpected token (%.*s [->]%.*s %.*s)"
248 #define _expected_token "expected token '%s' before '%.*s'"
248 #define _missing_quote "missing closing quote symbol (%.*s)" 249 #define _missing_quote "missing closing quote symbol (%.*s)"
250 #define _parser_state "parser reached invalid state"
251 #define _unknown_attribute "unknown attribute '%.*s'"
252 #define _invalid_depth "invalid depth"
249 253
250 static UcxList* dav_parse_tokenize(sstr_t src) { 254 static UcxList* dav_parse_tokenize(sstr_t src) {
251 UcxList *tokens = NULL; 255 UcxList *tokens = NULL;
252 256
253 // Delimiters: whitespace and dead whitespace around commas 257 // Delimiters: whitespace and dead whitespace around commas
408 stmt->type = DAVQL_GET; 412 stmt->type = DAVQL_GET;
409 413
410 /* 414 /*
411 * 10: field list 415 * 10: field list
412 * 20: FROM clause 416 * 20: FROM clause
413 * 520: expecting WHERE or WITH clause 417 * 530: expecting WHERE or WITH clause
414 * 30: WHERE clause 418 * 30: WHERE clause
415 * 530: expecting WITH clause 419 * 540: expecting WITH clause
416 * 40: WITH clause 420 * 40: WITH clause
417 * 500: ready to quit 421 * 500: expect end
418 * 999: error
419 * 422 *
420 */ 423 */
421 int step = 10; 424 int step = 10;
422 425
423 // Variables for token sublists for expressions 426 // Variables for token sublists for expressions
431 } 434 }
432 435
433 sstr_t tokendata = *token_sstr(token); 436 sstr_t tokendata = *token_sstr(token);
434 437
435 switch (step) { 438 switch (step) {
439 // too much input data
440 case 500:
441 dav_parse_unexpected_token(stmt, token);
442 goto ultrabreak;
436 // optional clauses 443 // optional clauses
437 case 520: 444 case 530:
438 if (!sstrcasecmp(tokendata, S("where"))) { 445 if (!sstrcasecmp(tokendata, S("where"))) {
439 step = 30; 446 step = 30;
440 } 447 }
441 /* no break and no else*/ 448 /* no break and no else*/
442 case 530: 449 case 540:
443 if (!sstrcasecmp(tokendata, S("with"))) { 450 if (!sstrcasecmp(tokendata, S("with"))) {
444 step = 40; 451 step = 40;
445 } else { 452 } else {
446 dav_parse_unexpected_token(stmt, token); 453 dav_parse_unexpected_token(stmt, token);
447 goto ultrabreak; 454 goto ultrabreak;
477 // from clause 484 // from clause
478 case 20: { 485 case 20: {
479 DavQLExpression *expr = dav_parse_expression(stmt, token, 1); 486 DavQLExpression *expr = dav_parse_expression(stmt, token, 1);
480 stmt->path = expr->srctext; 487 stmt->path = expr->srctext;
481 dav_free_expression(expr); 488 dav_free_expression(expr);
482 step = 520; 489 step = 530;
483 break; 490 break;
484 } 491 }
485 // where clause 492 // where clause
486 case 30: 493 case 30:
487 step = 530; 494 step = 540;
488 break; 495 break;
489 // with clause 496 // with clause
490 case 40: 497 case 40: {
491 step = 500; 498 /*
492 break; 499 * 0: key
493 } 500 * 1: =
494 } 501 * 2: value
495 502 * TODO: commas
496 if (step < 500) { 503 */
504 static int withparser = 0;
505
506 /*
507 * 1: depth
508 */
509 int key;
510
511 switch (withparser) {
512 case 0:
513 if (!sstrcasecmp(tokendata, S("depth"))) {
514 key = 1;
515 withparser = 1;
516 } else {
517 stmt->errorcode = DAVQL_ERROR_UNKNOWN_ATTRIBUTE;
518 stmt->errormessage = ucx_sprintf(_unknown_attribute,
519 sfmtarg(tokendata)).ptr;
520 }
521 break;
522 case 1:
523 if (sstrcmp(tokendata, S("="))) {
524 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
525 stmt->errormessage = ucx_sprintf(_expected_token,
526 "=", sfmtarg(tokendata)).ptr;
527 } else {
528 withparser = 2;
529 }
530 break;
531 case 2:
532 switch (key) {
533 case 1: /* depth */
534 if (!sstrcasecmp(tokendata, S("infinity"))) {
535 stmt->depth = DAV_DEPTH_INFINITY;
536 } else {
537 char *conv = malloc(tokendata.length+1);
538 char *chk;
539 memcpy(conv, tokendata.ptr, tokendata.length);
540 conv[tokendata.length] = '\0';
541 stmt->depth = strtol(conv, &chk, 10);
542 if (*chk || stmt->depth < -1) {
543 stmt->errorcode = DAVQL_ERROR_INVALID_DEPTH;
544 stmt->errormessage = strdup(_invalid_depth);
545 }
546 free(conv);
547 }
548 break;
549 }
550 step = 500;
551 break;
552 }
553 break;
554 }
555 default:
556 stmt->errorcode = DAVQL_ERROR_INVALID;
557 stmt->errormessage = strdup(_parser_state);
558 }
559 }
560
561 if (!stmt->errorcode && step < 500) {
497 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_END; 562 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_END;
498 stmt->errormessage = strdup(_unexpected_end_msg); 563 stmt->errormessage = strdup(_unexpected_end_msg);
499 } 564 }
500 } 565 }
501 566

mercurial