libidav/davqlexec.c

changeset 126
b156cae29e65
parent 124
41939c8f3f9c
child 127
7072a2b4ae35
equal deleted inserted replaced
125:5e2576b08680 126:b156cae29e65
132 132
133 // TODO: get property list 133 // TODO: get property list
134 134
135 UcxBuffer *bcode = dav_compile_expr(mp->allocator, st->where, ap); 135 UcxBuffer *bcode = dav_compile_expr(mp->allocator, st->where, ap);
136 136
137 print_bytecode(bcode); 137 //print_bytecode(bcode);
138
139 DavResource *res = dav_resource_new(sn, "/test.txt");
140 dav_set_property_ns(res, "DAV:", "string", "value");
141 dav_set_property_ns(res, "DAV:", "integer", "1337");
142 res->lastmodified = 100;
143
144 DavQLStackObj result;
145 dav_exec_expr(bcode, res, &result);
138 } 146 }
139 147
140 static int count_func_args(DavQLExpression *expr) { 148 static int count_func_args(DavQLExpression *expr) {
141 int count = 0; 149 int count = 0;
142 DavQLExpression *arg = expr->right; 150 DavQLExpression *arg = expr->right;
147 } else { 155 } else {
148 break; 156 break;
149 } 157 }
150 } 158 }
151 return count; 159 return count;
160 }
161
162 static int identifier2propname(UcxAllocator *a, sstr_t id, DavPropName *propname) {
163 ssize_t count;
164 sstr_t *s = sstrsplit_a(a, id, S(":"), &count);
165 if(count == 2) {
166 sstr_t ns = s[0];
167 sstr_t name = s[1];
168 propname->ns = ns.ptr;
169 propname->name = name.ptr;
170 return 0;
171 } else {
172 return 1;
173 }
152 } 174 }
153 175
154 static int add_cmd(UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, va_list ap) { 176 static int add_cmd(UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, va_list ap) {
155 if(!expr) { 177 if(!expr) {
156 return 0; 178 return 0;
195 case DAVQL_IDENTIFIER: { 217 case DAVQL_IDENTIFIER: {
196 sstr_t propertyname = sstrchr(src, ':'); 218 sstr_t propertyname = sstrchr(src, ':');
197 cmd.type = DAVQL_CMD_RES_IDENTIFIER; 219 cmd.type = DAVQL_CMD_RES_IDENTIFIER;
198 if(propertyname.length > 0) { 220 if(propertyname.length > 0) {
199 cmd.type = DAVQL_CMD_PROP_IDENTIFIER; 221 cmd.type = DAVQL_CMD_PROP_IDENTIFIER;
200 222 if(identifier2propname(a, src, &cmd.data.property)) {
201 // TODO 223 // error
224 return -1;
225 }
202 } else if(!sstrcmp(src, S("name"))) { 226 } else if(!sstrcmp(src, S("name"))) {
203 cmd.data.resprop = DAVQL_RES_NAME; 227 cmd.data.resprop = DAVQL_RES_NAME;
204 } else if(!sstrcmp(src, S("path"))) { 228 } else if(!sstrcmp(src, S("path"))) {
205 cmd.data.resprop = DAVQL_RES_PATH; 229 cmd.data.resprop = DAVQL_RES_PATH;
206 } else if(!sstrcmp(src, S("href"))) { 230 } else if(!sstrcmp(src, S("href"))) {
213 cmd.data.resprop = DAVQL_RES_CREATIONDATE; 237 cmd.data.resprop = DAVQL_RES_CREATIONDATE;
214 } else if(!sstrcmp(src, S("lastmodified"))) { 238 } else if(!sstrcmp(src, S("lastmodified"))) {
215 cmd.data.resprop = DAVQL_RES_LASTMODIFIED; 239 cmd.data.resprop = DAVQL_RES_LASTMODIFIED;
216 } else if(!sstrcmp(src, S("iscollection"))) { 240 } else if(!sstrcmp(src, S("iscollection"))) {
217 cmd.data.resprop = DAVQL_RES_ISCOLLECTION; 241 cmd.data.resprop = DAVQL_RES_ISCOLLECTION;
242 } else if(!sstrcmp(src, S("true"))) {
243 cmd.type = DAVQL_CMD_INT;
244 cmd.data.integer = 1;
245 } else if(!sstrcmp(src, S("false"))) {
246 cmd.type = DAVQL_CMD_INT;
247 cmd.data.integer = 0;
248 } else {
249 // error, unknown identifier
250 return -1;
218 } 251 }
219 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); 252 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
220 break; 253 break;
221 } 254 }
222 case DAVQL_UNARY: { 255 case DAVQL_UNARY: {
286 cmd.type = DAVQL_CMD_OP_LOGICAL_NOT; 319 cmd.type = DAVQL_CMD_OP_LOGICAL_NOT;
287 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); 320 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
288 break; 321 break;
289 } 322 }
290 case DAVQL_LAND: { 323 case DAVQL_LAND: {
291 cmd.type = DAVQL_CMD_OP_LOGICAL_NOT; 324 cmd.type = DAVQL_CMD_OP_LOGICAL_AND;
292 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode); 325 ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
293 break; 326 break;
294 } 327 }
295 case DAVQL_LOR: { 328 case DAVQL_LOR: {
296 int nleft = add_cmd(a, bcode, expr->left, ap); 329 int nleft = add_cmd(a, bcode, expr->left, ap);
407 } 440 }
408 441
409 return bcode; 442 return bcode;
410 } 443 }
411 444
445 int dav_exec_expr(UcxBuffer *bcode, DavResource *res, DavQLStackObj *result) {
446 size_t count = bcode->pos / sizeof(DavQLCmd);
447 DavQLCmd *cmds = (DavQLCmd*)bcode->space;
448
449 // create execution stack
450 size_t stsize = 64;
451 size_t stpos = 0;
452 DavQLStackObj *stack = calloc(stsize, sizeof(DavQLStackObj));
453 #define DAVQL_PUSH(obj) \
454 if(stpos == stsize) { \
455 stsize += 64; \
456 stack = realloc(stack, stsize * sizeof(DavQLStackObj)); \
457 } \
458 stack[stpos++] = obj;
459 #define DAVQL_POP() stack[--stpos]
460
461 DavQLStackObj obj;
462 for(size_t i=0;i<count;i++) {
463 DavQLCmd cmd = cmds[i];
464 switch(cmd.type) {
465 case DAVQL_CMD_INT: {
466 printf("int %lld\n", cmd.data.integer);
467 obj.type = 0;
468 obj.length = 0;
469 obj.data.integer = cmd.data.integer;
470 DAVQL_PUSH(obj);
471 break;
472 }
473 case DAVQL_CMD_STRING: {
474 printf("string \"%.*s\"\n", cmd.data.string.length, cmd.data.string.ptr);
475 obj.type = 1;
476 obj.length = cmd.data.string.length;
477 obj.data.string = cmd.data.string.ptr;
478 DAVQL_PUSH(obj);
479 break;
480 }
481 case DAVQL_CMD_TIMESTAMP: {
482 printf("timestamp %d\n", cmd.data.timestamp);
483 obj.type = 0;
484 obj.length = 0;
485 obj.data.integer = cmd.data.timestamp;
486 DAVQL_PUSH(obj);
487 break;
488 }
489 case DAVQL_CMD_RES_IDENTIFIER: {
490 char *rid[8] = {"name", "path", "href", "contentlength", "contenttype", "creationdate", "lastmodified", "iscollection"};
491 printf("resprop %s\n", rid[cmd.data.resprop]);
492 switch(cmd.data.resprop) {
493 case DAVQL_RES_NAME: {
494 obj.type = 1;
495 obj.length = strlen(res->name);
496 obj.data.string = res->name;
497 break;
498 }
499 case DAVQL_RES_PATH: {
500 obj.type = 1;
501 obj.length = strlen(res->path);
502 obj.data.string = res->path;
503 break;
504 }
505 case DAVQL_RES_HREF: {
506 obj.type = 1;
507 obj.length = strlen(res->href);
508 obj.data.string = res->href;
509 break;
510 }
511 case DAVQL_RES_CONTENTLENGTH: {
512 obj.type = 0;
513 obj.length = 0;
514 obj.data.integer = res->contentlength;
515 break;
516 }
517 case DAVQL_RES_CONTENTTYPE: {
518 obj.type = 1;
519 obj.length = strlen(res->contenttype);
520 obj.data.string = res->contenttype;
521 break;
522 }
523 case DAVQL_RES_CREATIONDATE: {
524 obj.type = 0;
525 obj.length = 0;
526 obj.data.integer = res->creationdate;
527 break;
528 }
529 case DAVQL_RES_LASTMODIFIED: {
530 obj.type = 0;
531 obj.length = 0;
532 obj.data.integer = res->lastmodified;
533 break;
534 }
535 case DAVQL_RES_ISCOLLECTION: {
536 obj.type = 0;
537 obj.length = 0;
538 obj.data.integer = res->iscollection;
539 break;
540 }
541 }
542 DAVQL_PUSH(obj);
543 break;
544 }
545 case DAVQL_CMD_PROP_IDENTIFIER: {
546 printf("property %s:%s\n", cmd.data.property.ns, cmd.data.property.name);
547 char *value = dav_get_property_ns(res, cmd.data.property.ns, cmd.data.property.name);
548 obj.type = 1;
549 obj.length = value ? strlen(value) : 0;
550 obj.data.string = value;
551 DAVQL_PUSH(obj);
552 break;
553 }
554 case DAVQL_CMD_OP_UNARY_ADD: {
555 printf("uadd\n");
556 break;
557 }
558 case DAVQL_CMD_OP_UNARY_SUB: {
559 printf("usub\n");
560 break;
561 }
562 case DAVQL_CMD_OP_UNARY_NEG: {
563 printf("uneg\n");
564 break;
565 }
566 case DAVQL_CMD_OP_BINARY_ADD: {
567 printf("add\n");
568 break;
569 }
570 case DAVQL_CMD_OP_BINARY_SUB: {
571 printf("sub\n");
572 break;
573 }
574 case DAVQL_CMD_OP_BINARY_MUL: {
575 printf("mul\n");
576 break;
577 }
578 case DAVQL_CMD_OP_BINARY_DIV: {
579 printf("div\n");
580 break;
581 }
582 case DAVQL_CMD_OP_BINARY_AND: {
583 printf("and\n");
584 break;
585 }
586 case DAVQL_CMD_OP_BINARY_OR: {
587 printf("or\n");
588 break;
589 }
590 case DAVQL_CMD_OP_BINARY_XOR: {
591 printf("xor\n");
592 break;
593 }
594 case DAVQL_CMD_OP_LOGICAL_NOT: {
595 printf("not\n");
596 break;
597 }
598 case DAVQL_CMD_OP_LOGICAL_AND: {
599 printf("land\n");
600 break;
601 }
602 case DAVQL_CMD_OP_LOGICAL_OR_L: {
603 printf("or_l %d\n", cmd.data.integer);
604 break;
605 }
606 case DAVQL_CMD_OP_LOGICAL_OR: {
607 printf("or\n");
608 break;
609 }
610 case DAVQL_CMD_OP_LOGICAL_XOR: {
611 printf("lxor\n");
612 break;
613 }
614 case DAVQL_CMD_OP_EQ: {
615 printf("eq\n");
616 break;
617 }
618 case DAVQL_CMD_OP_NEQ: {
619 printf("neq\n");
620 break;
621 }
622 case DAVQL_CMD_OP_LT: {
623 printf("lt\n");
624 break;
625 }
626 case DAVQL_CMD_OP_GT: {
627 printf("gt\n");
628 DavQLStackObj obj2 = DAVQL_POP();
629 DavQLStackObj obj1 = DAVQL_POP();
630 // result
631 obj.type = 0;
632 obj.length = 0;
633
634 int64_t int1;
635 int64_t int2;
636 int isint = 1;
637 if(obj1.type == 0) {
638 int1 = obj1.data.integer;
639 } else {
640 isint = util_strtoint(obj1.data.string, &int1);
641 }
642 if(isint) {
643 if(obj2.type == 0) {
644 int2 = obj2.data.integer;
645 } else {
646 isint = util_strtoint(obj2.data.string, &int2);
647 }
648 if(isint) {
649 obj.data.integer = int1 > int2;
650 }
651 }
652
653 // string compare
654 // TODO
655 DAVQL_PUSH(obj);
656 break;
657 }
658 case DAVQL_CMD_OP_LE: {
659 printf("le\n");
660 break;
661 }
662 case DAVQL_CMD_OP_GE: {
663 printf("ge\n");
664 break;
665 }
666 case DAVQL_CMD_OP_LIKE: {
667 printf("like\n");
668 break;
669 }
670 case DAVQL_CMD_OP_UNLIKE: {
671 printf("unlike\n");
672 break;
673 }
674 case DAVQL_CMD_CALL: {
675 printf("call %x\n", cmd.data.func);
676 break;
677 }
678 }
679 }
680
681 for(int i=0;i<stpos;i++) {
682 DavQLStackObj obj = stack[i];
683 if(obj.type == 0) {
684 printf("stack: int=%lld\n", obj.data.integer);
685 } else {
686 printf("stack: string=\"%.*s\"\n", obj.length, obj.data.string);
687 }
688 }
689 return 0;
690 }
691
412 692
413 void print_bytecode(UcxBuffer *bcode) { 693 void print_bytecode(UcxBuffer *bcode) {
414 bcode->pos = 0; 694 bcode->pos = 0;
415 DavQLCmd cmd; 695 DavQLCmd cmd;
416 while(ucx_buffer_read(&cmd, sizeof(DavQLCmd), 1, bcode) == 1) { 696 while(ucx_buffer_read(&cmd, sizeof(DavQLCmd), 1, bcode) == 1) {
417 switch(cmd.type) { 697 switch(cmd.type) {
418 case DAVQL_CMD_INT: { 698 case DAVQL_CMD_INT: {
419 printf("int %ll\n", cmd.data.integer); 699 printf("int %lld\n", cmd.data.integer);
420 break; 700 break;
421 } 701 }
422 case DAVQL_CMD_STRING: { 702 case DAVQL_CMD_STRING: {
423 printf("string \"%.*s\"\n", cmd.data.string.length, cmd.data.string.ptr); 703 printf("string \"%.*s\"\n", cmd.data.string.length, cmd.data.string.ptr);
424 break; 704 break;

mercurial