From 65782a9bab0e75bcbbdf883c0541cdbd6e7d9f59 Mon Sep 17 00:00:00 2001 From: shaoying Date: Thu, 19 Jul 2018 09:34:04 +0800 Subject: [PATCH] mac pro ctx&cli --- etc/init.shy | 24 +- src/contexts/aaa/aaa.go | 1 - src/contexts/cli/cli.go | 575 ++++++++++++++-------------------------- src/contexts/ctx.go | 547 +++++--------------------------------- src/contexts/nfs/nfs.go | 6 +- src/contexts/yac/yac.go | 11 +- 6 files changed, 303 insertions(+), 861 deletions(-) diff --git a/etc/init.shy b/etc/init.shy index 54138866..499871d2 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -1,6 +1,26 @@ -config debug on + +if 1 + 2 + echo "hello" +end + +if 1 + 2 + echo "hello" +else + echo "world" +end + +if 0 + echo "hello" +end + +if 0 + echo "hello" +else + echo "word" +end + +return "hello" "world" source etc/demo.shy -return ~file1 history load hi.cmd scan_file etc/demo.shy diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index 1fc1cbcf..c5b7f3a0 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -178,7 +178,6 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", msg.Cap("password", password) - m.Login(msg) aaa.sessions[m.Cap("sessid")] = msg.Target() m.Echo(msg.Cap("sessid")) diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index ce40882b..7609a48a 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -16,36 +16,28 @@ import ( // {{{ // }}} +type Frame struct { + pos int + key string + run string +} + type CLI struct { nfs *ctx.Message - lex *ctx.Message - yac *ctx.Message - target *ctx.Context alias map[string][]string + target *ctx.Context + stack []Frame *ctx.Context } -func (cli *CLI) check(arg string) bool { // {{{ - switch arg { - case "", "0", "false": - return false - } - - return true -} - -// }}} - func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} s := new(CLI) s.Context = c - s.lex = cli.lex - s.yac = cli.yac s.nfs = cli.nfs s.target = m.Source() if len(arg) > 0 { @@ -65,19 +57,19 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ } if len(arg) > 0 && arg[0] == "source" { + cli.Caches["last"] = &ctx.Cache{Name: "前一条消息", Value: "0", Help: "前一条命令的编号"} + cli.Caches["target"] = &ctx.Cache{Name: "操作目标", Value: cli.Name, Help: "命令操作的目标"} + cli.Caches["level"] = &ctx.Cache{Name: "嵌套层级", Value: "0", Help: "嵌套层级"} + cli.Caches["skip"] = &ctx.Cache{Name: "跳过执行", Value: "false", Help: "命令只解析不执行"} return cli } - cli.Caches["level"] = &ctx.Cache{Name: "嵌套层级", Value: "0", Help: "嵌套层级"} - cli.Caches["skip"] = &ctx.Cache{Name: "跳过执行", Value: "0", Help: "命令只解析不执行"} cli.Caches["else"] = &ctx.Cache{Name: "解析选择语句", Value: "false", Help: "解析选择语句"} cli.Caches["loop"] = &ctx.Cache{Name: "解析循环语句", Value: "-2", Help: "解析选择语句"} cli.Caches["fork"] = &ctx.Cache{Name: "解析结束", Value: "-2", Help: "解析结束模块销毁"} cli.Caches["exit"] = &ctx.Cache{Name: "解析结束", Value: "false", Help: "解析结束模块销毁"} - cli.Caches["target"] = &ctx.Cache{Name: "操作目标", Value: cli.Name, Help: "命令操作的目标"} cli.Caches["result"] = &ctx.Cache{Name: "执行结果", Value: "", Help: "前一条命令的执行结果"} - cli.Caches["last"] = &ctx.Cache{Name: "前一条消息", Value: "0", Help: "前一条命令的编号"} cli.Caches["back"] = &ctx.Cache{Name: "前一条指令", Value: "", Help: "前一条指令"} cli.Caches["next"] = &ctx.Cache{Name: "下一条指令", Value: "", Help: "下一条指令"} @@ -93,81 +85,6 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ return x.Value // }}} }} - cli.Configs["lex"] = &ctx.Config{Name: "词法解析器", Value: "", Help: "命令行词法解析器", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { - if len(arg) > 0 && len(arg[0]) > 0 { // {{{ - cli, ok := m.Target().Server.(*CLI) - m.Assert(ok, "模块类型错误") - - lex := m.Find(arg[0], true) - m.Assert(lex != nil, "词法解析模块不存在") - if lex.Cap("status") != "start" { - lex.Target().Start(lex) - m.Spawn(lex.Target()).Cmd("train", "'[^']*'", "word", "word") - m.Spawn(lex.Target()).Cmd("train", "\"[^\"]*\"", "word", "word") - m.Spawn(lex.Target()).Cmd("train", "[^\t \n]+", "word", "word") - m.Spawn(lex.Target()).Cmd("train", "[\t \n]+", "void", "void") - m.Spawn(lex.Target()).Cmd("train", "#[^\n]*\n", "help", "void") - } - cli.lex = lex - return arg[0] - } - return x.Value - // }}} - }} - cli.Configs["yac"] = &ctx.Config{Name: "词法解析器", Value: "", Help: "命令行词法解析器", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { - if len(arg) > 0 && len(arg[0]) > 0 { // {{{ - cli, ok := m.Target().Server.(*CLI) - m.Assert(ok, "模块类型错误") - - yac := m.Find(arg[0], true) - m.Assert(yac != nil, "词法解析模块不存在") - if yac.Cap("status") != "start" { - yac.Target().Start(yac) - yac.Cmd("train", "void", "void", "[\t ]+") - - yac.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*") - yac.Cmd("train", "num", "num", "mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}") - yac.Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}") - - yac.Cmd("train", "tran", "tran", "mul{", "@", "$", "}", "opt{", "[a-zA-Z0-9_]+", "}") - yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "tran", "str", "[a-zA-Z0-9_/\\-.:]+", "}") - - yac.Cmd("train", "op1", "op1", "mul{", "$", "@", "}") - yac.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}") - yac.Cmd("train", "op1", "op1", "mul{", "-e", "-f", "-d", "}") - yac.Cmd("train", "op1", "op1", "mul{", "-", "+", "}") - yac.Cmd("train", "op2", "op2", "mul{", "+", "-", "*", "/", "}") - yac.Cmd("train", "op2", "op2", "mul{", ">", ">=", "<", "<=", "=", "!=", "}") - - yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "tran", "}") - yac.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}") - yac.Cmd("train", "val", "val", "(", "exp", ")") - - yac.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}") - yac.Cmd("train", "stm", "let", "let", "key", "mul{", "=", "<-", "}", "exp") - yac.Cmd("train", "stm", "if", "if", "exp") - yac.Cmd("train", "stm", "elif", "elif", "exp") - yac.Cmd("train", "stm", "for", "for", "exp") - yac.Cmd("train", "stm", "else", "else") - yac.Cmd("train", "stm", "end", "end") - yac.Cmd("train", "stm", "function", "function", "rep{", "key", "}") - yac.Cmd("train", "stm", "return", "return", "rep{", "exp", "}") - - yac.Cmd("train", "cmd", "echo", "rep{", "exp", "}") - yac.Cmd("train", "cmd", "cmd", "cache", "rep{", "word", "}") - yac.Cmd("train", "cmd", "cmd", "cache", "key", "rep{", "word", "}") - yac.Cmd("train", "cmd", "cmd", "cache", "key", "opt{", "=", "exp", "}") - yac.Cmd("train", "cmd", "cmd", "rep{", "word", "}") - yac.Cmd("train", "tran", "tran", "$", "(", "cmd", ")") - - yac.Cmd("train", "line", "line", "opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}") - } - cli.yac = yac - return arg[0] - } - return x.Value - // }}} - }} cli.Configs["PS1"] = &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { if len(arg) > 0 { // {{{ return arg[0] @@ -229,9 +146,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ yac.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*") yac.Cmd("train", "num", "num", "mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}") yac.Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}") - yac.Cmd("train", "tran", "tran", "mul{", "@", "$", "}", "opt{", "[a-zA-Z0-9_]+", "}") - yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "tran", "str", "[a-zA-Z0-9_/\\-.:]+", "}") yac.Cmd("train", "op1", "op1", "mul{", "$", "@", "}") yac.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}") @@ -243,18 +158,19 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "tran", "}") yac.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}") yac.Cmd("train", "val", "val", "(", "exp", ")") - yac.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}") yac.Cmd("train", "stm", "let", "let", "key", "mul{", "=", "<-", "}", "exp") + yac.Cmd("train", "stm", "if", "if", "exp") - yac.Cmd("train", "stm", "elif", "elif", "exp") - yac.Cmd("train", "stm", "for", "for", "exp") yac.Cmd("train", "stm", "else", "else") yac.Cmd("train", "stm", "end", "end") + + yac.Cmd("train", "stm", "elif", "elif", "exp") + yac.Cmd("train", "stm", "for", "for", "exp") yac.Cmd("train", "stm", "function", "function", "rep{", "key", "}") yac.Cmd("train", "stm", "return", "return", "rep{", "exp", "}") - yac.Cmd("train", "cmd", "echo", "rep{", "exp", "}") + yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "tran", "str", "[a-zA-Z0-9_/\\-.:]+", "}") yac.Cmd("train", "cmd", "cmd", "cache", "rep{", "word", "}") yac.Cmd("train", "cmd", "cmd", "cache", "key", "rep{", "word", "}") yac.Cmd("train", "cmd", "cmd", "cache", "key", "opt{", "=", "exp", "}") @@ -268,18 +184,33 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ m.Option("target", m.Target().Name) yac = m.Sesss("yac") yac.Call(func(cmd *ctx.Message) *ctx.Message { + m.Log("fuck", nil, "skip: %s, level:%s %v", m.Cap("skip"), m.Cap("level"), cli.stack) + if m.Caps("skip") { + switch cmd.Detail(0) { + case "if": + cmd.Set("detail", "if", "0") + case "else": + case "end": + default: + cmd.Hand = true + return nil + } + } + cmd.Cmd() m.Option("target", cli.target.Name) if cmd.Has("return") { m.Options("scan_end", true) m.Target().Close(m.Spawn()) + m.Result(0, cmd.Meta["return"]) } return nil }, "parse", arg[1]) m.Cap("stream", yac.Target().Name) if arg[1] == "stdio" { - m.Spawn().Cmd("source", "etc/init.shy") + msg := m.Spawn().Cmd("source", "etc/init.shy") + msg.Result(0, msg.Meta["return"]) } return false } @@ -311,17 +242,6 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.Context.Exit = make(chan bool) cli.Context.Master(cli.Context) - m.Deal(func(msg *ctx.Message, arg ...string) bool { - return !m.Caps("skip") || Index.Has(msg.Get("detail"), "command") - - }, func(msg *ctx.Message, arg ...string) bool { - if m.Caps("skip") { - return !m.Caps("exit") - } - - return !m.Caps("exit") - }) - if cli.Pulse.Has("save") { m.Cap("status", "stop") cli.Exit <- true @@ -354,14 +274,11 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ var Pulse *ctx.Message var Index = &ctx.Context{Name: "cli", Help: "管理中心", Caches: map[string]*ctx.Cache{ - "time": &ctx.Cache{Name: "time", Value: "0", Help: "所有模块的当前目录", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string { - t := time.Now().Unix() - return fmt.Sprintf("%d", t) - }}, "nshell": &ctx.Cache{Name: "nshell", Value: "0", Help: "模块数量"}, }, Configs: map[string]*ctx.Config{ "time_format": &ctx.Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"}, + "time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"}, "time_interval": &ctx.Config{Name: "time_interval(open/close)", Value: "open", Help: "时间区间"}, "cli_name": &ctx.Config{Name: "cli_name", Value: "shell", Help: "时间格式", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { if len(arg) > 0 { // {{{ @@ -373,50 +290,68 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "时间区间"}, }, Commands: map[string]*ctx.Command{ - "alias": &ctx.Command{Name: "alias [short [long]]|[delete short]", Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - switch len(arg) { - case 0: - for k, v := range cli.alias { - m.Echo("%s: %v\n", k, v) + "source": &ctx.Command{ + Name: "source filename [async [cli_name [cli_help]]", + Help: "解析脚本, filename: 文件名, cli_name: 模块名, cli_help: 模块帮助", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + m.Start(m.Confx("cli_name", arg, 2), m.Confx("cli_help", arg, 3), key, arg[0]) + if len(arg) > 1 && arg[1] == "async" { + return } - case 1: - m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]]) - default: - if arg[0] == "delete" { - m.Echo("delete: %s %v\n", arg[1], cli.alias[arg[1]]) - delete(cli.alias, arg[1]) - } else { - cli.alias[arg[0]] = arg[1:] + <-m.Target().Exit + sub := m.Target().Server.(*CLI) + cli.target = sub.target + } // }}} + }}, + "return": &ctx.Command{Name: "return result...", Help: "结束脚本, rusult: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Add("append", "return", arg[1:]) + }}, + "alias": &ctx.Command{ + Name: "alias [short [long...]]|[delete short]", + Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + switch len(arg) { + case 0: + for k, v := range cli.alias { + m.Echo("%s: %v\n", k, v) + } + case 1: m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]]) + default: + if arg[0] == "delete" { + m.Echo("delete: %s %v\n", arg[1], cli.alias[arg[1]]) + delete(cli.alias, arg[1]) + } else { + cli.alias[arg[0]] = arg[1:] + m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]]) + } } - } - } // }}} - }}, + } // }}} + }}, "sleep": &ctx.Command{Name: "sleep time", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Source().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - if d, e := time.ParseDuration(arg[0]); m.Assert(e) { - m.Log("info", nil, "sleep %v", d) - time.Sleep(d) - m.Log("info", nil, "sleep %v done", d) - } + if d, e := time.ParseDuration(arg[0]); m.Assert(e) { // {{{ + m.Log("info", nil, "sleep %v", d) + time.Sleep(d) + m.Log("info", nil, "sleep %v done", d) } // }}} }}, - "time": &ctx.Command{Name: "time [time_format format] [parse when] when [begin|end|yestoday|tommorow|monday|sunday|first|last|origin|last]", - Form: map[string]int{"parse": 1, "time_format": 1, "time_interval": 1}, - Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "time": &ctx.Command{ + Name: "time [time_format format] [parse when] when [begin|end|yestoday|tommorow|monday|sunday|first|last|origin|last]", + Form: map[string]int{"time_format": 1, "parse": 1, "time_interval": 1}, + Help: "查看时间, time_format: 输出或解析的时间格式, parse: 输入的时间字符串, when: 输入的时间戳, 其它是时间偏移", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { t := time.Now() // {{{ - f := m.Confx("time_format") - if m.Options("parse") { - n, e := time.ParseInLocation(f, m.Option("parse"), time.Local) + n, e := time.ParseInLocation(m.Confx("time_format"), m.Option("parse"), time.Local) m.Assert(e) t = n } if len(arg) > 0 { if i, e := strconv.Atoi(arg[0]); e == nil { - t = time.Unix(int64(i/1000), 0) + t = time.Unix(int64(i/m.Confi("time_unit")), 0) arg = arg[1:] } } @@ -424,7 +359,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", if len(arg) > 0 { switch arg[0] { case "begin": - // t.Add(-((time.Second)t.Second() + (time.Minute)t.Minute() + (time.Hour)t.Hour())) d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", t.Hour(), t.Minute(), t.Second())) m.Assert(e) t = t.Add(-d) @@ -472,13 +406,47 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } if m.Options("parse") || !m.Options("time_format") { - m.Echo("%d000", t.Unix()) + m.Echo("%d", t.Unix()*int64(m.Confi("time_unit"))) } else { - m.Echo(t.Format(f)) + m.Echo(t.Format(m.Confx("time_format"))) } // }}} }}, - "express": &ctx.Command{Name: "express exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "echo": &ctx.Command{Name: "echo arg...", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Echo("%s", strings.Join(arg[1:], "")) + }}, + + "tran": &ctx.Command{Name: "tran word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + msg := m.Spawn(cli.target) + switch len(arg) { + case 1: + m.Echo(arg[0]) + case 2: + switch arg[0] { + case "$": + m.Echo(msg.Cap(arg[1])) + case "@": + m.Echo(msg.Conf(arg[1])) + default: + m.Echo(arg[0]) + m.Echo(arg[1]) + } + default: + last := len(arg) - 1 + switch arg[0] { + case "$": + m.Result(0, arg[2:last]) + case "@": + m.Result(0, arg[2:last]) + } + } + } //}}} + }}, + "str": &ctx.Command{Name: "str word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Echo(arg[0][1 : len(arg[0])-1]) + }}, + "val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { result := "false" // {{{ switch len(arg) { case 0: @@ -591,130 +559,89 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Echo(result) // }}} }}, - "str": &ctx.Command{Name: "str word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - str := arg[0][1 : len(arg[0])-1] - str = strings.Replace(str, "\\n", "\n", -1) - str = strings.Replace(str, "\\t", "\t", -1) - m.Echo(str) - } else { - m.Set("result", arg...) - } - // }}} - }}, - "val": &ctx.Command{Name: "val word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - if arg[0] == "(" { - m.Echo(arg[1]) - return - } - - if len(arg) == 1 { - m.Echo(arg[0]) - return - } - - switch arg[0] { - case "-z": - if arg[1] == "" { - m.Echo("true") - } else { - m.Echo("false") - } - case "-n": - if arg[1] == "" { - m.Echo("false") - } else { - m.Echo("true") - } - case "-e": - if _, e := os.Stat(arg[1]); e == nil { - m.Echo("true") - } else { - m.Echo("false") - } - case "-f": - if info, e := os.Stat(arg[1]); e == nil && !info.IsDir() { - m.Echo("true") - } else { - m.Echo("false") - } - case "-d": - if info, e := os.Stat(arg[1]); e == nil && info.IsDir() { - m.Echo("true") - } else { - m.Echo("false") - } - case "$": - m.Echo(m.Cap(arg[1])) - case "@": - m.Echo(m.Conf(arg[1])) - } - } else { - m.Set("result", arg...) - } - // }}} - }}, "exp": &ctx.Command{Name: "exp word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - pre := map[string]int{"+": 1, "-": 1, "*": 2, "/": 2} - num := []string{arg[0]} - op := []string{} + pre := map[string]int{"+": 1, "-": 1, "*": 2, "/": 2} // {{{ + num := []string{arg[0]} + op := []string{} - for i := 1; i < len(arg); i += 2 { - if len(op) > 0 && pre[op[len(op)-1]] >= pre[arg[i]] { - num[len(op)-1] = m.Cmd("express", num[len(op)-1], op[len(op)-1], num[len(op)]).Get("result") - num = num[:len(num)-1] - op = op[:len(op)-1] - } - - num = append(num, arg[i+1]) - op = append(op, arg[i]) + for i := 1; i < len(arg); i += 2 { + if len(op) > 0 && pre[op[len(op)-1]] >= pre[arg[i]] { + num[len(op)-1] = m.Spawn().Cmd("val", num[len(op)-1], op[len(op)-1], num[len(op)]).Get("result") + num = num[:len(num)-1] + op = op[:len(op)-1] } - for i := len(op) - 1; i >= 0; i-- { - num[i] = m.Spawn(m.Target()).Cmd("express", num[i], op[i], num[i+1]).Get("result") - } - - m.Echo("%s", num[0]) - } else { - m.Set("result", arg...) + num = append(num, arg[i+1]) + op = append(op, arg[i]) } + + for i := len(op) - 1; i >= 0; i-- { + num[i] = m.Spawn().Cmd("val", num[i], op[i], num[i+1]).Get("result") + } + + m.Echo("%s", num[0]) // }}} }}, - "tran": &ctx.Command{Name: "tran word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - msg := m.Spawn(cli.target) - switch len(arg) { - case 1: - switch arg[0] { - case "$": - m.Echo("cache") - case "@": - m.Echo("config") - } - case 2: - switch arg[0] { - case "$": - m.Echo(msg.Cap(arg[1])) - case "@": - m.Echo(msg.Conf(arg[1])) - } - default: - last := len(arg) - 1 - switch arg[0] { - case "$": - m.Result(0, arg[2:last]) - case "@": - m.Result(0, arg[2:last]) - } + "var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 3 { // {{{ + switch arg[2] { + case "=": + m.Cap(arg[1], arg[3]) + case "<-": + m.Cap(arg[1], m.Cap("last")) } - } else { - m.Set("result", arg...) + } + m.Echo(m.Cap(arg[1])) + // }}} + }}, + "let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式(a {+|-|*|/|%} b)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + switch arg[2] { // {{{ + case "=": + m.Cap(arg[1], arg[3]) + case "<-": + m.Cap(arg[1], m.Cap("last")) + } + m.Echo(m.Cap(arg[1])) + // }}} + }}, + "if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + cli.stack = append(cli.stack, Frame{pos: m.Optioni("nline") - 1, key: key, run: arg[1]}) + m.Capi("level", 1) + m.Caps("skip", !ctx.Right(arg[1])) + m.Log("fuck", nil, "if %v", cli.stack) } // }}} }}, + "else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + if m.Caps("skip") { + m.Caps("skip", false) + } else { + if len(cli.stack) == 1 { + m.Caps("skip", true) + } else { + frame := cli.stack[len(cli.stack)-2] + if ctx.Right(frame.run) { + m.Caps("skip", true) + } + } + } + } // }}} + }}, + "end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + if cli.stack = cli.stack[:len(cli.stack)-1]; m.Capi("level", -1) > 0 { + frame := cli.stack[len(cli.stack)-1] + m.Caps("skip", !ctx.Right(frame.run)) + } else { + m.Caps("skip", false) + } + m.Log("fuck", nil, "if %v", cli.stack) + } // }}} + }}, + "cmd": &ctx.Command{Name: "cmd word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ + if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ detail := []string{} if a, ok := cli.alias[arg[0]]; ok { @@ -724,13 +651,11 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", detail = append(detail, arg...) } - msg := m.Spawn(cli.target) - msg.Cmd(detail) - if msg.Target().Context() != nil || msg.Target() == ctx.Index { + msg := m.Spawn(cli.target).Cmd(detail) + if msg.Hand { cli.target = msg.Target() - } - - if !msg.Hand && cli.Owner == ctx.Index.Owner { + m.Cap("target", cli.target.Name) + } else { msg.Hand = true msg.Log("system", nil, "%v", msg.Meta["detail"]) @@ -755,76 +680,12 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } } } - - m.Cap("target", cli.target.Name) - m.Set("result", msg.Meta["result"]...) + m.Copy(msg, "result").Copy(msg, "append") m.Capi("last", 0, msg.Code()) - - } else { - m.Set("result", arg...) } // }}} }}, - "var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 3 { - switch arg[2] { - case "=": - m.Cap(arg[1], arg[3]) - case "<-": - m.Cap(arg[1], m.Cap("last")) - } - } - } else { - m.Set("result", arg...) - } // }}} - }}, - "let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式(a {+|-|*|/|%} b)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - switch arg[2] { - case "=": - m.Cap(arg[1], arg[3]) - case "<-": - m.Cap(arg[1], m.Cap("last")) - } - } else { - m.Set("result", arg...) - } // }}} - }}, - "source_old": &ctx.Command{Name: "source_old file", Help: "运行脚本, file: 脚本文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - cli, ok := m.Source().Server.(*CLI) // {{{ - if !ok { - cli, ok = m.Target().Server.(*CLI) - } - if !m.Caps("skip") { - msg := m.Spawn(cli) - msg.Start(fmt.Sprintf("%s_%d_%s", key, msg.Optioni("level", msg.Capi("level")+1), arg[0]), "脚本文件", arg[0]) - // <-msg.Target().Exit - // m.Copy(msg, "result").Copy(msg, "append") - // nfs := msg.Sesss("nfs") - // nfs.Target().Close(nfs) - // - // sub, _ := msg.Target().Server.(*CLI) - // if sub.target != msg.Target() { - // cli.target = sub.target - // } - } // }}} - }}, - "return": &ctx.Command{Name: "return result...", Help: "结束脚本, rusult: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - m.Add("append", "return", arg[1:]) - } // }}} - }}, - "if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ - if m.Optioni("skip", 0); m.Caps("skip") || !cli.check(arg[1]) { - m.Optioni("skip", m.Capi("skip")+1) - } - - m.Start(fmt.Sprintf("%s%d", key, m.Optioni("level", m.Capi("level")+1)), "条件语句") - } // }}} - }}, "elif": &ctx.Command{Name: "elif exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ if !m.Caps("else") { @@ -838,36 +699,17 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", return } - m.Caps("else", m.Caps("skip", !cli.check(arg[1]))) - } // }}} - }}, - "else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ - m.Caps("skip", !m.Caps("else")) - } // }}} - }}, - "end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ - if m.Capi("fork") != -2 { - m.Spawn(cli.nfs.Target()).Cmd("copy", cli.Name, m.Cap("fork"), m.Option("pos")) - } - - if m.Caps("exit", true); !m.Caps("skip") && m.Capi("loop") >= 0 { - m.Append("back", m.Cap("loop")) - m.Caps("exit", false) - } else { - m.Put("append", "cli", cli.Context.Context()) - } + m.Caps("else", m.Caps("skip", !ctx.Right(arg[1]))) } // }}} }}, "for": &ctx.Command{Name: "for exp", Help: "循环语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ + if _, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ if m.Capi("loop") != -2 && m.Capi("loop") == m.Optioni("pos")-1 { - m.Caps("skip", !cli.check(arg[1])) + m.Caps("skip", !ctx.Right(arg[1])) return } - if m.Optioni("skip", 0); m.Caps("skip") || !cli.check(arg[1]) { + if m.Optioni("skip", 0); m.Caps("skip") || !ctx.Right(arg[1]) { m.Optioni("skip", m.Capi("skip")+1) } m.Optioni("loop", m.Optioni("pos")-1) @@ -895,23 +737,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Echo("%d\n", i) } }}, - "echo": &ctx.Command{Name: "echo arg...", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Echo("%s", strings.Join(arg, "")) - }}, - "source": &ctx.Command{ - Name: "source filename [async [cli_name [cli_help]]", - Help: "解析脚本, filename: 文件名, cli_name: 模块名, cli_help: 模块帮助", - Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { - m.Start(m.Confx("cli_name", arg, 2), m.Confx("cli_help", arg, 3), key, arg[0]) - if len(arg) > 1 && arg[1] == "async" { - return - } - <-m.Target().Exit - sub := m.Target().Server.(*CLI) - cli.target = sub.target - } - }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index 38a3eea4..91089ace 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -1,8 +1,6 @@ package ctx // {{{ // }}} import ( // {{{ - "crypto/md5" - "encoding/hex" "encoding/json" "errors" "fmt" @@ -21,7 +19,7 @@ import ( // {{{ // }}} -func Right(str string) bool { +func Right(str string) bool { // {{{ switch str { case "", "0", "false", "off", "no", "error: ": return false @@ -29,6 +27,31 @@ func Right(str string) bool { return true } +// }}} +func Trans(arg ...interface{}) []string { // {{{ + ls := []string{} + for _, v := range arg { + value := "" + switch val := v.(type) { + case []string: + ls = append(ls, val...) + continue + case string: + value = val + case bool: + value = fmt.Sprintf("%t", val) + case int, int8, int16, int32, int64: + value = fmt.Sprintf("%d", val) + default: + value = fmt.Sprintf("%v", val) + } + ls = append(ls, value) + } + return ls +} + +// }}} + type Cache struct { Name string Value string @@ -90,6 +113,21 @@ type Context struct { Server } +func (c *Context) Register(s *Context, x Server) (password string) { // {{{ + if c.contexts == nil { + c.contexts = make(map[string]*Context) + } + if x, ok := c.contexts[s.Name]; ok { + panic(errors.New(c.Name + "上下文中已存在模块:" + x.Name)) + } + + c.contexts[s.Name] = s + s.context = c + s.Server = x + return s.password +} + +// }}} func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{ s := &Context{Name: name, Help: help, root: c.root, context: c} @@ -235,100 +273,6 @@ func (c *Context) Close(m *Message, arg ...string) bool { // {{{ // }}} -func (c *Context) Password(meta string) string { // {{{ - bs := md5.Sum([]byte(fmt.Sprintln("%d%d%s", time.Now().Unix(), rand.Int(), meta))) - sessid := hex.EncodeToString(bs[:]) - return sessid -} - -// }}} -func (c *Context) Register(s *Context, x Server) (password string) { // {{{ - if c.contexts == nil { - c.contexts = make(map[string]*Context) - } - if x, ok := c.contexts[s.Name]; ok { - panic(errors.New(c.Name + "上下文中已存在模块:" + x.Name)) - } - - c.contexts[s.Name] = s - s.context = c - s.Server = x - s.password = c.Password(s.Name) - return s.password -} - -// }}} -func (c *Context) Check(m *Message, arg ...string) bool { // {{{ - if g, ok := c.Index["void"]; ok && g != nil { - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "caches": - _, ok = g.Caches[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "commands": - _, ok = g.Commands[arg[1]] - } - - if ok { - return true - } - } - - aaa := m - for msg := m; msg != nil && msg.code != 0 && msg != msg.message; msg = msg.message { - aaa = nil - if a, ok := msg.Sessions["aaa"]; ok { - aaa = a - break - } - } - - if aaa == nil { - return true - } - - if c.Owner == nil { - return true - } - - if c.Owner == aaa.target { - return true - } - - group := aaa.Cap("group") - if group == aaa.Conf("rootname") { - return true - } - - if g, ok := c.Index[group]; ok && g != nil { - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "caches": - _, ok = g.Caches[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "commands": - _, ok = g.Commands[arg[1]] - } - - if ok { - return true - } - } - - m.Log("check", nil, "%s %d %v failure", c.Name, m.code, arg) - return false -} - -// }}} - func (c *Context) Context() *Context { // {{{ return c.context } @@ -436,18 +380,16 @@ func (m *Message) Target(s ...*Context) *Context { // {{{ } // }}} - -func (m *Message) Login(aaa *Message) { // {{{ - m.source.Owner = m.target - for msg := m; msg != nil; msg = msg.message { - if nfs, ok := msg.Sessions["nfs"]; ok { - nfs.Sessions["aaa"] = aaa - return - } +func (m *Message) Format() string { // {{{ + name := fmt.Sprintf("%s->%s", m.source.Name, m.target.Name) + if m.Name != "" { + name = fmt.Sprintf("%s.%s->%s.%d", m.source.Name, m.Name, m.target.Name, m.Index) } + return fmt.Sprintf("%d(%s): %s %v", m.code, name, m.time.Format("15:04:05"), m.Meta["detail"]) } // }}} + func (m *Message) Log(action string, ctx *Context, str string, arg ...interface{}) *Message { // {{{ if !m.Options("log") { return m @@ -460,185 +402,6 @@ func (m *Message) Log(action string, ctx *Context, str string, arg ...interface{ return m } -// }}} -func (m *Message) Check(s *Context, arg ...string) bool { // {{{ - return true - if m.root.target.Sessions == nil || m.root.target.Sessions["aaa"] == nil { - return true - } - - if g, ok := s.Index["void"]; ok && g != nil { - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "caches": - _, ok = g.Caches[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "commands": - _, ok = g.Commands[arg[1]] - } - - if ok { - return true - } - } - - aaa := m - for msg := m; msg != nil && msg.code != 0 && msg != msg.message; msg = msg.message { - if a, ok := msg.Target().Sessions["aaa"]; ok { - aaa = a - break - } - } - - if aaa == nil { - return true - } - - group := aaa.Cap("group") - if group == aaa.Conf("rootname") { - return true - } - - if g, ok := s.Index[group]; ok && g != nil { - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "caches": - _, ok = g.Caches[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "commands": - _, ok = g.Commands[arg[1]] - } - - if ok { - return true - } - } - - fmt.Printf("check %s %s %v false\n", group, s.Name, arg) - return false - - if aaa.target.Caches == nil { - return true - } - if aaa.target.Caches["group"] == nil { - return true - } - - g, ok := s.Index[group] - gg, gok := s.Index["void"] - - if len(arg) < 2 { - if ok && g != nil { - return true - } - - if gok && gg != nil { - return true - } - - return false - } - fmt.Printf("%v\n", arg) - - ok, gok = false, false - switch arg[0] { - case "commands": - if g != nil { - _, ok = g.Commands[arg[1]] - } - if gg != nil { - _, gok = gg.Commands[arg[1]] - } - case "configs": - if g != nil { - _, ok = g.Configs[arg[1]] - } - if gg != nil { - _, gok = gg.Configs[arg[1]] - } - case "caches": - if g != nil { - _, ok = g.Caches[arg[1]] - } - if gg != nil { - _, gok = gg.Caches[arg[1]] - } - } - - if ok { - return true - } - if gok { - return true - } - return false -} - -// }}} -func (m *Message) Permit(s *Context, arg ...string) bool { // {{{ - - if m.root.target.Sessions == nil || m.root.target.Sessions["aaa"] == nil { - return true - } - - if aaa := m.Sesss("aaa"); aaa != nil { - - if g, ok := s.Index["void"]; ok && g != nil { - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "caches": - _, ok = g.Caches[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "commands": - _, ok = g.Commands[arg[1]] - } - - if ok { - return true - } - } - - group := aaa.Cap("group") - if group == aaa.Conf("rootname") { - return true - } - - if g, ok := s.Index[group]; ok && g != nil { - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "caches": - _, ok = g.Caches[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "commands": - _, ok = g.Commands[arg[1]] - } - - if ok { - return true - } - } - return true - } - - return true -} - // }}} func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ switch e := e.(type) { @@ -652,9 +415,6 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ return true } case *Context: - if m.Check(e, msg...) { - return true - } if len(msg) > 2 { msg = msg[2:] } @@ -760,40 +520,12 @@ func (m *Message) Spawn(arg ...interface{}) *Message { // {{{ return msg } -// }}} -func (m *Message) Reply(key ...string) *Message { // {{{ - if m.Template == nil { - m.Template = m.Spawn(m.source) - } - - msg := m.Template - if len(key) == 0 { - return msg - } - - if msg.source.Sessions == nil { - msg.source.Sessions = make(map[string]*Message) - } - msg.source.Sessions[key[0]] = msg - msg.Name = key[0] - return msg -} - -// }}} -func (m *Message) Format() string { // {{{ - name := fmt.Sprintf("%s->%s", m.source.Name, m.target.Name) - if m.Name != "" { - name = fmt.Sprintf("%s.%s->%s.%d", m.source.Name, m.Name, m.target.Name, m.Index) - } - return fmt.Sprintf("%d(%s): %s %v", m.code, name, m.time.Format("15:04:05"), m.Meta["detail"]) -} - // }}} func (m *Message) BackTrace(hand func(m *Message) bool) { // {{{ target := m.target for s := target; s != nil; s = s.context { - if m.target = s; m.Check(s) && !hand(m) { + if m.target = s; !hand(m) { break } } @@ -809,7 +541,7 @@ func (m *Message) Travel(c *Context, hand func(m *Message) bool) { // {{{ cs := []*Context{c} for i := 0; i < len(cs); i++ { - if m.target = cs[i]; m.Check(cs[i]) && !hand(m) { + if m.target = cs[i]; !hand(m) { break } @@ -1004,28 +736,6 @@ func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg // }}} -func (m *Message) Trans(arg ...interface{}) []string { - ls := []string{} - for _, v := range arg { - value := "" - switch val := v.(type) { - case []string: - ls = append(ls, val...) - continue - case string: - value = val - case bool: - value = fmt.Sprintf("%t", val) - case int, int8, int16, int32, int64: - value = fmt.Sprintf("%d", val) - default: - value = fmt.Sprintf("%v", val) - } - ls = append(ls, value) - } - return ls -} - func (m *Message) Add(meta string, key string, value ...interface{}) *Message { // {{{ if m.Meta == nil { m.Meta = make(map[string][]string) @@ -1037,13 +747,13 @@ func (m *Message) Add(meta string, key string, value ...interface{}) *Message { switch meta { case "detail", "result": m.Meta[meta] = append(m.Meta[meta], key) - m.Meta[meta] = append(m.Meta[meta], m.Trans(value...)...) + m.Meta[meta] = append(m.Meta[meta], Trans(value...)...) case "option", "append": if _, ok := m.Meta[key]; !ok { m.Meta[key] = make([]string, 0, 3) } - m.Meta[key] = append(m.Meta[key], m.Trans(value...)...) + m.Meta[key] = append(m.Meta[key], Trans(value...)...) for _, v := range m.Meta[meta] { if v == key { @@ -1606,36 +1316,25 @@ func (m *Message) Start(name string, help string, arg ...string) bool { // {{{ } // }}} -func (m *Message) Starts(name string, help string, arg ...string) bool { // {{{ - return m.Set("detail", arg...).target.Spawn(m, name, help).Begin(m).Start(m) -} +func (m *Message) Cmd(args ...interface{}) *Message { // {{{ + if len(args) > 0 { + m.Set("detail").Detail(0, args...) + } -// }}} + key := m.Meta["detail"][0] + arg := m.Meta["detail"][1:] -func (m *Message) Exec(key string, arg ...string) string { // {{{ - - for _, c := range []*Context{m.target, m.target.master, m.target.Owner, m.source, m.source.master, m.source.Owner} { + for _, c := range []*Context{m.target, m.source} { for s := c; s != nil; s = s.context { - if x, ok := s.Commands[key]; ok && x.Hand != nil && c.Check(m, "commands", key) { + if x, ok := s.Commands[key]; ok && x.Hand != nil { m.TryCatch(m, true, func(m *Message) { - m.Log("cmd", s, "%d %s %v %v", len(m.target.Historys), key, arg, m.Meta["option"]) + m.Log("cmd", s, "%s %v %v", s.Name, m.Meta["detail"], m.Meta["option"]) - if x.Options != nil { - for _, v := range m.Meta["option"] { - if _, ok := x.Options[v]; !ok { - panic(errors.New(fmt.Sprintf("未知参数: %s", v))) - } - } - } - - if m.Has("args") { - m.Meta["args"] = nil - } - if x.Form != nil { + if args := []string{}; x.Form != nil { for i := 0; i < len(arg); i++ { n, ok := x.Form[arg[i]] if !ok { - m.Add("option", "args", arg[i]) + args = append(args, arg[i]) continue } @@ -1643,113 +1342,19 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ n += len(arg) - i } - // if x, ok := m.Meta[arg[i]]; ok && len(x) == n { - // m.Add("option", "args", arg[i]) - // continue - // } - // m.Add("option", arg[i], arg[i+1:i+1+n]) i += n } - arg = m.Meta["args"] + arg = args } - m.Hand = true - // x.Hand(m.Set("result").Set("append"), s, key, arg...) x.Hand(m, s, key, arg...) - - if x.Appends != nil { - for _, v := range m.Meta["append"] { - if _, ok := x.Appends[v]; !ok { - panic(errors.New(fmt.Sprintf("未知参数: %s", v))) - } - } - } - - if m.target.Historys == nil { - m.target.Historys = make([]*Message, 0, 10) - } - m.target.Historys = append(m.target.Historys, m) + m.Hand = true }) - - return m.Get("result") + return m } } } - return "" -} - -// }}} -func (m *Message) Deal(pre func(msg *Message, arg ...string) bool, post func(msg *Message, arg ...string) bool) { // {{{ - if m.target.messages == nil { - m.target.messages = make(chan *Message, m.Confi("MessageQueueSize")) - } - - for run := true; run; { - m.TryCatch(<-m.target.messages, true, func(msg *Message) { - defer func() { - if msg.Wait != nil { - msg.Wait <- true - } - }() - - if len(msg.Meta["detail"]) == 0 { - return - } - - if pre == nil || pre(msg, msg.Meta["detail"]...) { - msg.Exec(msg.Meta["detail"][0], msg.Meta["detail"][1:]...) - } - - if post != nil && !post(msg, msg.Meta["result"]...) { - run = false - return - } - }) - } -} - -// }}} -func (m *Message) Post(s *Context, async ...bool) string { // {{{ - if s == nil { - s = m.target.master - } - - if s != nil && s.messages != nil { - if s.messages <- m; m.Wait != nil { - <-m.Wait - } - return m.Get("result") - } - - return m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...) -} - -// }}} -func (m *Message) Cmd(arg ...interface{}) *Message { // {{{ - if m.Hand { - if m.message != nil { - m = m.message.Spawn(m.target) - } else { - msg := m.Spawn(m.target) - msg.source = m.source - m = msg - } - } - - if len(arg) > 0 { - m.Set("detail") - m.Detail(0, arg...) - } - - m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...) - return m - if s, t := m.source.master, m.target.master; t != nil && s != t { - m.Post(s) - } else { - m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...) - } - return m } @@ -1845,13 +1450,9 @@ func (m *Message) Confi(key string, arg ...int) int { // {{{ func (m *Message) Conf(key string, arg ...string) string { // {{{ var hand func(m *Message, x *Config, arg ...string) string - for _, c := range []*Context{m.target, m.target.master, m.target.Owner, m.source, m.source.master, m.source.Owner} { + for _, c := range []*Context{m.target, m.source} { for s := c; s != nil; s = s.context { if x, ok := s.Configs[key]; ok { - if !m.Check(s, "configs", key) { - continue - } - switch len(arg) { case 3: if hand == nil { @@ -1875,7 +1476,7 @@ func (m *Message) Conf(key string, arg ...string) string { // {{{ } } - if len(arg) == 3 && m.Check(m.target, "configs", key) { + if len(arg) == 3 { if m.target.Configs == nil { m.target.Configs = make(map[string]*Config) } @@ -1970,13 +1571,9 @@ func (m *Message) Capi(key string, arg ...int) int { // {{{ func (m *Message) Cap(key string, arg ...string) string { // {{{ var hand func(m *Message, x *Cache, arg ...string) string - for _, c := range []*Context{m.target, m.target.master, m.target.Owner, m.source, m.source.master, m.source.Owner} { + for _, c := range []*Context{m.target, m.source} { for s := c; s != nil; s = s.context { if x, ok := s.Caches[key]; ok { - if !m.Check(s, "caches", key) { - continue - } - switch len(arg) { case 3: if hand == nil { @@ -2001,7 +1598,7 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{ } } - if len(arg) == 3 && m.Check(m.target, "caches", key) { + if len(arg) == 3 { if m.target.Caches == nil { m.target.Caches = make(map[string]*Cache) } @@ -2829,15 +2426,13 @@ var Index = &Context{Name: "ctx", Help: "模块中心", m.Echo(":") msg.target = msg.target.Owner - if msg.target != nil && msg.Check(msg.target, "caches", "username") && msg.Check(msg.target, "caches", "group") { + if msg.target != nil { m.Echo("%s:%s", msg.Cap("username"), msg.Cap("group")) } m.Echo("): ") msg.target = target - if msg.Check(msg.target, "caches", "status") && msg.Check(msg.target, "caches", "stream") { - m.Echo("%s(%s) ", msg.Cap("status"), msg.Cap("stream")) - } + m.Echo("%s(%s) ", msg.Cap("status"), msg.Cap("stream")) m.Echo("%s\n", target.Help) return true }) diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 487ff04f..b95eeddd 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -579,7 +579,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ for nfs.prompt(); !m.Options("scan_end") && bio.Scan(); nfs.prompt() { text := bio.Text() m.Capi("nread", len(text)+1) - m.Capi("nline", 1) if line += text; len(text) > 0 && text[len(text)-1] == '\\' { line = line[:len(line)-1] @@ -588,6 +587,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ nfs.history = append(nfs.history, line) msg := m.Spawn(m.Source()).Set("detail", line) + msg.Option("nline", m.Capi("nline", 1)) m.Back(msg) for _, v := range msg.Meta["result"] { @@ -1138,8 +1138,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", args = append(args, arg[1:]...) } - m.Log("info", nil, "cmd: %s %v", "git", m.Trans("-C", p, c, args)) - cmd := exec.Command("git", m.Trans("-C", p, c, args)...) + m.Log("info", nil, "cmd: %s %v", "git", ctx.Trans("-C", p, c, args)) + cmd := exec.Command("git", ctx.Trans("-C", p, c, args)...) if out, e := cmd.CombinedOutput(); e != nil { m.Echo("error: ") m.Echo("%s\n", e) diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index ec8a9d87..2f6ad7f9 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -185,7 +185,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po } // }}} -func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int) (string, []string) { // {{{ +func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line string, level int) (string, []string) { // {{{ // m.Log("debug", nil, "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line) hash, word := 0, []string{} @@ -220,7 +220,7 @@ func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int if state == nil { //嵌套语法递归解析 for i := 0; i < m.Capi("ncell"); i++ { if x := yac.mat[s][byte(i)]; i < m.Capi("nlang") && x != nil { - if l, w := yac.parse(m, i, void, line, level+1); len(w) > 0 { + if l, w := yac.parse(m, out, i, void, line, level+1); l != line { line, word = l, append(word, w...) state = x break @@ -242,7 +242,7 @@ func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int if hash == 0 { word = word[:0] } else { //执行命令 - msg := m.Spawn(m.Source()).Add("detail", yac.hand[hash], word) + msg := out.Spawn(m.Source()).Add("detail", yac.hand[hash], word) if m.Back(msg); msg.Hand { //命令替换 m.Assert(!msg.Has("return")) word = msg.Meta["result"] @@ -334,7 +334,10 @@ func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) { // {{{ //解析循环 for m.Cap("stream", nfs.Target().Name); !m.Options("scan_end"); next <- true { line := <-data - _, word := yac.parse(m, m.Optioni("page"), m.Optioni("void"), line, 1) + if len(line) == 0 { + continue + } + _, word := yac.parse(m, out, m.Optioni("page"), m.Optioni("void"), line, 1) if len(word) > 0 { word = word[:len(word)-1]