From 716f4da5c16903a45b88113754a5c62711e8cdf6 Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 12 Aug 2018 14:45:12 +0800 Subject: [PATCH] mac add ctx.Chain --- etc/init.shy | 18 +- src/contexts/cli/cli.go | 4 +- src/contexts/ctx.go | 489 +++++++++++++++++++++++++++++++++------- src/contexts/log/log.go | 176 +++------------ src/contexts/nfs/nfs.go | 10 +- src/contexts/yac/yac.go | 63 +++--- 6 files changed, 488 insertions(+), 272 deletions(-) diff --git a/etc/init.shy b/etc/init.shy index e7f45443..67890560 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -1,22 +1,12 @@ -var a = {\ - context: [hello context world]\ - message: [hello message world]\ - hi: [\ - hello\ - world\ - ]\ -} -for index $a key - echo $key - for index $a $key value - echo $key $value - end -end +login root root source etc/local.shy ~file1 history load etc/history.txt + +~shell1 alias import nfs alias send send alias dial dial +config debug on diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index b117a812..0852c197 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -46,7 +46,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server if len(arg) > 0 { // {{{ return arg[0] } - return time.Now().Format(x.Value) + return time.Now().Format(x.Value.(string)) // }}} }}, "ps_end": &ctx.Config{Name: "ps_end", Value: "> ", Help: "命令行提示符结尾"}, @@ -56,7 +56,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server } ps := make([]string, 0, 3) - for _, v := range strings.Split(x.Value, " ") { + for _, v := range strings.Split(x.Value.(string), " ") { if m.Conf(v) != "" { ps = append(ps, m.Conf(v)) } else { diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index d43346e4..6e747c3b 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -7,6 +7,7 @@ import ( // {{{ "html/template" "io" "math/rand" + "os" "regexp" "runtime/debug" "sort" @@ -59,6 +60,147 @@ func Trans(arg ...interface{}) []string { // {{{ return ls } +// }}} +func Chain(data interface{}, args ...interface{}) interface{} { // {{{ + if len(args) == 1 { + if arg, ok := args[0].([]string); ok { + args = args[:0] + for _, v := range arg { + args = append(args, v) + } + } + } + + root := data + for i := 0; i < len(args); i += 2 { + var parent interface{} + parent_key, parent_index := "", 0 + data = root + + keys := []string{} + switch arg := args[i].(type) { + case map[string]interface{}: + args = args[:0] + for k, v := range arg { + args = append(args, k, v) + } + i = -2 + continue + case []string: + keys = arg + keys = strings.Split(strings.Join(arg, "."), ".") + case string: + keys = strings.Split(arg, ".") + case nil: + continue + default: + keys = append(keys, fmt.Sprintf("%v", arg)) + } + + for j, k := range keys { + switch value := data.(type) { + case nil: + if i == len(args)-1 { + return nil + } + + if _, e := strconv.Atoi(k); e == nil { + node := []interface{}{nil} + switch p := parent.(type) { + case map[string]interface{}: + p[parent_key] = node + case []interface{}: + p[parent_index] = node + } + if data, parent_index = node, 0; j == len(keys)-1 { + node[0] = args[i+1] + } + } else { + node := map[string]interface{}{} + switch p := parent.(type) { + case map[string]interface{}: + p[parent_key] = node + case []interface{}: + p[parent_index] = node + } + if data, parent_key = node, k; j == len(keys)-1 { + node[k] = args[i+1] + } + } + + parent, data = data, nil + case []string: + if index, e := strconv.Atoi(k); e == nil { + index = (index+2+len(value)+2)%(len(value)+2) - 2 + if i == len(args)-1 { + if index < 0 { + return "" + } + return value[index] + } + switch index { + case -1: + return append([]string{args[i+1].(string)}, value...) + case -2: + return append(value, args[i+1].(string)) + default: + value[index] = args[i+1].(string) + } + } + + case map[string]string: + if i == len(args)-1 { + return value[k] + } + value[k] = args[i+1].(string) + case map[string]interface{}: + if j == len(keys)-1 { + if i == len(args)-1 { + return value[k] + } + value[k] = args[i+1] + } + parent, data, parent_key = data, value[k], k + case []interface{}: + index, e := strconv.Atoi(k) + if e != nil { + return nil + } + index = (index+2+len(value)+2)%(len(value)+2) - 2 + + if i == len(args)-1 { + if index < 0 { + return nil + } + if j == len(keys)-1 { + return value[index] + } + } else { + if index == -1 { + value = append([]interface{}{nil}, value...) + index = 0 + } else if index == -2 { + value = append(value, nil) + index = len(value) - 1 + } + + if j == len(keys)-1 { + value[index] = args[i+1] + } + } + + parent, data, parent_index = data, value[index], index + } + + if root == nil { + root = parent + } + } + } + + return root +} + // }}} type Cache struct { @@ -70,7 +212,7 @@ type Cache struct { type Config struct { Name string - Value string + Value interface{} Help string Hand func(m *Message, x *Config, arg ...string) string } @@ -162,7 +304,7 @@ func (c *Context) Begin(m *Message, arg ...string) *Context { // {{{ m.Log("begin", "%d context %v %v", m.root.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"]) for k, x := range c.Configs { if x.Hand != nil { - m.Conf(k, x.Value) + m.Conf(k, x.Value.(string)) } } @@ -185,6 +327,9 @@ func (c *Context) Start(m *Message, arg ...string) bool { // {{{ return true } + m.Sess("log", m.Sess("log")) + m.Sess("lex", m.Sess("lex")) + running := make(chan bool) go m.TryCatch(m, true, func(m *Message) { m.Log(m.Cap("status", "start"), "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"]) @@ -352,7 +497,9 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // { } } case "detail", "result": - m.Set(meta, msg.Meta[meta]...) + if len(msg.Meta[meta]) > 0 { + m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:]) + } case "option", "append": if len(arg) == 0 { arg = msg.Meta[meta] @@ -374,14 +521,13 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // { // }}} func (m *Message) Log(action string, str string, arg ...interface{}) *Message { // {{{ - if !m.Options("log") { + l := m.Sess("log", !m.Confs("compact_log")) + if l == nil || m.Detail(0) == "log" || m.Detail(0) == "write" { return m } - if l := m.Sess("log"); l != nil { - l.Options("log", false) - l.Cmd("log", action, fmt.Sprintf(str, arg...)) - } + l.Optionv("msg", m) + l.Cmd("log", action, fmt.Sprintf(str, arg...)) return m } @@ -469,17 +615,18 @@ func (m *Message) Instance(msg *Message, source ...bool) bool { // {{{ } // }}} -func (m *Message) BackTrace(hand func(m *Message) bool, c ...*Context) { // {{{ +func (m *Message) BackTrace(hand func(m *Message) bool, c ...*Context) *Message { // {{{ target := m.target if len(c) > 0 { - target = c[0] + m.target = c[0] } - for s := target; s != nil; s = s.context { + for s := m.target; s != nil; s = s.context { if m.target = s; !hand(m) { break } } m.target = target + return m } // }}} @@ -627,8 +774,13 @@ func (m *Message) Sess(key string, arg ...interface{}) *Message { // {{{ m.Sessions[key] = m.Search(value, root)[0] } return m.Sessions[key] + } + } + + if len(arg) > 0 { + switch v := arg[0].(type) { case bool: - spawn = value + spawn = v } } @@ -1176,7 +1328,7 @@ func (m *Message) Optionv(key string, arg ...interface{}) interface{} { // {{{ } for msg := m; msg != nil; msg = msg.message { - if !msg.Has(key) { + if msg.Meta == nil || !msg.Has(key) { continue } for _, k := range msg.Meta["option"] { @@ -1368,25 +1520,52 @@ func (m *Message) Confx(key string, arg ...interface{}) string { // {{{ } // }}} -func (m *Message) Confs(key string, arg ...bool) bool { // {{{ +func (m *Message) Confs(key string, arg ...interface{}) bool { // {{{ + index, value := "", m.Conf(key) if len(arg) > 0 { - if arg[0] { - m.Conf(key, "1") - } else { - m.Conf(key, "0") + switch v := arg[0].(type) { + case string: + index, arg, value = v, arg[1:], m.Conf(key, v) + case []string: + index = strings.Join(v, ".") + arg, value = arg[1:], m.Conf(key, index) } } - return Right(m.Conf(key)) + if len(arg) > 0 { + val := "0" + if t, ok := arg[0].(bool); ok && t { + val = "1" + } + + if index != "" { + value = m.Conf(key, index, val) + } else { + value = m.Conf(key, val) + } + } + + return Right(value) } // }}} -func (m *Message) Confi(key string, arg ...int) int { // {{{ - n, e := strconv.Atoi(m.Conf(key)) +func (m *Message) Confi(key string, arg ...interface{}) int { // {{{ + index, value := "", m.Conf(key) + if len(arg) > 0 { + if i, ok := arg[0].(string); ok { + arg, index, value = arg[1:], i, m.Conf(key, i) + } + } + + n, e := strconv.Atoi(value) m.Assert(e) if len(arg) > 0 { - n, e = strconv.Atoi(m.Conf(key, fmt.Sprintf("%d", arg[0]))) + if index != "" { + n, e = strconv.Atoi(m.Conf(key, index, fmt.Sprintf("%d", arg[0]))) + } else { + n, e = strconv.Atoi(m.Conf(key, fmt.Sprintf("%d", arg[0]))) + } m.Assert(e) } @@ -1394,42 +1573,94 @@ func (m *Message) Confi(key string, arg ...int) int { // {{{ } // }}} -func (m *Message) Conf(key string, arg ...string) string { // {{{ +func (m *Message) Conf(key string, args ...interface{}) string { // {{{ var hand func(m *Message, x *Config, arg ...string) string for _, c := range []*Context{m.target, m.source} { for s := c; s != nil; s = s.context { if x, ok := s.Configs[key]; ok { - switch len(arg) { - case 3: - if hand == nil { - hand = x.Hand + switch value := x.Value.(type) { + case string: + val := "" + if len(args) > 0 { + switch v := args[0].(type) { + case string: + val = v + case nil: + default: + val = fmt.Sprintf("%v", v) + + } } - case 1: - if x.Hand != nil { - x.Value = x.Hand(m, x, arg[0]) - } else { - x.Value = arg[0] + switch len(args) { + case 0: + if x.Hand != nil { + return x.Hand(m, x) + } + return value + case 1: + if x.Hand != nil { + x.Value = x.Hand(m, x, val) + } else { + x.Value = val + } + return value + default: + if hand == nil { + hand = x.Hand + } } - return x.Value - case 0: - if x.Hand != nil { - return x.Hand(m, x) + default: + values := "" + for i := 0; i < len(args); i += 2 { + if i < len(args)-1 { + m.Log("fuck", "why %v %v %v", x.Value, args[i], args[i+1]) + x.Value = Chain(x.Value, args[i], args[i+1]) + m.Log("fuck", "why %v %v %v", x.Value) + } + + if val := Chain(x.Value, args[i]); val != nil { + m.Log("fuck", "why %v", val) + values = fmt.Sprintf("%v", val) + } } - return x.Value + + if len(args) == 0 && x.Value != nil { + values = fmt.Sprintf("%T", x.Value) + } + return values } } } } - if len(arg) == 3 { + if len(args) > 0 { + m.Log("conf", "%s %v", key, args) if m.target.Configs == nil { m.target.Configs = make(map[string]*Config) } - m.target.Configs[key] = &Config{Name: arg[0], Value: arg[1], Help: arg[2], Hand: hand} - m.Log("conf", "%s %v", key, arg) - return m.Conf(key, arg[1]) + arg := Trans(args...) + if len(arg) == 3 { + m.target.Configs[key] = &Config{Name: arg[0], Value: arg[1], Help: arg[2], Hand: hand} + return m.Conf(key, arg[1]) + } + if !m.Confs("auto_make") { + return "" + } + if len(arg) == 1 { + m.target.Configs[key] = &Config{Name: key, Value: arg[0], Help: "auto make", Hand: hand} + return m.Conf(key, arg[0]) + } + + var value interface{} + for i := 0; i < len(args)-1; i += 2 { + value = Chain(value, args[i], args[i+1]) + } + m.target.Configs[key] = &Config{Name: key, Value: value, Help: "auto make", Hand: hand} + if val := Chain(key, args[len(args)-2]); val != nil { + return fmt.Sprintf("%v", val) + } } return "" @@ -1817,7 +2048,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心", "nmessage": &Cache{Name: "nmessage", Value: "0", Help: "消息数量"}, }, Configs: map[string]*Config{ - "debug": &Config{Name: "debug(on/off)", Value: "off", Help: "调试模式,on:打印,off:不打印)"}, + "chain": &Config{Name: "chain", Value: map[string]interface{}{}, Help: "调试模式,on:打印,off:不打印)"}, + "compact_log": &Config{Name: "compact_log(true/false)", Value: "true", Help: "调试模式,on:打印,off:不打印)"}, + "auto_make": &Config{Name: "auto_make(true/false)", Value: "true", Help: "调试模式,on:打印,off:不打印)"}, + "debug": &Config{Name: "debug(on/off)", Value: "off", Help: "调试模式,on:打印,off:不打印)"}, "search_method": &Config{Name: "search_method(find/search)", Value: "search", Help: "搜索方法, find: 模块名精确匹配, search: 模块名或帮助信息模糊匹配"}, "search_choice": &Config{Name: "search_choice(first/last/rand/magic)", Value: "magic", Help: "搜索匹配, first: 匹配第一个模块, last: 匹配最后一个模块, rand: 随机选择, magic: 加权选择"}, @@ -2061,6 +2295,15 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } switch arg[0] { + case "list": + ms := []*Message{msg} + for i := 0; i < len(ms); i++ { + ms = append(ms, ms[i].messages...) + m.Add("append", "code", ms[i].code) + m.Add("append", "msg", fmt.Sprintf("%s->%s: %v", ms[i].source.Name, ms[i].target.Name, ms[i].Meta["detail"])) + } + m.Sort("code", "int") + m.Table() case "message": for msg := msg; msg != nil; msg = msg.message { m.Echo("%s\n", msg.Format()) @@ -2213,7 +2456,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } if len(arg) == 1 { - m.Log("fuck", "%v", m.Meta) for msg = msg; msg != nil; msg = msg.message { for k, v := range msg.Sessions { if k == arg[0] { @@ -2222,7 +2464,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } } } - m.Log("fuck", "%v", m.Meta) return } @@ -2586,50 +2827,138 @@ var Index = &Context{Name: "ctx", Help: "模块中心", // }}} }}, "config": &Command{ - Name: "config [all|key [value]|key name value help|delete key]", + Name: "config [all] [save|load file key...] [delete] [pop index] key [value...]|key name value help", Help: "查看、读写、添加配置变量", Hand: func(m *Message, c *Context, key string, arg ...string) { - switch len(arg) { //{{{ - case 0: - for k, v := range m.target.Configs { - m.Add("append", "key", k) - m.Add("append", "value", m.Conf(k)) - m.Add("append", "name", v.Name) + all := false // {{{ + if len(arg) > 0 && arg[0] == "all" { + arg, all = arg[1:], true + } + + action, which := "", "-1" + have := map[string]bool{} + if len(arg) > 0 { + switch arg[0] { + case "pop", "delete": + action, which, arg = arg[0], arg[1], arg[2:] + case "save", "load": + action, which, arg = arg[0], arg[1], arg[2:] + for _, v := range arg { + have[v] = true + } } - m.Sort("key", "string").Table() - return - case 1: - if arg[0] == "all" { - keys := []string{} - values := map[string]*Config{} - for s := m.target; s != nil; s = s.context { - for k, v := range s.Configs { - if _, ok := values[k]; !ok { - keys = append(keys, k) - values[k] = v + } + + save := map[string]interface{}{} + if action == "load" { + f, e := os.Open(which) + m.Assert(e) + defer f.Close() + + de := json.NewDecoder(f) + de.Decode(&save) + } + + sort := "string" + m.BackTrace(func(m *Message) bool { + for k, v := range m.target.Configs { + switch action { + case "save": + if len(have) == 0 || have[k] { + save[k] = v.Value + } + case "load": + if len(have) == 0 || have[k] { + v.Value = save[k] + } + case "pop": + switch val := v.Value.(type) { + case map[string]string: + delete(val, which) + case map[string]interface{}: + delete(val, which) + case []string: + if i, e := strconv.Atoi(which); e == nil { + i = (i+2+len(val)+2)%(len(val)+2) - 2 + if i > -1 { + m.Echo(val[i]) + for i := i; i < len(val)-1; i++ { + val[i] = val[i+1] + } + val = val[:len(val)-1] + } } + v.Value = val + case []interface{}: + if i, e := strconv.Atoi(which); e == nil { + i = (i+2+len(val)+2)%(len(val)+2) - 2 + if i > -1 { + for i := i; i < len(val)-1; i++ { + val[i] = val[i+1] + } + val = val[:len(val)-1] + } + } + v.Value = val + } + case "delete": + if which == k { + delete(m.target.Configs, which) + } + default: + switch len(arg) { + case 0: + m.Add("append", "key", k) + m.Add("append", "value", m.Conf(k)) + m.Add("append", "name", v.Name) + case 1: + if k != arg[0] { + continue + } + switch val := v.Value.(type) { + case map[string]string: + for k, _ := range val { + m.Add("append", "key", k) + m.Add("append", "val", m.Conf(arg[0], k)) + } + case map[string]interface{}: + for k, _ := range val { + m.Add("append", "key", k) + m.Add("append", "val", m.Conf(arg[0], k)) + } + case []string: + sort = "int" + for i, _ := range val { + m.Add("append", "key", i) + m.Add("append", "val", m.Conf(arg[0], k)) + } + case []interface{}: + sort = "int" + for i, _ := range val { + m.Add("append", "key", i) + m.Add("append", "val", m.Conf(arg[0], k)) + } + case string: + m.Echo(m.Conf(arg[0])) + } + default: + m.Echo(m.Conf(arg[0], arg[1:])) + return false } } - sort.Strings(keys) - for _, k := range keys { - m.Echo("%s(%s): %s\n", k, m.Conf(k), values[k].Name) - } - return } - case 2: - if arg[0] == "delete" { - if _, ok := m.target.Configs[arg[1]]; ok { - delete(m.target.Configs, arg[1]) - } - return - } - m.Conf(arg[0], arg[1]) - case 3: - m.Conf(arg[0], arg[0], arg[2], arg[0]) - default: - m.Conf(arg[0], arg[1:]...) + return all + }).Sort("key", sort).Table() + + if action == "save" { + f, e := os.Create(which) + m.Assert(e) + defer f.Close() + + buf, e := json.MarshalIndent(save, "", " ") + m.Assert(e) + f.Write(buf) } - m.Echo("%s", m.Conf(arg[0])) // }}} }}, "cache": &Command{ diff --git a/src/contexts/log/log.go b/src/contexts/log/log.go index 2f23546d..2bd79f93 100644 --- a/src/contexts/log/log.go +++ b/src/contexts/log/log.go @@ -3,8 +3,7 @@ package log // {{{ import ( // {{{ "contexts" "fmt" - Log "log" - "strconv" + "os" "strings" "time" ) @@ -12,14 +11,9 @@ import ( // {{{ // }}} type LOG struct { - module map[string]map[string]bool - silent map[string]bool - color map[string]int - *Log.Logger - nfs *ctx.Message + out *os.File - *ctx.Message *ctx.Context } @@ -34,24 +28,16 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ - log.Message = m - - log.Configs["flag_date"] = &ctx.Config{Name: "输出日期", Value: "true", Help: "模块日志输出消息日期"} - log.Configs["flag_time"] = &ctx.Config{Name: "输出时间", Value: "true", Help: "模块日志输出消息时间"} - log.Configs["flag_color"] = &ctx.Config{Name: "输出颜色", Value: "true", Help: "模块日志输出颜色"} - log.Configs["flag_code"] = &ctx.Config{Name: "输出序号", Value: "true", Help: "模块日志输出消息的编号"} - log.Configs["flag_action"] = &ctx.Config{Name: "输出类型", Value: "true", Help: "模块日志类型"} - log.Configs["flag_name"] = &ctx.Config{Name: "输出名称", Value: "true", Help: "模块日志输出消息源模块与消息目的模块"} - - log.Configs["bench.log"] = &ctx.Config{Name: "日志文件", Value: "var/bench.log", Help: "模块日志输出的文件"} - + log.Configs["flag_color"] = &ctx.Config{Name: "flag_color", Value: "true", Help: "模块日志输出颜色"} + log.Configs["flag_time"] = &ctx.Config{Name: "flag_time", Value: "2006/01/02 15:04:05 ", Help: "模块日志输出颜色"} + log.Configs["bench.log"] = &ctx.Config{Name: "bench.log", Value: "var/bench.log", Help: "模块日志输出的文件"} return log } // }}} func (log *LOG) Start(m *ctx.Message, arg ...string) bool { // {{{ - log.Message = m log.nfs = m.Sess("nfs").Cmd("append", m.Confx("bench.log", arg, 0), "", "日志文件") + log.out = log.nfs.Optionv("out").(*os.File) return false } @@ -68,146 +54,58 @@ func (log *LOG) Close(m *ctx.Message, arg ...string) bool { // {{{ var Pulse *ctx.Message var Index = &ctx.Context{Name: "log", Help: "日志中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{}, + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{ + "module": &ctx.Config{Name: "module", Value: map[string]interface{}{ + "shy": map[string]interface{}{"true": true, "false": false, "one": 1, "zero": 0, "yes": "yes", "no": "no"}, + "log": map[string]interface{}{"cmd": true}, + "lex": map[string]interface{}{"cmd": true, "debug": true}, + "yac": map[string]interface{}{"cmd": true, "debug": true}, + }, Help: "模块日志输出的文件"}, + "silent": &ctx.Config{Name: "silent", Value: map[string]string{}, Help: "模块日志输出的文件"}, + "color": &ctx.Config{Name: "color", Value: map[string]string{ + "debug": "0", "error": "31", "check": "31", + "cmd": "32", "conf": "33", + "search": "35", "find": "35", "cb": "35", "lock": "35", + "begin": "36", "start": "36", "close": "36", + }, Help: "模块日志输出颜色"}, + }, Commands: map[string]*ctx.Command{ - "silent": &ctx.Command{Name: "silent [[module] level state]", Help: "查看或设置日志开关, module: 模块名, level: 日志类型, state(true/false): 是否打印日志", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{ - switch len(arg) { - case 2: - if len(arg) > 1 { - log.silent[arg[0]] = ctx.Right(arg[1]) - } - case 3: - if log.module[arg[0]] == nil { - log.module[arg[0]] = map[string]bool{} - } - log.module[arg[0]][arg[1]] = ctx.Right(arg[2]) - } - - for k, v := range log.silent { - m.Echo("%s: %t\n", k, v) - } - for k, v := range log.module { - for i, x := range v { - m.Echo("%s(%s): %t\n", k, i, x) - } - } - } // }}} - }}, - "color": &ctx.Command{Name: "color [level color]", Help: "查看或设置日志颜色, level: 日志类型, color: 文字颜色", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{ - if len(arg) > 1 { - c, e := strconv.Atoi(arg[1]) - m.Assert(e) - log.color[arg[0]] = c - } - - for k, v := range log.color { - m.Echo("\033[%dm%s: %d\033[0m\n", v, k, v) - } - } // }}} - }}, "log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{ - if s, ok := log.silent[arg[0]]; ok && s == true { + if log, ok := m.Target().Server.(*LOG); m.Assert(ok) && log.out != nil { // {{{ + if m.Confs("silent", arg[0]) { return } - msg := m.Message() - if x, ok := m.Data["msg"]; ok { - if msg, ok = x.(*ctx.Message); !ok { - msg = m.Message() - } + msg, ok := m.Optionv("msg").(*ctx.Message) + if !ok { + msg = m } - if s, ok := log.module[msg.Target().Name]; ok { - if x, ok := s[arg[0]]; ok && x { - return - } - } - - date := "" - if m.Confs("flag_date") { - date += time.Now().Format("2006/01/02 ") - } - if m.Confs("flag_time") { - date += time.Now().Format("15:04:05 ") + if m.Confs("module", fmt.Sprintf("%s.%s", msg.Target().Name, arg[0])) { + return } color := 0 - if m.Confs("flag_color") { - if c, ok := log.color[arg[0]]; ok { - color = c - } - } - - code := "" - if m.Confs("flag_code") { - code = fmt.Sprintf("%d ", msg.Code()) - } - - action := "" - if m.Confs("flag_action") { - action = fmt.Sprintf("%s", arg[0]) - - if m.Confs("flag_name") { - action = fmt.Sprintf("%s(%s->%s)", action, msg.Source().Name, msg.Target().Name) - } + if m.Confs("flag_color") && m.Confs("color", arg[0]) { + color = m.Confi("color", arg[0]) } + date := time.Now().Format(m.Conf("flag_time")) + action := fmt.Sprintf("%d %s(%s->%s)", msg.Code(), arg[0], msg.Source().Name, msg.Target().Name) cmd := strings.Join(arg[1:], "") - if log.nfs != nil { - if color > 0 { - m.Spawn(log.nfs.Target()).Cmd("write", fmt.Sprintf("%s\033[%dm%s%s %s\033[0m\n", date, color, code, action, cmd)) - } else { - m.Spawn(log.nfs.Target()).Cmd("write", fmt.Sprintf("%s%s%s %s\n", date, code, action, cmd)) - } + if color > 0 { + log.out.WriteString(fmt.Sprintf("%s\033[%dm%s %s\033[0m\n", date, color, action, cmd)) + } else { + log.out.WriteString(fmt.Sprintf("%s%s %s\n", date, action, cmd)) } } // }}} }}, }, - Index: map[string]*ctx.Context{ - "void": &ctx.Context{Name: "void", Help: "void", - Configs: map[string]*ctx.Config{ - "flag_code": &ctx.Config{}, - "flag_action": &ctx.Config{}, - "flag_name": &ctx.Config{}, - "flag_color": &ctx.Config{}, - "flag_time": &ctx.Config{}, - "flag_date": &ctx.Config{}, - }, - Commands: map[string]*ctx.Command{"log": &ctx.Command{}}, - }, - }, } func init() { log := &LOG{} log.Context = Index ctx.Index.Register(Index, log) - - log.color = map[string]int{ - "error": 31, - "check": 31, - "cmd": 32, - "conf": 33, - "search": 35, - "find": 35, - "cb": 35, - "lock": 35, - "spawn": 35, - "begin": 36, - "start": 36, - "close": 36, - "debug": 0, - } - log.silent = map[string]bool{ - // "lock": true, - } - log.module = map[string]map[string]bool{ - "log": {"cmd": true}, - "lex": {"cmd": true, "debug": true}, - "yac": {"cmd": true, "debug": true}, - } } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index e684474c..bc2f783d 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -493,7 +493,6 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ } case termbox.KeyCtrlI: - break if len(tab) == 0 { tabi = 0 prefix := string(buf) @@ -508,8 +507,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ } if tabi >= 0 && tabi < len(tab) { - rest = rest[:0] - rest = append(rest, []rune(tab[tabi])...) + rest = append(rest[:0], []rune(tab[tabi])...) tabi = (tabi + 1) % len(tab) } @@ -802,6 +800,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", "nfile": &ctx.Cache{Name: "nfile", Value: "-1", Help: "已经打开的文件数量"}, }, Configs: map[string]*ctx.Config{ + "pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "pscolor"}, "nfs_name": &ctx.Config{Name: "nfs_name", Value: "file", Help: "默认模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { if len(arg) > 0 { // {{{ return arg[0] @@ -1094,7 +1093,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", // }}} }}, "pwd": &ctx.Command{Name: "pwd", Help: "查看当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - wd, e := os.Getwd() // {{{ + if len(arg) > 0 { // {{{ + os.Chdir(arg[0]) + } + wd, e := os.Getwd() m.Assert(e) m.Echo(wd) // }}} }}, diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index 285d8c05..874d5dde 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -34,7 +34,6 @@ type YAC struct { mat []map[byte]*State state map[State]*State - *ctx.Message *ctx.Context } @@ -49,7 +48,7 @@ func (yac *YAC) name(page int) string { // {{{ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Point, []*Point) { // {{{ ss := []int{page} - sn := make([]bool, yac.Capi("nline")) + sn := make([]bool, m.Capi("nline")) points := []*Point{} ends := []*Point{} @@ -80,7 +79,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po if word[i] == "rep{" { state.star = s yac.mat[x.s][x.c] = state - yac.Log("debug", "REP(%d, %d): %v", x.s, x.c, state) + m.Log("debug", "REP(%d, %d): %v", x.s, x.c, state) } } case "mul{": @@ -105,14 +104,14 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po if yac.mat[s][c] != nil { *state = *yac.mat[s][c] } else { - yac.Capi("nnode", 1) + m.Capi("nnode", 1) } - yac.Log("debug", "GET(%d, %d): %v \033[31m(%s)\033[0m", s, c, state, word[i]) + m.Log("debug", "GET(%d, %d): %v \033[31m(%s)\033[0m", s, c, state, word[i]) if state.next == 0 { - state.next = yac.Capi("nline", 1) - 1 + state.next = m.Capi("nline", 1) - 1 yac.mat = append(yac.mat, map[byte]*State{}) - for i := 0; i < yac.Capi("nlang"); i++ { + for i := 0; i < m.Capi("nlang"); i++ { yac.mat[state.next][byte(i)] = nil } sn = append(sn, false) @@ -122,7 +121,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po ends = append(ends, &Point{s, c}) points = append(points, &Point{s, c}) - yac.Log("debug", "SET(%d, %d): %v", s, c, state) + m.Log("debug", "SET(%d, %d): %v", s, c, state) } } @@ -138,7 +137,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po } for _, s := range ss { - if s < yac.Capi("nlang") || s >= len(yac.mat) { + if s < m.Capi("nlang") || s >= len(yac.mat) { continue } @@ -151,7 +150,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po } if void { - yac.Log("debug", "DEL: %d-%d", yac.Capi("nline")-1, yac.Capi("nline", 0, s)) + m.Log("debug", "DEL: %d-%d", m.Capi("nline")-1, m.Capi("nline", 0, s)) yac.mat = yac.mat[:s] } } @@ -162,7 +161,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po *state = *yac.mat[p.s][p.c] if state.next == s { - yac.Log("debug", "GET(%d, %d): %v", p.s, p.c, state) + m.Log("debug", "GET(%d, %d): %v", p.s, p.c, state) if state.next >= len(yac.mat) { state.next = 0 } @@ -170,12 +169,12 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po state.hash = hash } yac.mat[p.s][p.c] = state - yac.Log("debug", "SET(%d, %d): %v", p.s, p.c, state) + m.Log("debug", "SET(%d, %d): %v", p.s, p.c, state) } if x, ok := yac.state[*state]; !ok { yac.state[*state] = yac.mat[p.s][p.c] - yac.Capi("nreal", 1) + m.Capi("nreal", 1) } else { yac.mat[p.s][p.c] = x } @@ -191,30 +190,32 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line m.Log("debug", "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line) } + spawn := !m.Confs("compact_lex") + hash, word := 0, []string{} for star, s := 0, page; s != 0 && len(line) > 0; { //解析空白 - lex := m.Sess("lex") - lex.Cmd("parse", line, yac.name(void)) - if lex.Result(0) == "-1" { + lex := m.Sess("lex", spawn) + if lex.Cmd("parse", line, yac.name(void)); lex.Result(0) == "-1" { break } //解析单词 line = lex.Result(1) - lex = m.Sess("lex") - lex.Cmd("parse", line, yac.name(s)) - if lex.Result(0) == "-1" { + lex = m.Sess("lex", spawn) + if lex.Cmd("parse", line, yac.name(s)); lex.Result(0) == "-1" { break } //解析状态 - c := byte(lex.Resulti(0)) + result := append([]string{}, lex.Meta["result"]...) + i, _ := strconv.Atoi(result[0]) + c := byte(i) state := yac.mat[s][c] if state != nil { //全局语法检查 - if key := m.Sess("lex").Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(2)) <= len(lex.Result(2)) { - line, word = lex.Result(1), append(word, lex.Result(2)) + if key := m.Sess("lex", spawn).Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(2)) <= len(result[2]) { + line, word = result[1], append(word, result[2]) } else { state = nil } @@ -262,7 +263,6 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line // }}} func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ - yac.Message = m c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} @@ -277,8 +277,6 @@ func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ - yac.Message = m - if len(arg) > 0 && arg[0] == "parse" { return yac } @@ -306,8 +304,6 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) { // {{{ - yac.Message = m - if len(arg) > 0 && arg[0] == "parse" { lex := m.Sess("lex") if lex.Cap("status") != "start" { @@ -374,10 +370,11 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", "nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"}, }, Configs: map[string]*ctx.Config{ - "debug": &ctx.Config{Name: "debug", Value: "false", Help: "词法集合的最大数量"}, - "ncell": &ctx.Config{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"}, - "nlang": &ctx.Config{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"}, - "label": &ctx.Config{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"}, + "compact_lex": &ctx.Config{Name: "compact_lex(true/false)", Value: "true", Help: "调试模式,on:打印,off:不打印)"}, + "debug": &ctx.Config{Name: "debug", Value: "false", Help: "词法集合的最大数量"}, + "ncell": &ctx.Config{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"}, + "nlang": &ctx.Config{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"}, + "label": &ctx.Config{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"}, "yac_name": &ctx.Config{Name: "yac_name", Value: "parse", Help: "模块名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { if len(arg) > 0 { // {{{ return arg[0] @@ -445,7 +442,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", m.Assert(page < m.Capi("nlang"), "语法集合过多") yac.mat[page] = map[byte]*State{} - for i := 0; i < yac.Capi("nlang"); i++ { + for i := 0; i < m.Capi("nlang"); i++ { yac.mat[page][byte(i)] = nil } } @@ -468,7 +465,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", // yac.train(m, page, hash, arg[2:]) yac.seed = append(yac.seed, &Seed{page, hash, arg[2:]}) - yac.Cap("stream", fmt.Sprintf("%d,%s,%s", yac.Capi("nseed", 1), yac.Cap("npage"), yac.Cap("nhash"))) + m.Cap("stream", fmt.Sprintf("%d,%s,%s", m.Capi("nseed", 1), m.Cap("npage"), m.Cap("nhash"))) } // }}} }},