diff --git a/etc/init.shy b/etc/init.shy index 32d2c134..74533cc8 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -1,9 +1,13 @@ -scan_file etc/demo.shy - +~cli config debug on return +scan_file etc/demo.shy +echo "who" +~web + command add get "https://chat.shylinux.com" source etc/local.shy ~aaa login root root -~web - command add get "https://chat.shylinux.com" + +~yac + scan_file etc/demo.shy demo_file diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index b3216a9b..1d35ca44 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -215,6 +215,24 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ + if len(arg) > 0 && arg[0] == "scan_file" { + cli.Context.Exit = make(chan bool) + m.Find("yac").Call(func(cmd *ctx.Message) *ctx.Message { + if cmd.Detail(0) == "scan_end" { + msg := m.Spawn() + cli.Exit <- true + m.Target().Close(msg) + return nil + } + + cmd.Source(m.Target()) + cmd.Target(m.Target()) + cmd.Cmd() + return nil + }, "scan_file", arg[1]) + return false + } + m.Sesss("cli", m) cli.Caches["#"] = &ctx.Cache{Name: "参数个数", Value: fmt.Sprintf("%d", len(arg)), Help: "参数个数"} for i, v := range arg { @@ -251,13 +269,29 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.nfs = m.Sesss("nfs", "nfs") if m.Has("stdio") { - cli.nfs.Cmd("scan", m.Cap("stream", "stdio"), m.Spawn(m.Target()).Cmd("source", m.Cap("init.shy")).Get("result")) + m.Spawn().Cmd("scan_file", m.Cap("stream", m.Cap("init.shy"))) + cli.Context.Exit = make(chan bool) + m.Find("yac").Call(func(cmd *ctx.Message) *ctx.Message { + if cmd.Detail(0) == "scan_end" { + msg := m.Spawn() + cli.Exit <- true + m.Target().Close(msg) + return nil + } + + cmd.Source(m.Target()) + cmd.Target(m.Target()) + cmd.Cmd() + return nil + }, "scan_file", m.Cap("stream", "stdio")) } else { if _, e := os.Stat(m.Cap("init.shy")); e == nil { + // m.Spawn().Cmd("scan_file", m.Cap("stream", m.Cap("init.shy"))) cli.nfs.Cmd("scan", m.Cap("stream", m.Cap("init.shy"))) } } }() + return false } m.Deal(func(msg *ctx.Message, arg ...string) bool { @@ -293,8 +327,6 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ } } } - return false - return true } @@ -839,14 +871,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Echo("%s", strings.Join(arg, "")) }}, "scan_file": &ctx.Command{Name: "scan_file", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Find("yac").Call(func(cmd *ctx.Message) *ctx.Message { - cmd.Source(m.Target()) - cmd.Target(m.Target()) - m.Log("fuck", nil, "------cmd run- %v %s", cmd.Meta, cmd.Hand) - cmd.Cmd() - m.Log("fuck", nil, "------cmd run- %v", cmd.Meta) - return nil - }, "scan_file", arg[0]) + m.Start(arg[0], "cli", "scan_file", arg[0]) + <-m.Target().Exit }}, }, Index: map[string]*ctx.Context{ diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index ead15a57..b7dffd71 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -958,7 +958,11 @@ func (m *Message) Back(msg *Message) *Message { // {{{ return m } - m.Log("cb", nil, "%d %v %v", msg.code, msg.Meta["result"], msg.Meta["append"]) + if msg.Hand { + m.Log("cb", nil, "%d %v %v", msg.code, msg.Meta["result"], msg.Meta["append"]) + } else { + m.Log("cb", nil, "%d %v %v", msg.code, msg.Meta["detail"], msg.Meta["option"]) + } m.callback.ncall++ if sub := m.callback.hand(msg); sub != nil && m.message != nil && m.message != m { diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index f06e4855..cddea159 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -93,7 +93,8 @@ func (nfs *NFS) prompt(arg ...string) { // {{{ rest = arg[1] } - if nfs.color(nfs.cli.Conf("PS1"), nfs.Confi("pscolor")).color(line).color(rest); len(rest) > 0 { + // if nfs.color(nfs.cli.Conf("PS1"), nfs.Confi("pscolor")).color(line).color(rest); len(rest) > 0 { + if fmt.Fprintf(nfs.out, "> %s%s", line, rest); len(rest) > 0 { fmt.Fprintf(nfs.out, "\033[%dD", len(rest)) } } @@ -198,8 +199,10 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ if nfs.Cap("stream") != "stdio" { return nfs.in.Read(p) } + nfs.Log("fuck", nil, "why") nfs.width, nfs.height = termbox.Size() + nfs.Log("fuck", nil, "why %d %d", nfs.width, nfs.height) buf := make([]rune, 0, 1024) rest := make([]rune, 0, 1024) @@ -435,10 +438,35 @@ func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 0 && arg[0] == "scan_file" { + if arg[1] == "stdio" { + if in, ok := m.Data["in"]; ok { + nfs.in = in.(*os.File) + } + if out, ok := m.Data["out"]; ok { + nfs.out = out.(*os.File) + } + bio := bufio.NewScanner(nfs) + nfs.Message = m + termbox.Init() + defer termbox.Close() + + m.Cap("stream", "stdio") + nfs.prompt() + for bio.Scan() { + text := bio.Text() + "; " + m.Result(0, 0, len(text)) + m.Put("append", "0", text) + m.Back(m) + nfs.prompt() + } + + return true + } + in, ok := m.Optionv("in").(*os.File) m.Assert(ok) - for { + for !m.Options("scan_end") { buf := make([]byte, m.Confi("buffer_size")) n, e := in.Read(buf) if e != nil && e != io.EOF { @@ -454,7 +482,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ break } } - return false + return true } m.Target().Sessions["nfs"] = m @@ -641,22 +669,28 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ for text = nfs.buf[pos] + "\n"; text != ""; { - line := m.Spawn(yac.Target()) - line.Optioni("pos", pos) - line.Options("stdio", true) - line.Put("option", "cli", cli.Target()) - text = line.Cmd("parse", "line", "void", text).Get("result") - cli.Target(line.Data["cli"].(*ctx.Context)) - if line.Has("return") { - goto out - } - if line.Has("back") { - pos = line.Appendi("back") + if true { + m.Result(0, 0, len(text)) + m.Put("append", fmt.Sprintf("%d", len(text)), text) + m.Back(m) + } else { + line := m.Spawn(yac.Target()) + line.Optioni("pos", pos) + line.Options("stdio", true) + line.Put("option", "cli", cli.Target()) + text = line.Cmd("parse", "line", "void", text).Get("result") + cli.Target(line.Data["cli"].(*ctx.Context)) + if line.Has("return") { + goto out + } + if line.Has("back") { + pos = line.Appendi("back") + } + if result := strings.TrimRight(strings.Join(line.Meta["result"][1:len(line.Meta["result"])-1], ""), "\n"); len(result) > 0 { + nfs.print("%s", result+"\n") + } } - if result := strings.TrimRight(strings.Join(line.Meta["result"][1:len(line.Meta["result"])-1], ""), "\n"); len(result) > 0 { - nfs.print("%s", result+"\n") - } } } @@ -714,14 +748,21 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", // }}} }}, "nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"}, - "buffer_size": &ctx.Config{Name: "buffer_size", Value: "16", Help: "缓存区大小"}, + "buffer_size": &ctx.Config{Name: "buffer_size", Value: "1024", Help: "缓存区大小"}, }, Commands: map[string]*ctx.Command{ "scan_file": &ctx.Command{Name: "scan_file filename", Help: "扫描文件, filename: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ - f, e := os.Open(arg[0]) - m.Assert(e) - m.Put("option", "in", f).Start(m.Confx("nfs_name", arg, 0), m.Confx("nfs_help", arg, 1), "scan_file", arg[0]) + if arg[0] == "stdio" { + m.Put("option", "in", os.Stdin) + m.Put("option", "out", os.Stdout) + } else { + f, e := os.Open(arg[0]) + m.Assert(e) + m.Put("option", "in", f) + } + + m.Start(m.Confx("nfs_name", arg, 0), m.Confx("nfs_help", arg, 1), "scan_file", arg[0]) } // }}} }}, "buffer": &ctx.Command{Name: "buffer [index string]", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index 9c1bb851..9fb3f556 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -3,6 +3,7 @@ package yac // {{{ import ( // {{{ "contexts" "fmt" + "io" "strconv" "strings" ) @@ -258,7 +259,8 @@ func (yac *YAC) parse(m *ctx.Message, cli *ctx.Context, page, void int, line str // }}} func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, []string) { // {{{ - m.Log("fuck", nil, "begin--%v-----%v", page, yac.word[page]) + level := m.Optioni("level2") + m.Optioni("level2", level+1) if line == "" { //加载数据 if data, ok := m.Optionv("data").(chan []byte); ok { if buf := <-data; len(buf) > 0 { @@ -266,31 +268,49 @@ func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, [ } } } + m.Assert(line != "") hash, word := 0, []string{} for star, s := 0, page; s != 0 && len(line) > 0; { - line = m.Sesss("lex", "lex").Cmd("scan", line, yac.name(void)).Result(1) - lex := m.Sesss("lex", "lex").Cmd("scan", line, yac.name(s)) - + lex := m.Sesss("lex", "lex").Cmd("scan", line, yac.name(void)) if lex.Result(0) == "-1" { //加载数据 + if next, ok := m.Optionv("next").(chan bool); ok { + next <- true + } if data, ok := m.Optionv("data").(chan []byte); ok { if buf := <-data; len(buf) > 0 { line += string(buf) continue } } - break + m.Assert(false) + } + line = lex.Result(1) + + lex = m.Sesss("lex", "lex").Cmd("scan", line, yac.name(s)) + + if lex.Result(0) == "-1" { //加载数据 + if next, ok := m.Optionv("next").(chan bool); ok { + next <- true + } + if data, ok := m.Optionv("data").(chan []byte); ok { + if buf := <-data; len(buf) > 0 { + line += string(buf) + continue + } + } + m.Assert(false) } c := byte(lex.Resulti(0)) state := yac.mat[s][c] if state != nil { //全局语法检查 - line, word = lex.Result(1), append(word, lex.Result(2)) - // if key := m.Find("lex").Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(2)) <= len(lex.Result(2)) { - // } else { - // state = nil - // } + if key := m.Sesss("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)) + } else { + state = nil + } } if state == nil { //嵌套语法递归解析 @@ -321,10 +341,11 @@ func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, [ msg := m.Spawn().Add("detail", yac.hand[hash], word...) if m.Back(msg); msg.Hand { word = msg.Meta["result"] + m.Assert(!msg.Has("return")) } } - m.Log("fuck", nil, "return--%s-----%v", line, word) + m.Optioni("level2", level) return line, word } @@ -506,18 +527,58 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ m.Optioni("page", yac.page["line"]) m.Optioni("void", yac.page["void"]) + m.Options("scan_end", false) + m.Option("level2", "1") data := make(chan []byte) + next := make(chan bool, 1) + m.Optionv("next", next) + end := make(chan bool, 1) + var out io.Writer m.Find("nfs").Call(func(nfs *ctx.Message) *ctx.Message { - buf := nfs.Appendv(nfs.Result(0)).([]byte) - data <- buf + o := nfs.Optionv("out") + if o != nil { + out = o.(io.Writer) + } + + buf := []byte{} + switch v := nfs.Appendv(nfs.Result(0)).(type) { + case []byte: + buf = v + case string: + buf = []byte(v) + } + select { + case data <- buf: + <-next + case <-end: + } return nil }, "scan_file", arg[0], "脚本解析") go func() { + defer func() { + if e := recover(); e != nil { + end <- true + m.Option("scan_end", true) + m.Back(m.Spawn().Add("detail", "scan_end")) + } + }() m.Optionv("data", data) - line, word := yac.scan(m, m.Optioni("page"), m.Optioni("void"), "") - m.Log("fuck", nil, "----%s---%v", line, word) + m.Optionv("next", next) + line := "" + word := []string{} + for { + line, word = yac.scan(m, m.Optioni("page"), m.Optioni("void"), line) + if out != nil { + for i, v := range word { + if i == len(word)-1 { + break + } + fmt.Fprintf(out, "%s", v) + } + } + } }() } // }}}