diff options
| author | Mikhail Osipov <mike.osipov@gmail.com> | 2020-01-24 04:05:22 +0300 |
|---|---|---|
| committer | Mikhail Osipov <mikhail.osipov@kaspersky.com> | 2020-01-24 14:15:12 +0300 |
| commit | 774028525cf003e284071685e2b697ad305086e2 (patch) | |
| tree | e6b431082138a79f9dad7dd844adc7c4a3eb7015 | |
| parent | ab3e3860cbb836203ac707ea395af9902d29ad39 (diff) | |
eval query with env
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | TODO | 4 | ||||
| -rw-r--r-- | pkg/server/env.go | 20 | ||||
| -rw-r--r-- | pkg/server/server.go | 42 | ||||
| -rw-r--r-- | test/Makefile | 4 | ||||
| -rwxr-xr-x | test/hello.sh | 11 |
6 files changed, 71 insertions, 17 deletions
@@ -6,6 +6,9 @@ default: build $(TARGETS): $(SUBDIRS) $(SUBDIRS): - $(MAKE) -C $@ $(MAKECMDGOALS) + @$(MAKE) -C $@ $(MAKECMDGOALS) -.PHONY: $(TARGETS) $(SUBDIRS) +test: + @$(MAKE) -C test + +.PHONY: $(TARGETS) $(SUBDIRS) test @@ -12,5 +12,5 @@ note: created on stream creation. In the latter case client will be multiplexer -6. check variable name -7. substitute variable over query (maybe) +6. DONE check variable name +7. DONE substitute variable over query (maybe) diff --git a/pkg/server/env.go b/pkg/server/env.go index 7fc338d..2f6937e 100644 --- a/pkg/server/env.go +++ b/pkg/server/env.go @@ -10,6 +10,7 @@ func init() { newCmd(envSet, "env", "set") newCmd(envDel, "env", "del") newCmd(envShow, "env", "show") + newCmd(envClear, "env", "clear") } type env struct { @@ -17,7 +18,11 @@ type env struct { sync.Mutex } -var isValidVarName = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9]*$").MatchString +const varNamePattern = "[a-zA-Z][a-zA-Z0-9]*" + +var isValidVarName = regexp.MustCompile("^" + varNamePattern + "$").MatchString + +var varTokenRe = regexp.MustCompile("%" + varNamePattern) func (e *env) get(key string) (string, bool) { e.Lock() @@ -67,6 +72,13 @@ func (e *env) each(f func (string, string) bool) { } } +func (e *env) clear() { + e.Lock() + defer e.Unlock() + + e.m = nil +} + func envGet(r *request) { r.expect(1) @@ -96,10 +108,12 @@ func envDel(r *request) { } func envShow(r *request) { - r.expect(0) - r.c.s.env.each(func (k string, v string) bool { r.Println(k, v) return true }) } + +func envClear(r *request) { + r.c.s.env.clear() +} diff --git a/pkg/server/server.go b/pkg/server/server.go index e2515cb..0524216 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -245,22 +245,44 @@ func (r *request) decode(query string) []string { return t } -func (r *request) parse(query string) { - c, args := getCmd(r.decode(query)) - if c == nil { - r.Fatal("command not found") +func (r *request) eval(args []string) []string { + repl := func (v string) string { + if v, ok := r.c.s.env.get(v[1:]); ok { + return v + } + + r.Fatal("unbound variable ", v) + + return v } - for n, s := range args { - if strings.HasPrefix(s, "%") { - if v, ok := r.c.s.env.get(s[1:]); ok { - args[n] = v - } else { - r.Fatal("unbound variable ", s) + eval := func (s string) string { + var t string + + for ;; s = t { + t = varTokenRe.ReplaceAllStringFunc(s, repl) + + if s == t { + return s } } } + for n, s := range args { + args[n] = eval(s) + } + + return args +} + +func (r *request) parse(query string) { + args := r.eval(r.decode(query)) + + c, args := getCmd(args) + if c == nil { + r.Fatal("command not found") + } + r.args = args r.argc = len(args) r.cmd = c diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..31766f2 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,4 @@ +nothing: + @echo to be done... + +.PHONY: nothing diff --git a/test/hello.sh b/test/hello.sh new file mode 100755 index 0000000..26711ef --- /dev/null +++ b/test/hello.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +ROOT=$(dirname $0)/.. +PATH=$ROOT/cmd/tunnel + +tunnel env clear +tunnel env set cmd echo +tunnel env set x Hello +tunnel env set y World +tunnel env set args "%x, %y!" +tunnel %cmd %args |
