diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go
index 86cf6172..99556277 100644
--- a/src/contexts/cli/cli.go
+++ b/src/contexts/cli/cli.go
@@ -27,13 +27,11 @@ type Frame struct {
list []string
}
type CLI struct {
- alias map[string][]string
- label map[string]string
- target *ctx.Context
- stack []*Frame
+ label map[string]string
+ stack []*Frame
*time.Timer
- *ctx.Context
+ Context *ctx.Context
}
func (cli *CLI) schedule(m *ctx.Message) string {
@@ -50,74 +48,16 @@ func (cli *CLI) schedule(m *ctx.Message) string {
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{
- "level": &ctx.Cache{Name: "level", Value: "0", Help: "嵌套层级"},
- "parse": &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"},
- "last_msg": &ctx.Cache{Name: "last_msg", Value: "0", Help: "前一条消息"},
- "ps_count": &ctx.Cache{Name: "ps_count", Value: "0", Help: "命令计数"},
- "ps_target": &ctx.Cache{Name: "ps_target", Value: c.Name, Help: "当前模块", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
- if len(arg) > 0 {
- if cli, ok := m.Target().Server.(*CLI); ok {
- if msg := m.Find(arg[0]); msg != nil {
- cli.target = msg.Target()
- return arg[0]
- }
- }
- }
- return x.Value
- }},
- }
- c.Configs = map[string]*ctx.Config{
- "ps_time": &ctx.Config{Name: "ps_time", Value: "[15:04:05]", Help: "当前时间", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
- if len(arg) > 0 {
- return arg[0]
- }
- return time.Now().Format(x.Value.(string))
-
- }},
- "ps_end": &ctx.Config{Name: "ps_end", Value: "> ", Help: "命令行提示符结尾"},
- "prompt": &ctx.Config{Name: "prompt(ps_count/ps_time/ps_target/ps_end/...)", Value: "ps_count ps_time ps_target ps_end", Help: "命令行提示符, 以空格分隔, 依次显示缓存或配置信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
- if len(arg) > 0 {
- return arg[0]
- }
-
- ps := make([]string, 0, 3)
- for _, v := range strings.Split(x.Value.(string), " ") {
- if m.Conf(v) != "" {
- ps = append(ps, m.Conf(v))
- } else {
- ps = append(ps, m.Cap(v))
- }
- }
- return strings.Join(ps, "")
-
- }},
+ "level": &ctx.Cache{Name: "level", Value: "0", Help: "嵌套层级"},
+ "parse": &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"},
}
- s := new(CLI)
- s.Context = c
- s.target = c
- s.alias = map[string][]string{
- "~": []string{"context"},
- "!": []string{"message"},
- ":": []string{"command"},
- "::": []string{"command", "list"},
-
- "pwd": []string{"nfs.pwd"},
- "path": []string{"nfs.path"},
- "dir": []string{"nfs.dir"},
- "git": []string{"nfs.git"},
- "brow": []string{"web.brow"},
- }
-
- return s
+ return &CLI{Context: c}
}
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
- cli.target = m.Target()
return cli
}
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
- m.Optionv("ps_target", cli.target)
- m.Option("prompt", m.Conf("prompt"))
m.Cap("stream", m.Spawn(m.Sess("yac", false).Target()).Call(func(cmd *ctx.Message) *ctx.Message {
if !m.Caps("parse") {
switch cmd.Detail(0) {
@@ -132,12 +72,14 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
}
}
- if m.Option("prompt", cmd.Cmd().Conf("prompt")); cmd.Has("return") {
- kit.Log("error", "waht ?????")
+ if cmd.Cmd(); cmd.Has("return") {
m.Options("scan_end", true)
m.Target().Close(m)
}
- m.Optionv("ps_target", cli.target)
+
+ m.Optionv("ps_target", cmd.Optionv("ps_target"))
+ m.Set("append").Copy(cmd, "append")
+ m.Set("result").Copy(cmd, "result")
return nil
}, "scan", arg).Target().Name)
@@ -148,8 +90,6 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool {
case m.Target():
case m.Source():
}
- msg := cli.Message()
- msg.Append("last_target", msg.Cap("ps_target"))
return true
}
@@ -160,13 +100,24 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
Configs: map[string]*ctx.Config{
"init_shy": &ctx.Config{Name: "init_shy", Value: "etc/init.shy", Help: "启动脚本"},
"exit_shy": &ctx.Config{Name: "exit_shy", Value: "etc/exit.shy", Help: "启动脚本"},
-
- "time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"},
- "time_close": &ctx.Config{Name: "time_close(open/close)", Value: "open", Help: "时间区间"},
-
"cmd_script": &ctx.Config{Name: "cmd_script", Value: map[string]interface{}{
"sh": "bash", "shy": "source", "py": "python",
}, Help: "系统命令超时"},
+ "alias": &ctx.Config{Name: "alias", Value: map[string]interface{}{
+ "~": []string{"context"},
+ "!": []string{"message"},
+ ":": []string{"command"},
+ "::": []string{"command", "list"},
+
+ "pwd": []string{"nfs.pwd"},
+ "path": []string{"nfs.path"},
+ "dir": []string{"nfs.dir"},
+ "git": []string{"nfs.git"},
+ "brow": []string{"web.brow"},
+ }, Help: "启动脚本"},
+
+ "time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"},
+ "time_close": &ctx.Config{Name: "time_close(open/close)", Value: "open", Help: "时间区间"},
"source_list": &ctx.Config{Name: "source_list", Value: []interface{}{}, Help: "系统命令超时"},
"system_env": &ctx.Config{Name: "system_env", Value: map[string]interface{}{}, Help: "系统命令超时"},
@@ -184,198 +135,187 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
"alias": &ctx.Command{Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名, import导入模块所有命令",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- 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)
+ switch len(arg) {
+ case 0:
+ m.Cmdy("ctx.config", "alias")
+ case 1:
+ m.Cmdy("ctx.config", "alias", arg[0])
+ default:
+ switch arg[0] {
+ case "delete":
+ alias := m.Confm("alias")
+ m.Echo("delete: %s %v\n", arg[1], alias[arg[1]])
+ delete(alias, arg[1])
+ case "import":
+ msg := m.Find(arg[1], false)
+ if msg == nil {
+ msg = m.Find(arg[1], true)
+ }
+ if msg == nil {
+ m.Echo("%s not exist", arg[1])
+ return
+ }
+
+ module := msg.Cap("module")
+ for k, _ := range msg.Target().Commands {
+ if len(k) > 0 && k[0] == '/' {
+ continue
+ }
+
+ if len(arg) == 2 {
+ m.Confv("alias", k, []string{module + "." + k})
+ m.Log("info", "import %s.%s", module, k)
+ continue
+ }
+
+ if key := k; k == arg[2] {
+ if len(arg) > 3 {
+ key = arg[3]
+ }
+ m.Confv("alias", key, []string{module + "." + k})
+ m.Log("info", "import %s.%s as %s", module, k, key)
+ break
+ }
}
- case 1:
- m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
default:
- switch arg[0] {
- case "delete":
- m.Echo("delete: %s %v\n", arg[1], cli.alias[arg[1]])
- delete(cli.alias, arg[1])
- case "import":
- msg := m.Find(arg[1], false)
- if msg == nil {
- msg = m.Find(arg[1], true)
- }
- if msg == nil {
- m.Echo("%s not exist", arg[1])
- return
- }
- m.Log("info", "import %s", arg[1])
- module := msg.Cap("module")
- for k, _ := range msg.Target().Commands {
- if len(k) > 0 && k[0] == '/' {
- continue
- }
- if len(arg) == 2 {
- cli.alias[k] = []string{module + "." + k}
- continue
- }
- if key := k; k == arg[2] {
- if len(arg) > 3 {
- key = arg[3]
- }
- cli.alias[key] = []string{module + "." + k}
- break
- }
- }
- default:
- cli.alias[arg[0]] = arg[1:]
- m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
- m.Log("info", "%s: %v", arg[0], cli.alias[arg[0]])
- }
+ m.Confv("alias", arg[0], arg[1:])
+ m.Log("info", "%s: %v", arg[0], arg[1:])
}
}
return
}},
- "cmd": &ctx.Command{Name: "cmd word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
- detail := []string{}
- if a, ok := cli.alias[arg[0]]; ok {
- detail = append(detail, a...)
- detail = append(detail, arg[1:]...)
+ "cmd": &ctx.Command{Name: "cmd word", Help: "解析命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ // 解析别名
+ detail := []string{}
+ if alias, ok := m.Confv("alias", arg[0]).([]string); ok {
+ detail, arg = append(detail, alias...), arg[1:]
+ }
+ detail = append(detail, arg...)
+
+ // 目标切换
+ if detail[0] != "context" {
+ target := m.Optionv("ps_target")
+ defer func() { m.Optionv("ps_target", target) }()
+ }
+
+ // 解析脚本
+ msg := m
+ for k, v := range m.Confv("cmd_script").(map[string]interface{}) {
+ if strings.HasSuffix(detail[0], "."+k) {
+ msg = m.Spawn(m.Optionv("ps_target"))
+ detail[0] = m.Cmdx("nfs.path", detail[0])
+ detail = append([]string{v.(string)}, detail...)
+ break
+ }
+ }
+
+ // 解析路由
+ if msg == m {
+ if routes := strings.Split(detail[0], "."); len(routes) > 1 {
+ route := strings.Join(routes[:len(routes)-1], ".")
+ if msg = m.Find(route, false); msg == nil {
+ msg = m.Find(route, true)
+ }
+
+ if msg == nil {
+ m.Echo("%s not exist", route)
+ return
+ }
+ detail[0] = routes[len(routes)-1]
} else {
- detail = append(detail, arg...)
+ msg = m.Spawn(m.Optionv("ps_target"))
}
+ }
+ msg.Copy(m, "option").Copy(m, "append")
- if detail[0] != "context" {
- target := m.Cap("ps_target")
- defer func() {
- m.Cap("ps_target", target)
- }()
- }
-
- msg := m
- for k, v := range m.Confv("cmd_script").(map[string]interface{}) {
- if strings.HasSuffix(detail[0], "."+k) {
- detail[0] = m.Sess("nfs").Cmd("path", detail[0]).Result(0)
- detail = append([]string{v.(string)}, detail...)
- msg = m.Spawn(cli.target)
+ // 解析命令
+ args, rest := []string{}, []string{}
+ exports := []map[string]string{}
+ exec, execexec := true, false
+ for i := 0; i < len(detail); i++ {
+ switch detail[i] {
+ case "?":
+ if !kit.Right(detail[i+1]) {
+ return
+ }
+ i++
+ case "??":
+ exec = false
+ execexec = execexec || kit.Right(detail[i+1])
+ i++
+ case "<":
+ m.Cmdy("nfs.import", detail[i+1])
+ i++
+ case ">":
+ exports = append(exports, map[string]string{"file": detail[i+1]})
+ i++
+ case ">$":
+ if i == len(detail)-2 {
+ exports = append(exports, map[string]string{"cache": detail[i+1], "index": "result"})
+ i += 1
break
}
- }
-
- if msg == m {
- if routes := strings.Split(detail[0], "."); len(routes) > 1 {
- route := strings.Join(routes[:len(routes)-1], ".")
- if msg = m.Find(route, false); msg == nil {
- msg = m.Find(route, true)
- }
-
- if msg == nil {
- m.Echo("%s not exist", route)
- return
- }
- detail[0] = routes[len(routes)-1]
- } else {
- msg = m.Spawn(cli.target)
+ exports = append(exports, map[string]string{"cache": detail[i+1], "index": detail[i+2]})
+ i += 2
+ case ">@":
+ if i == len(detail)-2 {
+ exports = append(exports, map[string]string{"config": detail[i+1], "index": "result"})
+ i += 1
+ break
}
+ exports = append(exports, map[string]string{"config": detail[i+1], "index": detail[i+2]})
+ i += 2
+ case "|":
+ detail, rest = detail[:i], detail[i+1:]
+ case "%":
+ rest = append(rest, "select")
+ detail, rest = detail[:i], append(rest, detail[i+1:]...)
+ default:
+ args = append(args, detail[i])
}
- msg.Copy(m, "append")
- msg.Copy(m, "option")
-
- args := []string{}
- rest := []string{}
- exec := true
- execexec := false
- exports := []map[string]string{}
- for i := 0; i < len(detail); i++ {
- switch detail[i] {
- case "?":
- if !kit.Right(detail[i+1]) {
- return
- }
- i++
- case "??":
- exec = false
- execexec = execexec || kit.Right(detail[i+1])
- i++
- case "<":
- pipe := m.Sess("nfs").Cmd("import", detail[i+1])
- msg.Copy(pipe, "append")
- i++
- case ">":
- exports = append(exports, map[string]string{"file": detail[i+1]})
- i++
- case ">$":
- if i == len(detail)-2 {
- exports = append(exports, map[string]string{"cache": detail[i+1], "index": "result"})
- i += 1
- break
- }
- exports = append(exports, map[string]string{"cache": detail[i+1], "index": detail[i+2]})
- i += 2
- case ">@":
- if i == len(detail)-2 {
- exports = append(exports, map[string]string{"config": detail[i+1], "index": "result"})
- i += 1
- break
- }
- exports = append(exports, map[string]string{"config": detail[i+1], "index": detail[i+2]})
- i += 2
- case "|":
- detail, rest = detail[:i], detail[i+1:]
- case "%":
- rest = append(rest, "select")
- detail, rest = detail[:i], append(rest, detail[i+1:]...)
- default:
- args = append(args, detail[i])
- }
- }
-
- if !exec && !execexec {
- return
- }
-
- detail = args
- msg.Set("detail", detail)
-
- if msg.Cmd(); msg.Hand {
- m.Cap("ps_target", msg.Cap("module"))
- } else {
- msg.Copy(m, "target").Copy(m, "result").Detail(-1, "system")
- msg.Cmd()
- }
-
- for _, v := range exports {
- if v["file"] != "" {
- m.Sess("nfs").Copy(msg, "option").Copy(msg, "append").Copy(msg, "result").Cmd("export", v["file"])
- }
- if v["cache"] != "" {
- if v["index"] == "result" {
- m.Cap(v["cache"], strings.Join(msg.Meta["result"], ""))
- } else {
- m.Cap(v["cache"], msg.Append(v["index"]))
- }
- }
- if v["config"] != "" {
- if v["index"] == "result" {
- m.Conf(v["config"], strings.Join(msg.Meta["result"], ""))
- } else {
- m.Conf(v["config"], msg.Append(v["index"]))
- }
- }
- }
-
- if len(rest) > 0 {
- pipe := m.Spawn().Copy(msg, "option").Copy(msg, "append").Copy(msg, "result").Cmd("cmd", rest)
-
- msg.Set("result").Set("append")
- msg.Copy(pipe, "result").Copy(pipe, "append")
- }
-
- m.Target().Message().Set("result").Set("append").Copy(msg, "result").Copy(msg, "append")
- m.Set("append").Copy(msg, "append")
- m.Set("result").Copy(msg, "result")
-
- // m.Capi("last_msg", 0, msg.Code())
- // m.Capi("ps_count", 1)
}
+ if !exec && !execexec {
+ return
+ }
+
+ // 执行命令
+ if msg.Set("detail", args).Cmd(); !msg.Hand {
+ msg.Cmd("system", args)
+ }
+
+ // 管道命令
+ if len(rest) > 0 {
+ pipe := m.Spawn().Copy(msg, "option")
+ pipe.Copy(msg, "append").Copy(msg, "result").Cmd("cmd", rest)
+ msg.Set("append").Copy(pipe, "append")
+ msg.Set("result").Copy(pipe, "result")
+ }
+
+ // 导出结果
+ for _, v := range exports {
+ if v["file"] != "" {
+ m.Sess("nfs").Copy(msg, "option").Copy(msg, "append").Copy(msg, "result").Cmd("export", v["file"])
+ }
+ if v["cache"] != "" {
+ if v["index"] == "result" {
+ m.Cap(v["cache"], strings.Join(msg.Meta["result"], ""))
+ } else {
+ m.Cap(v["cache"], msg.Append(v["index"]))
+ }
+ }
+ if v["config"] != "" {
+ if v["index"] == "result" {
+ m.Conf(v["config"], strings.Join(msg.Meta["result"], ""))
+ } else {
+ m.Conf(v["config"], msg.Append(v["index"]))
+ }
+ }
+ }
+
+ // 返回结果
+ m.Optionv("ps_target", msg.Target())
+ m.Set("append").Copy(msg, "append")
+ m.Set("result").Copy(msg, "result")
return
}},
"str": &ctx.Command{Name: "str word", Help: "解析字符串", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@@ -383,33 +323,30 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
return
}},
"exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
- switch len(arg) {
- case 1:
- m.Echo(arg[0])
- case 2:
- msg := m.Spawn(cli.target)
- switch arg[0] {
- case "$":
- m.Echo(msg.Cap(arg[1]))
- case "@":
- value := msg.Option(arg[1])
- if value == "" {
- value = msg.Conf(arg[1])
- }
+ switch len(arg) {
+ case 1:
+ m.Echo(arg[0])
+ case 2:
+ msg := m.Spawn(m.Optionv("ps_target"))
+ switch arg[0] {
+ case "$":
+ m.Echo(msg.Cap(arg[1]))
+ case "@":
+ value := msg.Option(arg[1])
+ if value == "" {
+ value = msg.Conf(arg[1])
+ }
- m.Echo(value)
- default:
- m.Echo(arg[0]).Echo(arg[1])
- }
+ m.Echo(value)
default:
- switch arg[0] {
- case "$", "@":
- m.Result(0, arg[2:len(arg)-1])
- }
+ m.Echo(arg[0]).Echo(arg[1])
}
- return
- } //}}}
+ default:
+ switch arg[0] {
+ case "$", "@":
+ m.Result(0, arg[2:len(arg)-1])
+ }
+ }
return
}},
"val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@@ -614,10 +551,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
return
}},
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if cli, ok := m.Target().Server.(*CLI); ok {
- msg := cli.Message()
- msg.Result(-2, arg[1:])
- }
m.Add("append", "return", arg[1:])
return
}},
@@ -630,6 +563,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if (len(arg) == 0 || arg[0] == "stdio") && m.Target().Name == "cli" {
// 启动终端
m.Cmd("yac.init")
+ m.Optionv("ps_target", m.Target())
if m.Start("shy", "shell", "stdio"); m.Cmds("nfs.path", m.Confx("init_shy", arg, 1)) {
// msg := m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("init_shy"))
@@ -682,10 +616,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
return
}},
"arguments": &ctx.Command{Name: "arguments", Help: "脚本参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if cli, ok := m.Source().Server.(*CLI); ok {
- msg := cli.Message().Spawn().Cmd("detail", arg)
- m.Copy(msg, "append").Copy(msg, "result")
- }
+ m.Set("result", m.Optionv("arguments"))
return
}},
"run": &ctx.Command{Name: "run", Help: "脚本参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@@ -803,45 +734,37 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
} else {
wait := make(chan bool, 1)
go func() {
- if m.Has("cmd_error") {
- if out, e := cmd.CombinedOutput(); e != nil {
- m.Echo("error: ").Echo("%s\n", e)
- m.Echo("%s\n", string(out))
- } else {
- m.Echo(string(out))
- }
- } else {
- if out, e := cmd.Output(); e != nil {
- if e == exec.ErrNotFound {
- m.Echo("error: ").Echo("not found\n")
- } else {
- m.Echo("error: ").Echo("%s\n", e)
- m.Echo("%s\n", string(out))
- }
- } else {
- switch m.Option("cmd_parse") {
- case "json":
- var data interface{}
- if json.Unmarshal(out, &data) == nil {
- msg := m.Spawn().Put("option", "data", data).Cmd("trans", "data", "")
- m.Copy(msg, "append").Copy(msg, "result")
- } else {
- m.Echo(string(out))
- }
- case "csv":
- data, e := csv.NewReader(bytes.NewReader(out)).ReadAll()
- m.Assert(e)
- for i := 1; i < len(data); i++ {
- for j := 0; j < len(data[i]); j++ {
- m.Add("append", data[0][j], data[i][j])
- }
- }
- m.Table()
- default:
+ out := bytes.NewBuffer(make([]byte, 1024))
+ err := bytes.NewBuffer(make([]byte, 1024))
+ cmd.Stdout = out
+ cmd.Stderr = err
+
+ if e := cmd.Run(); e == nil {
+ m.Echo("error: ").Echo("%s", e).Echo(string(err))
+ } else {
+
+ switch m.Option("cmd_parse") {
+ case "json":
+ var data interface{}
+ if json.Unmarshal(out, &data) == nil {
+ msg := m.Spawn().Put("option", "data", data).Cmd("trans", "data", "")
+ m.Copy(msg, "append").Copy(msg, "result")
+ } else {
m.Echo(string(out))
}
+ case "csv":
+ data, e := csv.NewReader(bytes.NewReader(out)).ReadAll()
+ m.Assert(e)
+ for i := 1; i < len(data); i++ {
+ for j := 0; j < len(data[i]); j++ {
+ m.Add("append", data[0][j], data[i][j])
+ }
+ }
+ m.Table()
+ default:
+ m.Echo(string(out))
}
}
wait <- true
diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go
index ffba1e69..b486429a 100644
--- a/src/contexts/ctx/ctx.go
+++ b/src/contexts/ctx/ctx.go
@@ -402,13 +402,24 @@ func (m *Message) Format(arg ...string) string {
meta = append(meta, fmt.Sprintf("%v", m.Meta["result"]))
case "full":
meta = append(meta, fmt.Sprintf("%s\n", m.Format("time", "ship")))
- meta = append(meta, fmt.Sprintf("detail: %s\n", m.Format("detail")))
- meta = append(meta, fmt.Sprintf("option: %s\n", m.Format("option")))
- for k, v := range m.Meta {
- meta = append(meta, fmt.Sprintf(" %s: %v\n", k, v))
+ meta = append(meta, fmt.Sprintf("detail: %d %v\n", len(m.Meta["detail"]), m.Meta["detail"]))
+ meta = append(meta, fmt.Sprintf("option: %d %v\n", len(m.Meta["option"]), m.Meta["option"]))
+ for _, k := range m.Meta["option"] {
+ if v, ok := m.Data[k]; ok {
+ meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
+ } else if v, ok := m.Meta[k]; ok {
+ meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
+ }
}
- meta = append(meta, fmt.Sprintf("append: %s\n", m.Format("append")))
- meta = append(meta, fmt.Sprintf("result: %s\n", m.Format("result")))
+ meta = append(meta, fmt.Sprintf("append: %d %v\n", len(m.Meta["append"]), m.Meta["append"]))
+ for _, k := range m.Meta["append"] {
+ if v, ok := m.Data[k]; ok {
+ meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
+ } else if v, ok := m.Meta[k]; ok {
+ meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
+ }
+ }
+ meta = append(meta, fmt.Sprintf("result: %d %v\n", len(m.Meta["result"]), m.Meta["result"]))
}
}
return strings.Join(meta, " ")
@@ -786,6 +797,7 @@ func (m *Message) Table(cbs ...func(maps map[string]string, list []string, line
if len(m.Meta[k]) > depth {
depth = len(m.Meta[k])
}
+ width[k] = len(k)
for _, v := range m.Meta[k] {
if len(v) > width[k] {
width[k] = len(v)
@@ -1062,9 +1074,9 @@ func (m *Message) Back(msg *Message) *Message {
}
if msg.Hand {
- m.Log("cb", "%d %v %v", msg.code, msg.Meta["result"], msg.Meta["append"])
+ m.Log("cbs", msg.Format("ship", "result", "append"))
} else {
- m.Log("cb", "%d %v %v", msg.code, msg.Meta["detail"], msg.Meta["option"])
+ m.Log("cbs", msg.Format("ship", "detail", "option"))
}
if sub := m.callback(msg); sub != nil && m.message != nil && m.message != m {
@@ -1073,6 +1085,10 @@ func (m *Message) Back(msg *Message) *Message {
return m
}
+func (m *Message) Backs(msg *Message) *Message {
+ m.Back(msg)
+ return msg
+}
func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg ...interface{}) *Message {
if !sync {
return m.Call(cb, arg...)
@@ -1119,11 +1135,13 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
case io.EOF:
case nil:
default:
+ m.Log("stack", "%s", msg.Format("full"))
+ m.Log("stack", "%s\n%s\n", e, string(debug.Stack()))
+
if len(hand) > 1 {
m.TryCatch(msg, safe, hand[1:]...)
} else if !safe {
m.Log("error", "%s not catch %v", msg.Format(), e)
- debug.PrintStack()
msg.Assert(e)
}
}
@@ -1382,532 +1400,9 @@ func (m *Message) Cap(key string, arg ...interface{}) string {
return cache.Value
}
-var CGI = template.FuncMap{
- "meta": func(arg ...interface{}) string {
- //meta meta [key [index]]
- if len(arg) == 0 {
- return ""
- }
-
- up := ""
-
- list := []string{}
- switch data := arg[0].(type) {
- case map[string][]string:
- if len(arg) == 1 {
- list = append(list, fmt.Sprintf("detail: %s\n", data["detail"]))
- list = append(list, fmt.Sprintf("option: %s\n", data["option"]))
- list = append(list, fmt.Sprintf("result: %s\n", data["result"]))
- list = append(list, fmt.Sprintf("append: %s\n", data["append"]))
- break
- }
- if key, ok := arg[1].(string); ok {
- if list, ok = data[key]; ok {
- arg = arg[1:]
- } else {
- return up
- }
- } else {
- return fmt.Sprintf("%v", data)
- }
- case []string:
- list = data
- default:
- if data == nil {
- return ""
- }
- return fmt.Sprintf("%v", data)
- }
-
- if len(arg) == 1 {
- return strings.Join(list, "")
- }
-
- index, ok := arg[1].(int)
- if !ok {
- return strings.Join(list, "")
- }
-
- if index >= len(list) {
- return ""
- }
- return list[index]
- },
- "sess": func(arg ...interface{}) string {
- if len(arg) == 0 {
- return ""
- }
-
- if m, ok := arg[0].(*Message); ok {
- if len(arg) == 1 {
- return fmt.Sprintf("%v", m)
- }
-
- switch which := arg[1].(type) {
- case string:
- m.Sess(which, arg[2:]...)
- return ""
- }
- }
- return ""
- },
-
- "ctx": func(arg ...interface{}) string {
- if len(arg) == 0 {
- return ""
- }
- if m, ok := arg[0].(*Message); ok {
- if len(arg) == 1 {
- return fmt.Sprintf("%v", m)
- }
-
- switch which := arg[1].(type) {
- case string:
- switch which {
- case "name":
- return fmt.Sprintf("%s", m.target.Name)
- case "help":
- return fmt.Sprintf("%s", m.target.Help)
- case "context":
- return fmt.Sprintf("%s", m.target.context.Name)
- case "contexts":
- ctx := []string{}
- for _, v := range m.target.contexts {
- ctx = append(ctx, fmt.Sprintf("%d", v.Name))
- }
- return strings.Join(ctx, " ")
- case "time":
- return m.time.Format("2006-01-02 15:04:05")
- case "source":
- return m.source.Name
- case "target":
- return m.target.Name
- case "message":
- return fmt.Sprintf("%d", m.message.code)
- case "messages":
- case "sessions":
- msg := []string{}
- for k, _ := range m.Sessions {
- msg = append(msg, fmt.Sprintf("%s", k))
- }
- return strings.Join(msg, " ")
- }
- case int:
- }
- }
- return ""
- },
- "msg": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- if m, ok := arg[0].(*Message); ok {
- if len(arg) == 1 {
- return fmt.Sprintf("%v", m.Format())
- }
-
- switch which := arg[1].(type) {
- case string:
- switch which {
- case "spawn":
- return m.Spawn()
- case "code":
- return m.code
- case "time":
- return m.time.Format("2006-01-02 15:04:05")
- case "source":
- return m.source.Name
- case "target":
- return m.target.Name
- case "message":
- return m.message
- case "messages":
- return m.messages
- case "sessions":
- return m.Sessions
- default:
- return m.Sess(which)
- }
- case int:
- ms := []*Message{m}
- for i := 0; i < len(ms); i++ {
- if ms[i].code == which {
- return ms[i]
- }
- ms = append(ms, ms[i].messages...)
- }
- }
- }
- return ""
- },
-
- "cap": func(arg ...interface{}) string {
- if len(arg) == 0 {
- return ""
- }
-
- if m, ok := arg[0].(*Message); ok {
- if len(arg) == 1 {
- return fmt.Sprintf("%v", m)
- }
-
- switch which := arg[1].(type) {
- case string:
- if len(arg) == 2 {
- return m.Cap(which)
- }
-
- switch value := arg[2].(type) {
- case string:
- return m.Cap(which, value)
- case int:
- return fmt.Sprintf("%d", m.Capi(which, value))
- case bool:
- return fmt.Sprintf("%t", m.Caps(which, value))
- default:
- return m.Cap(which, fmt.Sprintf("%v", arg[2]))
- }
- }
- }
- return ""
- },
- "conf": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- if m, ok := arg[0].(*Message); ok {
- if len(arg) == 1 {
- list := []string{}
- for k, _ := range m.target.Configs {
- list = append(list, k)
- }
- return list
- }
-
- switch which := arg[1].(type) {
- case string:
- if len(arg) == 2 {
- return m.Confv(which)
- }
- return m.Confv(which, arg[2:]...)
- }
- }
- return ""
- },
- "cmd": func(arg ...interface{}) string {
- if len(arg) == 0 {
- return ""
- }
-
- return strings.Join(Pulse.Sess("cli").Cmd(arg).Meta["result"], "")
- },
-
- "detail": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- switch m := arg[0].(type) {
- case *Message:
- if len(arg) == 1 {
- return m.Meta["detail"]
- }
-
- index := 0
- switch value := arg[1].(type) {
- case int:
- index = value
- case string:
- i, e := strconv.Atoi(value)
- m.Assert(e)
- index = i
- }
-
- if len(arg) == 2 {
- return m.Detail(index)
- }
-
- return m.Detail(index, arg[2])
- case map[string][]string:
- return strings.Join(m["detail"], "")
- case []string:
- return strings.Join(m, "")
- default:
- return m
- }
- return ""
- },
- "option": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- switch m := arg[0].(type) {
- case *Message:
- if len(arg) == 1 {
- return m.Meta["option"]
- }
-
- switch value := arg[1].(type) {
- case int:
- if 0 <= value && value < len(m.Meta["option"]) {
- return m.Meta["option"][value]
- }
- case string:
- if len(arg) == 2 {
- return m.Optionv(value)
- }
-
- switch val := arg[2].(type) {
- case int:
- if 0 <= val && val < len(m.Meta[value]) {
- return m.Meta[value][val]
- }
- }
- }
- case map[string][]string:
- if len(arg) == 1 {
- return strings.Join(m["option"], "")
- }
- switch value := arg[1].(type) {
- case string:
- return strings.Join(m[value], "")
- }
- case []string:
- return strings.Join(m, "")
- default:
- return m
- }
- return ""
- },
- "result": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- switch m := arg[0].(type) {
- case *Message:
- if len(arg) == 1 {
- return m.Meta["result"]
- }
-
- index := 0
- switch value := arg[1].(type) {
- case int:
- index = value
- case string:
- i, e := strconv.Atoi(value)
- m.Assert(e)
- index = i
- }
-
- if len(arg) == 2 {
- return m.Result(index)
- }
-
- return m.Result(index, arg[2])
- case map[string][]string:
- return strings.Join(m["result"], "")
- case []string:
- return strings.Join(m, "")
- default:
- return m
- }
- return ""
- },
- "append": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- switch m := arg[0].(type) {
- case *Message:
- if len(arg) == 1 {
- return m.Meta["append"]
- }
-
- switch value := arg[1].(type) {
- case int:
- if 0 <= value && value < len(m.Meta["append"]) {
- return m.Meta["append"][value]
- }
- case string:
- if len(arg) == 2 {
- return m.Meta[value]
- }
-
- switch val := arg[2].(type) {
- case int:
- if 0 <= val && val < len(m.Meta[value]) {
- return m.Meta[value][val]
- }
- }
- }
- case map[string][]string:
- if len(arg) == 1 {
- return strings.Join(m["append"], "")
- }
- switch value := arg[1].(type) {
- case string:
- return strings.Join(m[value], "")
- }
- case []string:
- return strings.Join(m, "")
- default:
- return m
- }
- return ""
- },
- "table": func(arg ...interface{}) []interface{} {
- if len(arg) == 0 {
- return []interface{}{}
- }
-
- switch m := arg[0].(type) {
- case *Message:
- if len(m.Meta["append"]) == 0 {
- return []interface{}{}
- }
- if len(arg) == 1 {
- data := []interface{}{}
- nrow := len(m.Meta[m.Meta["append"][0]])
- for i := 0; i < nrow; i++ {
- line := map[string]string{}
- for _, k := range m.Meta["append"] {
- line[k] = m.Meta[k][i]
- if len(m.Meta[k]) != i {
- continue
- }
- }
- data = append(data, line)
- }
-
- return data
- }
- case map[string][]string:
- if len(arg) == 1 {
- data := []interface{}{}
- nrow := len(m[m["append"][0]])
-
- for i := 0; i < nrow; i++ {
- line := map[string]string{}
- for _, k := range m["append"] {
- line[k] = m[k][i]
- }
- data = append(data, line)
- }
-
- return data
- }
- }
- return []interface{}{}
- },
-
- "list": func(arg interface{}) interface{} {
- n := 0
- switch v := arg.(type) {
- case string:
- i, e := strconv.Atoi(v)
- if e == nil {
- n = i
- }
- case int:
- n = v
- }
-
- list := make([]int, n)
- for i := 1; i <= n; i++ {
- list[i-1] = i
- }
- return list
- },
- "slice": func(list interface{}, arg ...interface{}) interface{} {
- switch l := list.(type) {
- case string:
- if len(arg) == 0 {
- return l
- }
- if len(arg) == 1 {
- return l[arg[0].(int):]
- }
- if len(arg) == 2 {
- return l[arg[0].(int):arg[1].(int)]
- }
- }
-
- return ""
- },
-
- "work": func(m *Message, arg ...interface{}) interface{} {
- switch len(arg) {
- case 0:
- list := map[string]map[string]interface{}{}
- m.Confm("auth", []string{m.Option("sessid"), "ship"}, func(key string, ship map[string]interface{}) {
- if ship["type"] == "bench" {
- if work := m.Confm("auth", key); work != nil {
- list[key] = work
- }
- }
- })
- return list
- }
- return nil
- },
-
- "unescape": func(str string) interface{} {
- return template.HTML(str)
- },
- "json": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- b, _ := json.MarshalIndent(arg[0], "", " ")
- return string(b)
- },
- "so": func(arg ...interface{}) interface{} {
- if len(arg) == 0 {
- return ""
- }
-
- cli := Pulse.Sess("cli")
- cmd := strings.Join(kit.Trans(arg), " ")
- cli.Cmd("source", cmd)
-
- result := []string{}
- if len(cli.Meta["append"]) > 0 {
- result = append(result, "
")
- result = append(result, "", cmd, "")
- cli.Table(func(maps map[string]string, list []string, line int) bool {
- if line == -1 {
- result = append(result, "")
- for _, v := range list {
- result = append(result, "", v, " | ")
- }
- result = append(result, "
")
- return true
- }
- result = append(result, "")
- for _, v := range list {
- result = append(result, "", v, " | ")
- }
- result = append(result, "
")
- return true
- })
- result = append(result, "
")
- } else {
- result = append(result, "")
- result = append(result, fmt.Sprintf("%s", cli.Find("shy", false).Conf("prompt")), cmd, "\n")
- result = append(result, cli.Meta["result"]...)
- result = append(result, "
")
- }
-
- return template.HTML(strings.Join(result, ""))
- },
+type CTX struct {
}
-var Pulse = &Message{code: 0, time: time.Now(), source: Index, target: Index, Meta: map[string][]string{}}
+
var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
Caches: map[string]*Cache{
"begin_time": &Cache{Name: "begin_time", Value: "", Help: "启动时间"},
@@ -2457,7 +1952,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
case "switch":
m.target = msg.target
case "list":
- m.Target().Travel(msg, func(msg *Message, n int) bool {
+ msg.Target().Travel(msg, func(msg *Message, n int) bool {
m.Add("append", "name", msg.target.Name)
if msg.target.context != nil {
m.Add("append", "ctx", msg.target.context.Name)
@@ -2468,7 +1963,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
m.Add("append", "status", msg.Cap("status"))
m.Add("append", "stream", msg.Cap("stream"))
m.Add("append", "help", msg.target.Help)
- return true
+ return false
})
case "spawn":
msg.target.Spawn(msg, arg[0], arg[1]).Begin(msg, arg[2:]...)
@@ -3155,8 +2650,530 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
}},
},
}
+var CGI = template.FuncMap{
+ "meta": func(arg ...interface{}) string {
+ //meta meta [key [index]]
+ if len(arg) == 0 {
+ return ""
+ }
-type CTX struct {
+ up := ""
+
+ list := []string{}
+ switch data := arg[0].(type) {
+ case map[string][]string:
+ if len(arg) == 1 {
+ list = append(list, fmt.Sprintf("detail: %s\n", data["detail"]))
+ list = append(list, fmt.Sprintf("option: %s\n", data["option"]))
+ list = append(list, fmt.Sprintf("result: %s\n", data["result"]))
+ list = append(list, fmt.Sprintf("append: %s\n", data["append"]))
+ break
+ }
+ if key, ok := arg[1].(string); ok {
+ if list, ok = data[key]; ok {
+ arg = arg[1:]
+ } else {
+ return up
+ }
+ } else {
+ return fmt.Sprintf("%v", data)
+ }
+ case []string:
+ list = data
+ default:
+ if data == nil {
+ return ""
+ }
+ return fmt.Sprintf("%v", data)
+ }
+
+ if len(arg) == 1 {
+ return strings.Join(list, "")
+ }
+
+ index, ok := arg[1].(int)
+ if !ok {
+ return strings.Join(list, "")
+ }
+
+ if index >= len(list) {
+ return ""
+ }
+ return list[index]
+ },
+ "sess": func(arg ...interface{}) string {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ if m, ok := arg[0].(*Message); ok {
+ if len(arg) == 1 {
+ return fmt.Sprintf("%v", m)
+ }
+
+ switch which := arg[1].(type) {
+ case string:
+ m.Sess(which, arg[2:]...)
+ return ""
+ }
+ }
+ return ""
+ },
+
+ "ctx": func(arg ...interface{}) string {
+ if len(arg) == 0 {
+ return ""
+ }
+ if m, ok := arg[0].(*Message); ok {
+ if len(arg) == 1 {
+ return fmt.Sprintf("%v", m)
+ }
+
+ switch which := arg[1].(type) {
+ case string:
+ switch which {
+ case "name":
+ return fmt.Sprintf("%s", m.target.Name)
+ case "help":
+ return fmt.Sprintf("%s", m.target.Help)
+ case "context":
+ return fmt.Sprintf("%s", m.target.context.Name)
+ case "contexts":
+ ctx := []string{}
+ for _, v := range m.target.contexts {
+ ctx = append(ctx, fmt.Sprintf("%d", v.Name))
+ }
+ return strings.Join(ctx, " ")
+ case "time":
+ return m.time.Format("2006-01-02 15:04:05")
+ case "source":
+ return m.source.Name
+ case "target":
+ return m.target.Name
+ case "message":
+ return fmt.Sprintf("%d", m.message.code)
+ case "messages":
+ case "sessions":
+ msg := []string{}
+ for k, _ := range m.Sessions {
+ msg = append(msg, fmt.Sprintf("%s", k))
+ }
+ return strings.Join(msg, " ")
+ }
+ case int:
+ }
+ }
+ return ""
+ },
+ "msg": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ if m, ok := arg[0].(*Message); ok {
+ if len(arg) == 1 {
+ return fmt.Sprintf("%v", m.Format())
+ }
+
+ switch which := arg[1].(type) {
+ case string:
+ switch which {
+ case "spawn":
+ return m.Spawn()
+ case "code":
+ return m.code
+ case "time":
+ return m.time.Format("2006-01-02 15:04:05")
+ case "source":
+ return m.source.Name
+ case "target":
+ return m.target.Name
+ case "message":
+ return m.message
+ case "messages":
+ return m.messages
+ case "sessions":
+ return m.Sessions
+ default:
+ return m.Sess(which)
+ }
+ case int:
+ ms := []*Message{m}
+ for i := 0; i < len(ms); i++ {
+ if ms[i].code == which {
+ return ms[i]
+ }
+ ms = append(ms, ms[i].messages...)
+ }
+ }
+ }
+ return ""
+ },
+
+ "cap": func(arg ...interface{}) string {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ if m, ok := arg[0].(*Message); ok {
+ if len(arg) == 1 {
+ return fmt.Sprintf("%v", m)
+ }
+
+ switch which := arg[1].(type) {
+ case string:
+ if len(arg) == 2 {
+ return m.Cap(which)
+ }
+
+ switch value := arg[2].(type) {
+ case string:
+ return m.Cap(which, value)
+ case int:
+ return fmt.Sprintf("%d", m.Capi(which, value))
+ case bool:
+ return fmt.Sprintf("%t", m.Caps(which, value))
+ default:
+ return m.Cap(which, fmt.Sprintf("%v", arg[2]))
+ }
+ }
+ }
+ return ""
+ },
+ "conf": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ if m, ok := arg[0].(*Message); ok {
+ if len(arg) == 1 {
+ list := []string{}
+ for k, _ := range m.target.Configs {
+ list = append(list, k)
+ }
+ return list
+ }
+
+ switch which := arg[1].(type) {
+ case string:
+ if len(arg) == 2 {
+ return m.Confv(which)
+ }
+ return m.Confv(which, arg[2:]...)
+ }
+ }
+ return ""
+ },
+ "cmd": func(arg ...interface{}) string {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ return strings.Join(Pulse.Sess("cli").Cmd(arg).Meta["result"], "")
+ },
+
+ "detail": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ switch m := arg[0].(type) {
+ case *Message:
+ if len(arg) == 1 {
+ return m.Meta["detail"]
+ }
+
+ index := 0
+ switch value := arg[1].(type) {
+ case int:
+ index = value
+ case string:
+ i, e := strconv.Atoi(value)
+ m.Assert(e)
+ index = i
+ }
+
+ if len(arg) == 2 {
+ return m.Detail(index)
+ }
+
+ return m.Detail(index, arg[2])
+ case map[string][]string:
+ return strings.Join(m["detail"], "")
+ case []string:
+ return strings.Join(m, "")
+ default:
+ return m
+ }
+ return ""
+ },
+ "option": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ switch m := arg[0].(type) {
+ case *Message:
+ if len(arg) == 1 {
+ return m.Meta["option"]
+ }
+
+ switch value := arg[1].(type) {
+ case int:
+ if 0 <= value && value < len(m.Meta["option"]) {
+ return m.Meta["option"][value]
+ }
+ case string:
+ if len(arg) == 2 {
+ return m.Optionv(value)
+ }
+
+ switch val := arg[2].(type) {
+ case int:
+ if 0 <= val && val < len(m.Meta[value]) {
+ return m.Meta[value][val]
+ }
+ }
+ }
+ case map[string][]string:
+ if len(arg) == 1 {
+ return strings.Join(m["option"], "")
+ }
+ switch value := arg[1].(type) {
+ case string:
+ return strings.Join(m[value], "")
+ }
+ case []string:
+ return strings.Join(m, "")
+ default:
+ return m
+ }
+ return ""
+ },
+ "result": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ switch m := arg[0].(type) {
+ case *Message:
+ if len(arg) == 1 {
+ return m.Meta["result"]
+ }
+
+ index := 0
+ switch value := arg[1].(type) {
+ case int:
+ index = value
+ case string:
+ i, e := strconv.Atoi(value)
+ m.Assert(e)
+ index = i
+ }
+
+ if len(arg) == 2 {
+ return m.Result(index)
+ }
+
+ return m.Result(index, arg[2])
+ case map[string][]string:
+ return strings.Join(m["result"], "")
+ case []string:
+ return strings.Join(m, "")
+ default:
+ return m
+ }
+ return ""
+ },
+ "append": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ switch m := arg[0].(type) {
+ case *Message:
+ if len(arg) == 1 {
+ return m.Meta["append"]
+ }
+
+ switch value := arg[1].(type) {
+ case int:
+ if 0 <= value && value < len(m.Meta["append"]) {
+ return m.Meta["append"][value]
+ }
+ case string:
+ if len(arg) == 2 {
+ return m.Meta[value]
+ }
+
+ switch val := arg[2].(type) {
+ case int:
+ if 0 <= val && val < len(m.Meta[value]) {
+ return m.Meta[value][val]
+ }
+ }
+ }
+ case map[string][]string:
+ if len(arg) == 1 {
+ return strings.Join(m["append"], "")
+ }
+ switch value := arg[1].(type) {
+ case string:
+ return strings.Join(m[value], "")
+ }
+ case []string:
+ return strings.Join(m, "")
+ default:
+ return m
+ }
+ return ""
+ },
+ "table": func(arg ...interface{}) []interface{} {
+ if len(arg) == 0 {
+ return []interface{}{}
+ }
+
+ switch m := arg[0].(type) {
+ case *Message:
+ if len(m.Meta["append"]) == 0 {
+ return []interface{}{}
+ }
+ if len(arg) == 1 {
+ data := []interface{}{}
+ nrow := len(m.Meta[m.Meta["append"][0]])
+ for i := 0; i < nrow; i++ {
+ line := map[string]string{}
+ for _, k := range m.Meta["append"] {
+ line[k] = m.Meta[k][i]
+ if len(m.Meta[k]) != i {
+ continue
+ }
+ }
+ data = append(data, line)
+ }
+
+ return data
+ }
+ case map[string][]string:
+ if len(arg) == 1 {
+ data := []interface{}{}
+ nrow := len(m[m["append"][0]])
+
+ for i := 0; i < nrow; i++ {
+ line := map[string]string{}
+ for _, k := range m["append"] {
+ line[k] = m[k][i]
+ }
+ data = append(data, line)
+ }
+
+ return data
+ }
+ }
+ return []interface{}{}
+ },
+
+ "list": func(arg interface{}) interface{} {
+ n := 0
+ switch v := arg.(type) {
+ case string:
+ i, e := strconv.Atoi(v)
+ if e == nil {
+ n = i
+ }
+ case int:
+ n = v
+ }
+
+ list := make([]int, n)
+ for i := 1; i <= n; i++ {
+ list[i-1] = i
+ }
+ return list
+ },
+ "slice": func(list interface{}, arg ...interface{}) interface{} {
+ switch l := list.(type) {
+ case string:
+ if len(arg) == 0 {
+ return l
+ }
+ if len(arg) == 1 {
+ return l[arg[0].(int):]
+ }
+ if len(arg) == 2 {
+ return l[arg[0].(int):arg[1].(int)]
+ }
+ }
+
+ return ""
+ },
+
+ "work": func(m *Message, arg ...interface{}) interface{} {
+ switch len(arg) {
+ case 0:
+ list := map[string]map[string]interface{}{}
+ m.Confm("auth", []string{m.Option("sessid"), "ship"}, func(key string, ship map[string]interface{}) {
+ if ship["type"] == "bench" {
+ if work := m.Confm("auth", key); work != nil {
+ list[key] = work
+ }
+ }
+ })
+ return list
+ }
+ return nil
+ },
+
+ "unescape": func(str string) interface{} {
+ return template.HTML(str)
+ },
+ "json": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ b, _ := json.MarshalIndent(arg[0], "", " ")
+ return string(b)
+ },
+ "so": func(arg ...interface{}) interface{} {
+ if len(arg) == 0 {
+ return ""
+ }
+
+ cli := Pulse.Sess("cli")
+ cmd := strings.Join(kit.Trans(arg), " ")
+ cli.Cmd("source", cmd)
+
+ result := []string{}
+ if len(cli.Meta["append"]) > 0 {
+ result = append(result, "")
+ result = append(result, "", cmd, "")
+ cli.Table(func(maps map[string]string, list []string, line int) bool {
+ if line == -1 {
+ result = append(result, "")
+ for _, v := range list {
+ result = append(result, "", v, " | ")
+ }
+ result = append(result, "
")
+ return true
+ }
+ result = append(result, "")
+ for _, v := range list {
+ result = append(result, "", v, " | ")
+ }
+ result = append(result, "
")
+ return true
+ })
+ result = append(result, "
")
+ } else {
+ result = append(result, "")
+ result = append(result, fmt.Sprintf("%s", cli.Find("shy", false).Conf("prompt")), cmd, "\n")
+ result = append(result, cli.Meta["result"]...)
+ result = append(result, "
")
+ }
+
+ return template.HTML(strings.Join(result, ""))
+ },
}
func (ctx *CTX) Spawn(m *Message, c *Context, arg ...string) Server {
@@ -3189,6 +3206,8 @@ func (ctx *CTX) Close(m *Message, arg ...string) bool {
return true
}
+var Pulse = &Message{code: 0, time: time.Now(), source: Index, target: Index, Meta: map[string][]string{}}
+
func Start(args ...string) bool {
if len(args) == 0 {
args = append(args, os.Args[1:]...)
diff --git a/src/contexts/gdb/gdb.go b/src/contexts/gdb/gdb.go
index 8a8a8488..0a10816e 100644
--- a/src/contexts/gdb/gdb.go
+++ b/src/contexts/gdb/gdb.go
@@ -2,12 +2,13 @@ package gdb
import (
"contexts/ctx"
+ "toolkit"
+
"fmt"
"io/ioutil"
"os"
"os/signal"
"syscall"
- "toolkit"
)
type GDB struct {
diff --git a/src/contexts/log/log.go b/src/contexts/log/log.go
index bbed4645..a8fe9a94 100644
--- a/src/contexts/log/log.go
+++ b/src/contexts/log/log.go
@@ -89,13 +89,15 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
Configs: map[string]*ctx.Config{
"output": &ctx.Config{Name: "output", Value: map[string]interface{}{
"error": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
+ "trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
+ "debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
+
"bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
"begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"start": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"cmd": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"},
"lex": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
},
- "debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
}, Help: "日志输出配置"},
},
Commands: map[string]*ctx.Command{
diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go
index 6ab5b4f5..5a49c1bd 100644
--- a/src/contexts/nfs/nfs.go
+++ b/src/contexts/nfs/nfs.go
@@ -239,40 +239,6 @@ func (nfs *NFS) print(str string) bool {
return true
}
-func (nfs *NFS) prompt(arg ...string) string {
- nfs.out.WriteString("> ")
- return "> "
-
- ps := nfs.Option("prompt")
- if nfs.Caps("windows") {
- nfs.color(ps)
- return ps
- }
- line, rest := "", ""
- if len(arg) > 0 {
- line = arg[0]
- }
- if len(arg) > 1 {
- rest = arg[1]
- }
-
- if !nfs.Caps("windows") && len(nfs.pages) > 0 && nfs.width > 0 {
- for i := (len(nfs.pages[len(nfs.pages)-1]) - 1) / (nfs.width); i > 0; i-- {
- nfs.escape("2K").escape("A")
- }
- nfs.escape("2K").escape("G").escape("?25h")
- }
-
- if len(nfs.pages) > 0 {
- nfs.pages = nfs.pages[:len(nfs.pages)-1]
- }
- nfs.pages = append(nfs.pages, ps+line+rest+"\n")
-
- if nfs.color(ps, nfs.Confi("pscolor")).color(line).color(rest); len(rest) > 0 {
- nfs.escape("%dD", len(rest))
- }
- return ps
-}
func (nfs *NFS) zone(buf []string, top, height int) (row, col int) {
row, col = len(buf)-1, 0
for i := nfs.Capi("cursor_pos"); i > top-1; {
@@ -558,6 +524,54 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
return
}
+func (nfs *NFS) prompt(arg ...string) string {
+ m := nfs.Context.Message()
+ target := m.Optionv("ps_target").(*ctx.Context)
+ nfs.out.WriteString(fmt.Sprintf("%d[%s]%s> ", m.Capi("ninput"), time.Now().Format("15:04:05"), target.Name))
+ return "> "
+
+ ps := nfs.Option("prompt")
+ if nfs.Caps("windows") {
+ nfs.color(ps)
+ return ps
+ }
+ line, rest := "", ""
+ if len(arg) > 0 {
+ line = arg[0]
+ }
+ if len(arg) > 1 {
+ rest = arg[1]
+ }
+
+ if !nfs.Caps("windows") && len(nfs.pages) > 0 && nfs.width > 0 {
+ for i := (len(nfs.pages[len(nfs.pages)-1]) - 1) / (nfs.width); i > 0; i-- {
+ nfs.escape("2K").escape("A")
+ }
+ nfs.escape("2K").escape("G").escape("?25h")
+ }
+
+ if len(nfs.pages) > 0 {
+ nfs.pages = nfs.pages[:len(nfs.pages)-1]
+ }
+ nfs.pages = append(nfs.pages, ps+line+rest+"\n")
+
+ if nfs.color(ps, nfs.Confi("pscolor")).color(line).color(rest); len(rest) > 0 {
+ nfs.escape("%dD", len(rest))
+ }
+ return ps
+}
+func (nfs *NFS) printf(arg ...interface{}) *NFS {
+ for _, v := range arg {
+ if nfs.io != nil {
+ fmt.Fprint(nfs.io, kit.Format(v))
+ } else if nfs.out != nil {
+ nfs.out.WriteString(kit.Format(v))
+ }
+ }
+
+ return nfs
+}
+
func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
if len(arg) > 0 && (arg[0] == "scan" || arg[0] == "open" || arg[0] == "append") {
c.Caches = map[string]*ctx.Cache{
@@ -591,7 +605,22 @@ func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server {
return nfs
}
func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
+
+ if len(arg) > 0 && (arg[0] == "open" || arg[0] == "append") {
+ nfs.out = m.Optionv("out").(*os.File)
+ nfs.in = m.Optionv("in").(*os.File)
+ m.Cap("stream", arg[1])
+
+ if s, e := nfs.in.Stat(); m.Assert(e) {
+ if m.Capi("size", int(s.Size())); arg[0] == "append" {
+ m.Capi("pos", int(s.Size()))
+ }
+ }
+ return false
+ }
+
if len(arg) > 0 && arg[0] == "scan" {
+ m.Cap("stream", arg[1])
nfs.Caches["ninput"] = &ctx.Cache{Value: "0"}
nfs.Caches["noutput"] = &ctx.Cache{Value: "0"}
nfs.Configs["input"] = &ctx.Config{Value: []interface{}{}}
@@ -609,30 +638,38 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
}
line = strings.TrimSuffix(line, "\\")
}
-
m.Confv("input", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
m.Log("debug", "%s %d %d [%s]", "input", m.Capi("ninput", 1), len(line), line)
for i := m.Capi("ninput") - 1; i < m.Capi("ninput"); i++ {
line = m.Conf("input", []interface{}{i, "line"})
- msg := m.Spawn(m.Source()).Set("detail", line).Set("option", "file_pos", i)
- m.Back(msg)
+ msg := m.Backs(m.Spawn(m.Source()).Set("detail", line).Set("option", "file_pos", i))
lines := strings.Split(strings.Join(msg.Meta["result"], ""), "\n")
- for _, line := range lines {
- if line != "" {
- m.Log("debug", "%s %d %d [%s]", "output", m.Capi("noutput", 1), len(line), line)
- m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
- nfs.print(line)
- nfs.print("\n")
+ for j := len(lines) - 1; j > 0; j-- {
+ if strings.TrimSpace(lines[j]) != "" {
+ break
}
+ lines = lines[:j]
+ }
+ for _, line := range lines {
+ m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
+ m.Log("debug", "%s %d %d [%s]", "output", m.Capi("noutput", 1), len(line), line)
+ nfs.printf(line).printf("\n")
+ }
+
+ if msg.Appends("file_pos0") {
+ i = msg.Appendi("file_pos0") - 1
+ msg.Append("file_pos0", "")
}
}
-
line = ""
}
+ if !m.Options("scan_end") {
+ m.Backs(m.Spawn(m.Source()).Set("detail", "return"))
+ }
return true
}
@@ -649,12 +686,13 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
// nfs.Configs["statusfgcolor"] = &ctx.Config{Name: "statusfgcolor", Value: "1", Help: "pscolor"}
// nfs.Configs["statusbgcolor"] = &ctx.Config{Name: "statusbgcolor", Value: "2", Help: "pscolor"}
//
- nfs.in = m.Optionv("in").(*os.File)
- bio := bufio.NewScanner(nfs)
- s, e := nfs.in.Stat()
- m.Assert(e)
- m.Capi("size", int(s.Size()))
+ // nfs.in = m.Optionv("in").(*os.File)
+ // bio := bufio.NewScanner(nfs)
+ //
+ // s, e := nfs.in.Stat()
+ // m.Assert(e)
+ // m.Capi("size", int(s.Size()))
if m.Cap("stream", arg[1]) == "stdio" {
nfs.out = m.Optionv("out").(*os.File)
@@ -689,61 +727,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
// }
// }
}
-
- line := ""
- for nfs.prompt(); !m.Options("scan_end") && bio.Scan(); nfs.prompt() {
- kit.Log("error", "stdio read %v", "text")
- text := bio.Text()
- m.Capi("nread", len(text)+1)
- kit.Log("error", "stdio read %v", text)
- continue
-
- if line += text; len(text) > 0 && text[len(text)-1] == '\\' {
- line = line[:len(line)-1]
- continue
- }
- m.Capi("nline", 1)
- m.Confv("history", -2, line)
- history := m.Confv("history").([]interface{})
-
- for i := len(history) - 1; i < len(history); i++ {
- line = history[i].(string)
-
- msg := m.Spawn(m.Source()).Set("detail", line)
- msg.Option("file_pos", i)
- m.Back(msg)
-
- for _, v := range msg.Meta["result"] {
- m.Capi("nwrite", len(v))
- nfs.print(v)
- }
- if msg.Append("file_pos0") != "" {
- i = msg.Appendi("file_pos0") - 1
- msg.Append("file_pos0", "")
- }
- }
- line = ""
- }
-
- kit.Log("error", "stdio read %v", line)
- if !m.Options("scan_end") {
- msg := m.Spawn(m.Source()).Set("detail", "return")
- m.Back(msg)
- }
- return true
- }
-
- if len(arg) > 0 && (arg[0] == "open" || arg[0] == "append") {
- nfs.out = m.Optionv("out").(*os.File)
- nfs.in = m.Optionv("in").(*os.File)
- s, e := nfs.in.Stat()
- m.Assert(e)
- m.Capi("size", int(s.Size()))
- m.Cap("stream", arg[1])
- if arg[0] == "append" {
- m.Capi("pos", int(s.Size()))
- }
- return false
}
m.Cap("stream", m.Option("stream"))
@@ -864,7 +847,7 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool {
var FileNotExist = errors.New("file not exist")
var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
Caches: map[string]*ctx.Cache{
- "nfile": &ctx.Cache{Name: "nfile", Value: "-1", Help: "已经打开的文件数量"},
+ "nfile": &ctx.Cache{Name: "nfile", Value: "0", Help: "已经打开的文件数量"},
},
Configs: map[string]*ctx.Config{
"term_simple": &ctx.Config{Name: "term_simple", Value: "false", Help: "二维码的默认大小"},
@@ -902,6 +885,86 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", "usr", "etc", ""}, Help: "文件路径"},
},
Commands: map[string]*ctx.Command{
+ "open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ if m.Has("io") {
+ } else if p, f, e := open(m, arg[0], os.O_RDWR|os.O_CREATE); e == nil {
+ m.Put("option", "in", f).Put("option", "out", f)
+ arg[0] = p
+ } else {
+ return nil
+ }
+
+ m.Start(fmt.Sprintf("file%d", m.Capi("nfile")), fmt.Sprintf("file %s", arg[0]), "open", arg[0])
+ m.Echo(arg[0])
+ return
+ }},
+ "read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil {
+ if len(arg) > 1 {
+ m.Cap("pos", arg[1])
+ }
+
+ buf := make([]byte, kit.Int(m.Confx("buf_size", arg, 0)))
+ if n, e := nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e == io.EOF || m.Assert(e) {
+ m.Capi("nread", n)
+ if m.Capi("pos", n); n == 0 {
+ m.Cap("pos", "0")
+ }
+ }
+ m.Echo(string(buf))
+ }
+ return
+ }},
+ "write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
+ if len(arg) > 1 {
+ m.Cap("pos", arg[1])
+ }
+
+ if len(arg[0]) == 0 {
+ m.Assert(nfs.out.Truncate(int64(m.Capi("pos"))))
+ m.Cap("size", m.Cap("pos"))
+ m.Cap("pos", "0")
+ } else {
+ n, e := nfs.out.WriteAt([]byte(arg[0]), int64(m.Capi("pos")))
+ if m.Capi("nwrite", n); m.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
+ m.Cap("size", m.Cap("pos"))
+ }
+ nfs.out.Sync()
+ }
+
+ m.Echo(m.Cap("pos"))
+ }
+ return
+ }},
+
+ "scan": &ctx.Command{Name: "scan file name", Help: "扫描文件, file: 文件名, name: 模块名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
+ if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" {
+ m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout).Start(arg[0], help, key, arg[0])
+ } else if p, f, e := open(m, arg[0]); m.Assert(e) {
+ m.Put("option", "in", f).Start(fmt.Sprintf("file%s", m.Capi("nfile")), help, key, p)
+ }
+ }
+ return
+ }},
+ "prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
+ nfs.prompt()
+ for _, v := range arg {
+ nfs.printf(v)
+ m.Echo(v)
+ }
+ }
+ return
+ }},
+ "printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
+ if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
+ nfs.printf(arg)
+ }
+ return
+ }},
+
"listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
@@ -942,34 +1005,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
return
}},
- "scan": &ctx.Command{Name: "scan file name", Help: "扫描文件, file: 文件名, name: 模块名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
- help := fmt.Sprintf("scan %s", arg[0])
-
- if arg[0] == "stdio" {
- m.Optionv("in", os.Stdin)
- m.Optionv("out", os.Stdout)
- m.Start(arg[0], help, key, arg[0])
- return
- }
-
- if p, f, e := open(m, arg[0]); m.Assert(e) {
- m.Optionv("in", f)
- m.Start(m.Confx("nfs_name", arg, 1), help, key, p)
- }
- }
- return
- }},
- "prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
- nfs.prompt()
- for _, v := range arg {
- nfs.out.WriteString(v)
- m.Echo(v)
- }
- }
- return
- }},
"exec": &ctx.Command{Name: "exec cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
nfs.prompt()
@@ -987,75 +1022,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}
return
}},
- "show": &ctx.Command{Name: "show arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
- for _, v := range arg {
- nfs.out.WriteString(v)
- m.Echo(v)
- }
- }
- return
- }},
-
- "open": &ctx.Command{Name: "open file name", Help: "打开文件, file: 文件名, name: 模块名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- file := arg[0]
- if m.Has("io") {
-
- } else if p, f, e := open(m, file, os.O_RDWR|os.O_CREATE); e == nil {
- m.Put("option", "in", f).Put("option", "out", f)
- file = p
- } else {
- return nil
- }
-
- m.Start(m.Confx("nfs_name", arg, 1), fmt.Sprintf("file %s", file), "open", file)
- m.Echo(file)
- return
- }},
- "read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil {
- n, e := strconv.Atoi(m.Confx("buf_size", arg, 0))
- m.Assert(e)
-
- if len(arg) > 1 {
- m.Cap("pos", arg[1])
- }
-
- buf := make([]byte, n)
- if n, e = nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e != io.EOF {
- m.Assert(e)
- }
- m.Capi("nread", n)
- m.Echo(string(buf))
-
- if m.Capi("pos", n); n == 0 {
- m.Cap("pos", "0")
- }
- }
- return
- }},
- "write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
- if len(arg) > 1 {
- m.Cap("pos", arg[1])
- }
-
- if len(arg[0]) == 0 {
- m.Assert(nfs.out.Truncate(int64(m.Capi("pos"))))
- m.Cap("size", m.Cap("pos"))
- m.Cap("pos", "0")
- } else {
- n, e := nfs.out.WriteAt([]byte(arg[0]), int64(m.Capi("pos")))
- if m.Capi("nwrite", n); m.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
- m.Cap("size", m.Cap("pos"))
- }
- nfs.out.Sync()
- }
-
- m.Echo(m.Cap("pos"))
- }
- return
- }},
"load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "加载文件, buf_size: 加载大小, pos: 加载位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if p, f, e := open(m, arg[0]); m.Assert(e) {
diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go
index 92fdf753..707fd3aa 100644
--- a/src/contexts/yac/yac.go
+++ b/src/contexts/yac/yac.go
@@ -218,9 +218,10 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line
s, star = star, 0
}
}
+
if hash == 0 {
word = word[:0]
- } else if out != nil { //执行命令
+ } else if !m.Confs("exec", []string{yac.hand[hash], "disable"}) { //执行命令
msg := out.Spawn(m.Source()).Add("detail", yac.hand[hash], word)
if m.Back(msg); msg.Hand { //命令替换
m.Assert(!msg.Has("return"))
@@ -316,6 +317,10 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
map[string]interface{}{"page": "line", "hash": "line", "word": []interface{}{"opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}"}},
}, Help: "语法集合的最大数量"},
"info": &ctx.Config{Name: "info", Value: map[string]interface{}{"ncell": 128, "nlang": 64}, Help: "嵌套层级日志的标记"},
+ "exec": &ctx.Config{Name: "info", Value: map[string]interface{}{
+ "line": map[string]interface{}{"disable": true},
+ "word": map[string]interface{}{"disable": true},
+ }, Help: "嵌套层级日志的标记"},
},
Commands: map[string]*ctx.Command{
"init": &ctx.Command{Name: "init", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
diff --git a/src/toolkit/kit.go b/src/toolkit/kit.go
index 2c33ef38..3f1308f5 100644
--- a/src/toolkit/kit.go
+++ b/src/toolkit/kit.go
@@ -94,6 +94,12 @@ func Format(arg ...interface{}) string {
result = append(result, val...)
case float64:
result = append(result, fmt.Sprintf("%d", int(val)))
+ case *os.File:
+ if s, e := val.Stat(); e == nil {
+ result = append(result, fmt.Sprintf("%T [name: %s]", v, s.Name()))
+ } else {
+ result = append(result, fmt.Sprintf("%T", v))
+ }
case time.Time:
result = append(result, fmt.Sprintf("%d", val.Format("2006-01-02 15:03:04")))
// case error: