From 774028525cf003e284071685e2b697ad305086e2 Mon Sep 17 00:00:00 2001 From: Mikhail Osipov Date: Fri, 24 Jan 2020 04:05:22 +0300 Subject: eval query with env --- pkg/server/env.go | 20 +++++++++++++++++--- pkg/server/server.go | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 13 deletions(-) (limited to 'pkg/server') 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 -- cgit v1.2.3-70-g09d2