diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-02-12 16:30:53 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-02-12 16:30:53 +0200 |
commit | 133e104d9efac43c0cf243207c2c5eaf0343bced (patch) | |
tree | 64399bcc3d6b33de2fb911d291ba90656b028fc1 | |
parent | c36a2210ed6cd53c5c65418fa9c20ac22dec8c59 (diff) | |
download | vmod-variable-133e104d9efac43c0cf243207c2c5eaf0343bced.tar.gz vmod-variable-133e104d9efac43c0cf243207c2c5eaf0343bced.tar.bz2 |
Improve batchset
The new syntax allows for supplying replacement patterns as in
variable.batchset("x:duration=\2s", ...
* configure.ac: Remove unneeded check
* src/variable.c (vardef): New member repl.
(bref_expand): New function.
(vmod_batchset): Change handling of vars string.
* tests/batchset.at: Update.
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | src/variable.c | 135 | ||||
-rw-r--r-- | tests/batchset.at | 6 |
3 files changed, 99 insertions, 60 deletions
diff --git a/configure.ac b/configure.ac index 2fa32f6..f21fcfb 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -105,30 +105,12 @@ AC_ARG_WITH([vmoddir], | |||
105 | 105 | ||
106 | 106 | ||
107 | if test -z "$VMODDIR"; then | 107 | if test -z "$VMODDIR"; then |
108 | VMODDIR='$(libdir)/varnish/mods' | 108 | VMODDIR='$(libdir)/varnish/mods' |
109 | fi | 109 | fi |
110 | 110 | ||
111 | ########### | ||
112 | # Check for db.h and libdb | ||
113 | # | ||
114 | AC_CHECK_HEADER([db.h],,[AC_MSG_ERROR([Required header file db.h not found])]) | ||
115 | |||
116 | AC_CHECK_LIB(db, db_create, | ||
117 | [LIBS="$LIBS -ldb" | ||
118 | AC_RUN_IFELSE( | ||
119 | [AC_LANG_PROGRAM([#include "db.h"], | ||
120 | [int v_major, v_minor, v_patch; | ||
121 | db_version(&v_major, &v_minor, &v_patch); | ||
122 | return !(v_major == DB_VERSION_MAJOR | ||
123 | && v_minor == DB_VERSION_MINOR | ||
124 | && v_patch == DB_VERSION_PATCH); | ||
125 | ])], | ||
126 | [], | ||
127 | [AC_MSG_ERROR([header file db.h is not the same version as libdb])])]) | ||
128 | |||
129 | AC_CONFIG_COMMANDS([status],[ | 111 | AC_CONFIG_COMMANDS([status],[ |
130 | delim="-------------------------------------------------------------------" | 112 | delim="-------------------------------------------------------------------" |
131 | echo "" | 113 | echo "" |
132 | echo $delim | 114 | echo $delim |
133 | echo "Building for Varnish version $VARNISHVERSION" | 115 | echo "Building for Varnish version $VARNISHVERSION" |
134 | echo $delim | 116 | echo $delim |
diff --git a/src/variable.c b/src/variable.c index 6403c1a..9442b6b 100644 --- a/src/variable.c +++ b/src/variable.c | |||
@@ -497,13 +497,14 @@ log_error(const char *fmt, ...) | |||
497 | 497 | ||
498 | #define S(s) ((s) ? (s) : "NULL") | 498 | #define S(s) ((s) ? (s) : "NULL") |
499 | 499 | ||
500 | struct vardef { | 500 | struct vardef { |
501 | struct vardef *next; | 501 | struct vardef *next; |
502 | enum variable_type type; | 502 | enum variable_type type; |
503 | char name[1]; | 503 | char *name; |
504 | char *repl; | ||
504 | }; | 505 | }; |
505 | 506 | ||
506 | static void | 507 | static void |
507 | vardef_free(struct vardef *v) | 508 | vardef_free(struct vardef *v) |
508 | { | 509 | { |
509 | while (v) { | 510 | while (v) { |
@@ -567,12 +568,57 @@ str2duration(const char *str) | |||
567 | } | 568 | } |
568 | while (*p && isspace(*p)) | 569 | while (*p && isspace(*p)) |
569 | p++; | 570 | p++; |
570 | return *p ? 0 : r; | 571 | return *p ? 0 : r; |
571 | } | 572 | } |
572 | 573 | ||
574 | char * | ||
575 | bref_expand(const char *str, const char *input, pcre *re, | ||
576 | int ovsize, int *ovector) | ||
577 | { | ||
578 | size_t rlen = 0; | ||
579 | char *rbase = NULL; | ||
580 | char *rptr; | ||
581 | int nm = 2*ovsize/3; | ||
582 | const char *p; | ||
583 | |||
584 | for (p = str; *p; ) { | ||
585 | if (*p == '\\' && strchr("123456789", p[1])) { | ||
586 | int n = 2*(p[1] - '0'); | ||
587 | if (n < nm) { | ||
588 | rlen += ovector[n+1] - ovector[n]; | ||
589 | p += 2; | ||
590 | continue; | ||
591 | } | ||
592 | } | ||
593 | ++p; | ||
594 | ++rlen; | ||
595 | } | ||
596 | rbase = malloc(rlen + 1); | ||
597 | AN(rbase); | ||
598 | p = str; | ||
599 | rptr = rbase; | ||
600 | while (*p) { | ||
601 | if (*p == '\\' && strchr("123456789", p[1])) { | ||
602 | int n = 2*(p[1] - '0'); | ||
603 | if (n < nm) { | ||
604 | memcpy(rptr, input + ovector[n], | ||
605 | ovector[n+1] - ovector[n]); | ||
606 | rptr += ovector[n+1] - ovector[n]; | ||
607 | p += 2; | ||
608 | continue; | ||
609 | } | ||
610 | } | ||
611 | |||
612 | *rptr++ = *p++; | ||
613 | } | ||
614 | *rptr = 0; | ||
615 | |||
616 | return rbase; | ||
617 | } | ||
618 | |||
573 | VCL_VOID | 619 | VCL_VOID |
574 | vmod_batchset(VARIABLE_CTX ctx, | 620 | vmod_batchset(VARIABLE_CTX ctx, |
575 | VCL_STRING vars, VCL_STRING rxs, VCL_STRING input) | 621 | VCL_STRING vars, VCL_STRING rxs, VCL_STRING input) |
576 | { | 622 | { |
577 | struct symtab *vt = get_symtab(ctx); | 623 | struct symtab *vt = get_symtab(ctx); |
578 | struct vardef *head = NULL, *tail = NULL, *def; | 624 | struct vardef *head = NULL, *tail = NULL, *def; |
@@ -595,50 +641,63 @@ vmod_batchset(VARIABLE_CTX ctx, | |||
595 | log_error("variable.batchset: bad arguments: vars=%s, rxs=%s, input=%s", | 641 | log_error("variable.batchset: bad arguments: vars=%s, rxs=%s, input=%s", |
596 | S(vars), S(rxs), S(input)); | 642 | S(vars), S(rxs), S(input)); |
597 | return; | 643 | return; |
598 | } | 644 | } |
599 | 645 | ||
600 | while (*v) { | 646 | while (*v) { |
601 | size_t n = strcspn(v, "="); | 647 | char const *nameptr = v; |
648 | size_t n = strcspn(v, ":=,"); | ||
649 | size_t namelen; | ||
650 | char const *replptr; | ||
651 | size_t repllen; | ||
652 | char rbuf[3]; | ||
653 | enum variable_type type; | ||
654 | int delim; | ||
602 | 655 | ||
603 | if (!v[n]) { | 656 | namelen = n; |
604 | log_error("variable.batchset: vars argument invalid near %s", | 657 | |
605 | v); | 658 | v += n; |
606 | vardef_free(head); | 659 | delim = *v ? *v++ : 0; |
607 | return; | 660 | |
661 | if (delim == ':') { | ||
662 | n = strcspn(v, "=,"); | ||
663 | type = str2type(v, n); | ||
664 | v += n; | ||
665 | delim = *v ? *v++ : 0; | ||
666 | } else | ||
667 | type = variable_string; | ||
668 | |||
669 | if (delim == '=') { | ||
670 | n = strcspn(v, ","); | ||
671 | replptr = v; | ||
672 | repllen = n; | ||
673 | v += n; | ||
674 | delim = *v ? *v++ : 0; | ||
675 | } else { | ||
676 | rbuf[0] = '\\'; | ||
677 | rbuf[1] = count + '1'; | ||
678 | rbuf[2] = 0; | ||
679 | replptr = rbuf; | ||
680 | repllen = 2; | ||
608 | } | 681 | } |
609 | def = malloc(sizeof(def[0]) + n); | 682 | |
683 | def = malloc(sizeof(def[0]) + namelen + repllen + 2); | ||
610 | def->next = NULL; | 684 | def->next = NULL; |
611 | memcpy(def->name, v, n); | ||
612 | def->name[n] = 0; | ||
613 | if (tail) | 685 | if (tail) |
614 | tail->next = def; | 686 | tail->next = def; |
615 | else | 687 | else |
616 | head = def; | 688 | head = def; |
617 | tail = def; | 689 | tail = def; |
618 | ++count; | 690 | ++count; |
619 | 691 | def->type = type; | |
620 | v += n + 1; | 692 | def->name = (char*)(def + 1); |
621 | if (!*v) { | 693 | memcpy(def->name, nameptr, namelen); |
622 | log_error("variable.batchset: no type for %s", def->name); | 694 | def->name[namelen] = 0; |
623 | vardef_free(head); | 695 | def->repl = def->name + namelen + 1; |
624 | return; | 696 | memcpy(def->repl, replptr, repllen); |
625 | } | 697 | def->repl[repllen] = 0; |
626 | |||
627 | n = strcspn(v, ","); | ||
628 | def->type = str2type(v, n); | ||
629 | if (def->type == variable_unset) { | ||
630 | log_error("variable.batchset: invalid type for %s", | ||
631 | def->name); | ||
632 | vardef_free(head); | ||
633 | return; | ||
634 | } | ||
635 | |||
636 | v += n; | ||
637 | if (*v) | ||
638 | ++v; | ||
639 | } | 698 | } |
640 | 699 | ||
641 | re = pcre_compile(rxs, cflags, &error_ptr, &error_offset, NULL); | 700 | re = pcre_compile(rxs, cflags, &error_ptr, &error_offset, NULL); |
642 | if (!re) { | 701 | if (!re) { |
643 | log_error("variable.batchset: %s: compilation failed near %s: %s", | 702 | log_error("variable.batchset: %s: compilation failed near %s: %s", |
644 | rxs, rxs + error_offset, error_ptr); | 703 | rxs, rxs + error_offset, error_ptr); |
@@ -670,22 +729,14 @@ vmod_batchset(VARIABLE_CTX ctx, | |||
670 | else | 729 | else |
671 | /*FIXME*/; | 730 | /*FIXME*/; |
672 | vardef_free(head); | 731 | vardef_free(head); |