libidav/davqlparser.c

changeset 90
46971430650b
parent 89
785f6007a0c1
child 91
838b427267bb
equal deleted inserted replaced
89:785f6007a0c1 90:46971430650b
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 _expected_token "expected token '%s' before '%.*s'"
249 #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" 250 #define _parser_state "parser reached invalid state"
251 #define _unknown_attribute "unknown attribute '%.*s'" 251 #define _unknown_attribute "unknown attribute '%.*s'"
252 #define _duplicated_attribute "duplicated attribute '%.*s'"
252 #define _invalid_depth "invalid depth" 253 #define _invalid_depth "invalid depth"
253 254
254 static UcxList* dav_parse_tokenize(sstr_t src) { 255 static UcxList* dav_parse_tokenize(sstr_t src) {
255 UcxList *tokens = NULL; 256 UcxList *tokens = NULL;
256 257
406 sfmtarg(*token_sstr(token)), 407 sfmtarg(*token_sstr(token)),
407 sfmtarg(token->next?*token_sstr(token->next):emptystring)); 408 sfmtarg(token->next?*token_sstr(token->next):emptystring));
408 stmt->errormessage = errormsg.ptr; 409 stmt->errormessage = errormsg.ptr;
409 } 410 }
410 411
412 static int dav_parse_with_clause(DavQLStatement *stmt, UcxList *token) {
413 sstr_t tokendata = *token_sstr(token);
414 /*
415 * 0: key
416 * 1: =
417 * 2: value
418 * TODO: commas
419 */
420 static int parsestate = 0;
421
422 /*
423 * 1: depth
424 */
425 int key = 0;
426 static int keymask = 0;
427
428 switch (parsestate) {
429 case 0:
430 if (!sstrcasecmp(tokendata, S("depth"))) {
431 key = 1;
432 parsestate = 1;
433 } else {
434 stmt->errorcode = DAVQL_ERROR_UNKNOWN_ATTRIBUTE;
435 stmt->errormessage = ucx_sprintf(_unknown_attribute,
436 sfmtarg(tokendata)).ptr;
437 break;
438 }
439 if (keymask & key) {
440 stmt->errorcode = DAVQL_ERROR_DUPLICATED_ATTRIBUTE;
441 stmt->errormessage = ucx_sprintf(_duplicated_attribute,
442 sfmtarg(tokendata)).ptr;
443 } else {
444 keymask |= key;
445 }
446 return 0;
447 case 1:
448 if (sstrcmp(tokendata, S("="))) {
449 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_TOKEN;
450 stmt->errormessage = ucx_sprintf(_expected_token,
451 "=", sfmtarg(tokendata)).ptr;
452 } else {
453 parsestate = 2;
454 }
455 return 0;
456 case 2:
457 switch (key) {
458 case 1: /* depth */
459 if (!sstrcasecmp(tokendata, S("infinity"))) {
460 stmt->depth = DAV_DEPTH_INFINITY;
461 } else {
462 char *conv = malloc(tokendata.length+1);
463 char *chk;
464 memcpy(conv, tokendata.ptr, tokendata.length);
465 conv[tokendata.length] = '\0';
466 stmt->depth = strtol(conv, &chk, 10);
467 if (*chk || stmt->depth < -1) {
468 stmt->errorcode = DAVQL_ERROR_INVALID_DEPTH;
469 stmt->errormessage = strdup(_invalid_depth);
470 }
471 free(conv);
472 }
473 break;
474 }
475 parsestate = 0;
476 return 1;
477 default:
478 return -1;
479 }
480 }
481
411 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) { 482 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) {
412 stmt->type = DAVQL_GET; 483 stmt->type = DAVQL_GET;
413 484
414 /* 485 /*
415 * 10: field list 486 * 10: field list
416 * 20: FROM clause 487 * 20: FROM clause
417 * 530: expecting WHERE or WITH clause 488 * 530: expecting WHERE or WITH clause
418 * 30: WHERE clause 489 * 30: WHERE clause
419 * 540: expecting WITH clause 490 * 540: expecting WITH clause
491 * 541: expecting comma for WITH clause
420 * 40: WITH clause 492 * 40: WITH clause
421 * 500: expect end 493 * 500: expect end
422 * 494 *
423 */ 495 */
424 int step = 10; 496 int step = 10;
446 step = 30; 518 step = 30;
447 } 519 }
448 /* no break and no else*/ 520 /* no break and no else*/
449 case 540: 521 case 540:
450 if (!sstrcasecmp(tokendata, S("with"))) { 522 if (!sstrcasecmp(tokendata, S("with"))) {
523 step = 40;
524 } else {
525 dav_parse_unexpected_token(stmt, token);
526 goto ultrabreak;
527 }
528 break;
529 case 541:
530 if (!sstrcmp(tokendata, S(","))) {
451 step = 40; 531 step = 40;
452 } else { 532 } else {
453 dav_parse_unexpected_token(stmt, token); 533 dav_parse_unexpected_token(stmt, token);
454 goto ultrabreak; 534 goto ultrabreak;
455 } 535 }
493 case 30: 573 case 30:
494 step = 540; 574 step = 540;
495 break; 575 break;
496 // with clause 576 // with clause
497 case 40: { 577 case 40: {
498 /* 578 int withclause_result = dav_parse_with_clause(stmt, token);
499 * 0: key 579 if (withclause_result < 0) {
500 * 1: = 580 stmt->errorcode = DAVQL_ERROR_INVALID;
501 * 2: value 581 stmt->errormessage = strdup(_parser_state);
502 * TODO: commas 582 } else if (withclause_result > 0) {
503 */ 583 step = 541;
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 } 584 }
553 break; 585 break;
554 } 586 }
555 default: 587 default:
556 stmt->errorcode = DAVQL_ERROR_INVALID; 588 stmt->errorcode = DAVQL_ERROR_INVALID;

mercurial