diff --git a/etc/init.shy b/etc/init.shy index ce6d67fd..211b5aea 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -7,8 +7,9 @@ function plus let a = $a + 1 end end - -~log config bench.log hi.log +~yac check +~lex check +~nfs listen ":9494" return if 2 < 1 diff --git a/src/context/ctx.go b/src/context/ctx.go index fc451c2e..cb0df356 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -74,6 +74,7 @@ type Context struct { Requests []*Message Historys []*Message Sessions map[string]*Message + Exit chan bool Index map[string]*Context Groups map[string]*Context @@ -82,7 +83,6 @@ type Context struct { password string Server - Exit chan bool } func (c *Context) Password(meta string) string { // {{{ @@ -509,7 +509,7 @@ func (m *Message) Target(s ...*Context) *Context { // {{{ // }}} var i = 0 -func (m *Message) Log(action string, ctx *Context, str string, arg ...interface{}) { +func (m *Message) Log(action string, ctx *Context, str string, arg ...interface{}) { // {{{ if !m.Options("log") { return } @@ -528,10 +528,12 @@ func (m *Message) Log(action string, ctx *Context, str string, arg ...interface{ } } -func (m *Message) Gdb(action string) { +// }}} +func (m *Message) Gdb(action string) { // {{{ } +// }}} func (m *Message) Check(s *Context, arg ...string) bool { // {{{ if s.Owner == nil { return true @@ -599,7 +601,7 @@ func (m *Message) Check(s *Context, arg ...string) bool { // {{{ } // }}} -func (m *Message) Assert(e interface{}, msg ...string) bool { +func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ switch e := e.(type) { case error: case bool: @@ -642,6 +644,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { panic(e) } +// }}} func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message)) *Message { // {{{ defer func() { if e := recover(); e != nil { @@ -819,7 +822,7 @@ func (m *Message) Start(name string, help string, arg ...string) bool { // {{{ // }}} -func (m *Message) Sess(key string, arg ...string) *Message { +func (m *Message) Sess(key string, arg ...string) *Message { // {{{ if len(arg) > 0 { root := true if len(arg) > 2 { @@ -847,6 +850,8 @@ func (m *Message) Sess(key string, arg ...string) *Message { return nil } +// }}} + func (m *Message) Add(meta string, key string, value ...string) *Message { // {{{ if m.Meta == nil { m.Meta = make(map[string][]string) @@ -885,6 +890,7 @@ func (m *Message) Set(meta string, arg ...string) *Message { // {{{ if m.Meta == nil { m.Meta = make(map[string][]string) } + switch meta { case "detail", "result": delete(m.Meta, meta) @@ -1045,7 +1051,10 @@ func (m *Message) Insert(meta string, index int, arg ...interface{}) string { // } } - return m.Meta[meta][index] + if -1 < index && index < len(m.Meta[meta]) { + return m.Meta[meta][index] + } + return "" } // }}} @@ -1084,9 +1093,10 @@ func (m *Message) Results(index int, arg ...bool) bool { // {{{ // }}} -func (m *Message) Option(key string, arg ...string) string { // {{{ - if len(arg) > 0 { - m.Set("option", append([]string{key}, arg...)...) +func (m *Message) Option(key string, arg ...interface{}) string { // {{{ + m.Insert(key, 0, arg...) + if _, ok := m.Meta[key]; ok { + m.Add("option", key) } for msg := m; msg != nil; msg = msg.message { @@ -1099,36 +1109,21 @@ func (m *Message) Option(key string, arg ...string) string { // {{{ // }}} func (m *Message) Optioni(key string, arg ...int) int { // {{{ - if len(arg) > 0 { - meta := []string{} - for _, v := range arg { - meta = append(meta, fmt.Sprintf("%d", v)) - } - m.Option(key, meta...) - } - - i, e := strconv.Atoi(m.Option(key)) + i, e := strconv.Atoi(m.Option(key, arg)) m.Assert(e) return i } // }}} func (m *Message) Options(key string, arg ...bool) bool { // {{{ - if len(arg) > 0 { - meta := []string{} - for _, v := range arg { - meta = append(meta, fmt.Sprintf("%t", v)) - } - m.Option(key, meta...) - } - - return Right(m.Option(key)) + return Right(m.Option(key, arg)) } // }}} -func (m *Message) Append(key string, arg ...string) string { // {{{ - if len(arg) > 0 { - m.Set("append", append([]string{key}, arg...)...) +func (m *Message) Append(key string, arg ...interface{}) string { // {{{ + m.Insert(key, 0, arg...) + if _, ok := m.Meta[key]; ok { + m.Add("append", key) } for msg := m; msg != nil; msg = msg.message { @@ -1141,30 +1136,14 @@ func (m *Message) Append(key string, arg ...string) string { // {{{ // }}} func (m *Message) Appendi(key string, arg ...int) int { // {{{ - if len(arg) > 0 { - meta := []string{} - for _, v := range arg { - meta = append(meta, fmt.Sprintf("%d", v)) - } - m.Append(key, meta...) - } - - i, e := strconv.Atoi(m.Append(key)) + i, e := strconv.Atoi(m.Append(key, arg)) m.Assert(e) return i } // }}} func (m *Message) Appends(key string, arg ...bool) bool { // {{{ - if len(arg) > 0 { - meta := []string{} - for _, v := range arg { - meta = append(meta, fmt.Sprintf("%t", v)) - } - m.Append(key, meta...) - } - - return Right(m.Append(key)) + return Right(m.Append(key, arg)) } // }}} @@ -1284,7 +1263,7 @@ func (m *Message) Post(s *Context, async ...bool) string { // {{{ } // }}} -func (m *Message) Cmd(arg ...interface{}) *Message { +func (m *Message) Cmd(arg ...interface{}) *Message { // {{{ if m.Hand { if m.message != nil { m = m.message.Spawn(m.target) @@ -1309,6 +1288,8 @@ func (m *Message) Cmd(arg ...interface{}) *Message { return m } +// }}} + func (m *Message) Confs(key string, arg ...bool) bool { // {{{ if len(arg) > 0 { if arg[0] { @@ -1657,7 +1638,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", }}, "option": &Command{Name: "option key val...", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { if len(arg) > 0 { // {{{ - m.Option(arg[0], arg[1:]...) + m.Option(arg[0], arg[1:]) } else { for msg := m; msg != nil; msg = msg.message { m.Echo("%d %s:%s->%s %v\n", msg.code, msg.time.Format("15:03:04"), msg.source.Name, msg.target.Name, msg.Meta["detail"]) @@ -1669,7 +1650,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", }}, "append": &Command{Name: "append key val...", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { if len(arg) > 0 { // {{{ - m.Append(arg[0], arg[1:]...) + m.Append(arg[0], arg[1:]) } else { for msg := m; msg != nil; msg = msg.message { m.Echo("%d %s:%s->%s %v\n", msg.code, msg.time.Format("15:03:04"), msg.source.Name, msg.target.Name, msg.Meta["result"]) @@ -2042,7 +2023,7 @@ func Start(args ...string) { m.target.Begin(m) } log.Println() - Pulse.Sess("log", "log").Conf("bench.log", "hi.log") + Pulse.Sess("log", "log").Conf("bench.log", "var/bench.log") for _, m := range Pulse.Search(Pulse.Conf("start")) { m.Set("detail", Pulse.Conf("init.shy")).Set("option", "stdio").target.Start(m) diff --git a/src/context/lex/lex.go b/src/context/lex/lex.go index 6c137d9f..a81007cc 100644 --- a/src/context/lex/lex.go +++ b/src/context/lex/lex.go @@ -242,7 +242,7 @@ func (lex *LEX) parse(page int, line []byte) (hash int, rest []byte, word []byte if state.star { star = s - } else if _, ok := lex.mat[star][c]; !ok { + } else if x, ok := lex.mat[star][c]; !ok || !x.star { star = 0 } @@ -255,8 +255,6 @@ func (lex *LEX) parse(page int, line []byte) (hash int, rest []byte, word []byte pos, word = 0, word[:0] } rest = line[pos:] - - lex.Log("debug", nil, "\033[31m[%v]\033[0m %d [%v]", string(word), hash, string(rest)) return } @@ -275,32 +273,46 @@ func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server { } lex.Context.Master(nil) - lex.Caches["ncell"] = &ctx.Cache{Name: "字符上限", Value: "128", Help: "字符上限"} - lex.Caches["nlang"] = &ctx.Cache{Name: "集合上限", Value: "32", Help: "集合上限"} + lex.Caches["ncell"] = &ctx.Cache{Name: "字符上限", Value: "128", Help: "字符集合的最大数量"} + lex.Caches["nlang"] = &ctx.Cache{Name: "词法上限", Value: "32", Help: "词法集合的最大数量"} - lex.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "种子数量"} - lex.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "集合数量"} - lex.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "类型数量"} + lex.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "词法模板的数量"} + lex.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "词法集合的数量"} + lex.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "单词类型的数量"} - lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "32", Help: "状态数量"} - lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "节点数量"} - lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "实点数量"} + lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "32", Help: "状态机状态的数量"} + lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"} + lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"} - lex.Configs["compact"] = &ctx.Config{Name: "紧凑模式", Value: "true", Help: "实点数量"} + lex.Configs["compact"] = &ctx.Config{Name: "紧凑模式", Value: "true", Help: "词法状态的共用"} - return lex -} + if len(arg) > 0 { + if _, e := strconv.Atoi(arg[0]); lex.Assert(e) { + lex.Cap("nlang", arg[0]) + lex.Cap("nline", arg[0]) + } + } -func (lex *LEX) Start(m *ctx.Message, arg ...string) bool { - lex.Context.Master(nil) - lex.Message = m - - lex.seed = make([]*Seed, 0, 9) lex.page = map[string]int{"nil": 0} lex.hash = map[string]int{"nil": 0} lex.mat = make([]map[byte]*State, lex.Capi("nlang")) lex.state = make(map[State]*State) + + lex.char = map[byte][]byte{ + 't': []byte{'\t'}, + 'n': []byte{'\n'}, + 'b': []byte{'\t', ' '}, + 's': []byte{'\t', ' ', '\n'}, + 'd': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, + 'x': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'}, + } + + return lex +} + +func (lex *LEX) Start(m *ctx.Message, arg ...string) bool { + lex.Message = m return false } @@ -344,8 +356,9 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心", page = lex.index("npage", arg[1]) } - hash, word, rest := lex.parse(page, []byte(arg[0])) - m.Result(0, hash, string(word), string(rest)) + hash, rest, word := lex.parse(page, []byte(arg[0])) + m.Result(0, hash, string(rest), string(word)) + lex.Log("debug", nil, "\033[31m[%v]\033[0m %d [%v]", string(word), hash, string(rest)) } }}, "split": &ctx.Command{Name: "split line page void help", Help: "分割语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -425,13 +438,4 @@ func init() { lex := &LEX{} lex.Context = Index ctx.Index.Register(Index, lex) - - lex.char = map[byte][]byte{ - 't': []byte{'\t'}, - 'n': []byte{'\n'}, - 'b': []byte{'\t', ' '}, - 's': []byte{'\t', ' ', '\n'}, - 'd': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, - 'x': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'}, - } } diff --git a/src/context/nfs/nfs.go b/src/context/nfs/nfs.go index bfb34f2f..1947b7f6 100644 --- a/src/context/nfs/nfs.go +++ b/src/context/nfs/nfs.go @@ -1,42 +1,54 @@ -package nfs // {{{ -// }}} -import ( // {{{ +package nfs + +import ( "context" "bufio" "fmt" "github.com/skip2/go-qrcode" "io" + "net/url" "os" "strconv" "strings" ) -// }}} - type NFS struct { + io io.ReadWriteCloser + *bufio.Reader + *bufio.Writer + send map[string]*ctx.Message + in *os.File out *os.File buf []string + *ctx.Context } -func (nfs *NFS) print(str string, arg ...interface{}) bool { // {{{ - if nfs.out == nil { +func (nfs *NFS) print(str string, arg ...interface{}) bool { + switch { + case nfs.io != nil: + fmt.Fprintf(nfs.io, str, arg...) + case nfs.out != nil: + fmt.Fprintf(nfs.out, str, arg...) + default: return false } - - fmt.Fprintf(nfs.out, str, arg...) return true } -// }}} - func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { c.Caches = map[string]*ctx.Cache{ "pos": &ctx.Cache{Name: "读写位置", Value: "0", Help: "读写位置"}, "nline": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}, "return": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}, + + "nsend": &ctx.Cache{Name: "消息发送数量", Value: "0", Help: "消息发送数量"}, + "nrecv": &ctx.Cache{Name: "消息接收数量", Value: "0", Help: "消息接收数量"}, + "target": &ctx.Cache{Name: "消息接收模块", Value: "ssh", Help: "消息接收模块"}, + "result": &ctx.Cache{Name: "前一条指令执行结果", Value: "", Help: "前一条指令执行结果"}, + "sessid": &ctx.Cache{Name: "会话令牌", Value: "", Help: "会话令牌"}, } c.Configs = map[string]*ctx.Config{} @@ -55,7 +67,7 @@ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server } -func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { nfs.Context.Master(nil) if nfs.Context == Index { Pulse = m @@ -63,14 +75,84 @@ func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ return nfs } -// }}} func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { - if out, ok := m.Data["out"]; ok { - nfs.out = out.(*os.File) + if socket, ok := m.Data["io"]; ok { + nfs.io = socket.(io.ReadWriteCloser) + nfs.Reader = bufio.NewReader(nfs.io) + nfs.Writer = bufio.NewWriter(nfs.io) + nfs.send = make(map[string]*ctx.Message) + + target, msg := m.Target(), m.Spawn(m.Target()) + + for { + line, e := nfs.Reader.ReadString('\n') + m.Assert(e) + + if line = strings.TrimSpace(line); len(line) == 0 { + if msg.Log("info", nil, "remote: %v", msg.Meta["option"]); msg.Has("detail") { + msg.Log("info", nil, "%d exec: %v", m.Capi("nrecv", 1), msg.Meta["detail"]) + + msg.Cmd(msg.Meta["detail"]) + target = msg.Target() + m.Cap("target", target.Name) + + for _, v := range msg.Meta["result"] { + fmt.Fprintf(nfs.Writer, "result: %s\n", url.QueryEscape(v)) + } + + fmt.Fprintf(nfs.Writer, "nsend: %s\n", msg.Get("nrecv")) + for _, k := range msg.Meta["append"] { + for _, v := range msg.Meta[k] { + fmt.Fprintf(nfs.Writer, "%s: %s\n", k, v) + } + } + fmt.Fprintf(nfs.Writer, "\n") + nfs.Writer.Flush() + + if msg.Has("io") { + if f, ok := msg.Data["io"].(io.ReadCloser); ok { + io.Copy(nfs.Writer, f) + nfs.Writer.Flush() + f.Close() + } + } + } else { + msg.Log("info", nil, "%s echo: %v", msg.Get("nsend"), msg.Meta["result"]) + + m.Cap("result", msg.Get("result")) + msg.Meta["append"] = msg.Meta["option"] + send := nfs.send[msg.Get("nsend")] + send.Meta = msg.Meta + + if send.Has("io") { + if f, ok := send.Data["io"].(io.WriteCloser); ok { + io.CopyN(f, nfs.Reader, int64(send.Appendi("size"))) + f.Close() + } + } + + send.Recv <- true + } + msg = m.Spawn(target) + continue + } + + ls := strings.SplitN(line, ":", 2) + ls[0] = strings.TrimSpace(ls[0]) + ls[1], e = url.QueryUnescape(strings.TrimSpace(ls[1])) + m.Assert(e) + msg.Add("option", ls[0], ls[1]) + + } + return true } + if in, ok := m.Data["in"]; ok { nfs.in = in.(*os.File) } + if out, ok := m.Data["out"]; ok { + nfs.out = out.(*os.File) + } if len(arg) > 1 { if m.Cap("stream", arg[1]); arg[0] == "open" { return false @@ -172,7 +254,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } // }}} }}, "copy": &ctx.Command{Name: "copy name [begin [end]]", Help: "复制文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && len(nfs.buf) > 0 { + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && len(nfs.buf) > 0 { // {{{ begin, end := 0, len(nfs.buf) if len(arg) > 1 { i, e := strconv.Atoi(arg[1]) @@ -186,7 +268,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } m.Put("option", "buf", nfs.buf[begin:end]) m.Start(arg[0], "扫描文件", key) - } + } // }}} }}, "scan": &ctx.Command{Name: "scan file", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if arg[0] == "stdio" { // {{{ @@ -202,8 +284,134 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } // }}} }}, + + "listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + tcp := m.Sess("tcp") // {{{ + if tcp == nil { + tcp = m.Sess("tcp", "tcp") + } + m.Assert(tcp != nil) + tcp.Cmd(m.Meta["detail"]) + // }}} + }}, + "dial": &ctx.Command{Name: "dial args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + tcp := m.Sess("tcp") // {{{ + if tcp == nil { + tcp = m.Sess("tcp", "tcp") + } + m.Assert(tcp != nil) + tcp.Cmd(m.Meta["detail"]) + // }}} + }}, + "send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { + if m.Has("nrecv") { + if len(arg) > 1 && arg[0] == "file" { + info, e := os.Stat(arg[1]) + m.Assert(e) + m.Append("name", info.Name()) + m.Append("size", info.Size()) + m.Append("time", info.ModTime()) + m.Append("mode", info.Mode()) + + f, e := os.Open(arg[1]) + m.Assert(e) + m.Put("append", "io", f) + } + + } else { + nfs.send[m.Option("nrecv", m.Capi("nsend", 1))] = m + + if len(arg) > 1 && arg[0] == "file" { + info, e := os.Stat(arg[1]) + m.Assert(e) + m.Option("name", info.Name()) + m.Option("size", info.Size()) + m.Option("time", info.ModTime()) + m.Option("mode", info.Mode()) + + fmt.Fprintf(nfs.Writer, "detail: recv\n") + } + for _, v := range arg { + fmt.Fprintf(nfs.Writer, "detail: %v\n", v) + } + + for _, k := range m.Meta["option"] { + if k == "args" { + continue + } + for _, v := range m.Meta[k] { + fmt.Fprintf(nfs.Writer, "%s: %s\n", k, v) + } + } + + fmt.Fprintf(nfs.Writer, "\n") + nfs.Writer.Flush() + + if true { + if len(arg) > 1 && arg[0] == "file" { + f, e := os.Open(arg[1]) + m.Assert(e) + defer f.Close() + n, e := io.Copy(nfs.Writer, f) + m.Log("fuck", nil, "write %d %v", n, e) + } + } + + m.Recv = make(chan bool) + <-m.Recv + } + } + }}, + "recv": &ctx.Command{Name: "recv [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { + if m.Has("nrecv") { + if len(arg) > 1 && arg[0] == "file" { + f, e := os.Create(arg[1]) + m.Assert(e) + defer f.Close() + io.CopyN(f, nfs.Reader, int64(m.Optioni("size"))) + } + + return + } + + nfs.send[m.Option("nrecv", m.Capi("nsend", 1))] = m + + if len(arg) > 1 && arg[0] == "file" { + f, e := os.Create(arg[1]) + m.Assert(e) + m.Put("option", "io", f) + + fmt.Fprintf(nfs.Writer, "detail: send\n") + } + + for _, v := range arg { + fmt.Fprintf(nfs.Writer, "detail: %v\n", v) + } + + for _, k := range m.Meta["option"] { + if k == "args" { + continue + } + for _, v := range m.Meta[k] { + fmt.Fprintf(nfs.Writer, "%s: %s\n", k, v) + } + } + + fmt.Fprintf(nfs.Writer, "\n") + nfs.Writer.Flush() + + m.Recv = make(chan bool) + <-m.Recv + } + }}, "open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if f, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE, os.ModePerm); m.Assert(e) { // {{{ + if m.Has("io") { // {{{ + m.Put("option", "io", m.Data["io"]) + m.Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "打开文件", m.Meta["detail"]...) + m.Echo(m.Target().Name) + } else if f, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE, os.ModePerm); m.Assert(e) { m.Put("option", "in", f).Put("option", "out", f) m.Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "打开文件", m.Meta["detail"]...) m.Echo(m.Target().Name) @@ -290,6 +498,12 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, arg[0]) // }}} }}, + + "pwd": &ctx.Command{Name: "pwd", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + wd, e := os.Getwd() + m.Assert(e) + m.Echo(wd) + }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", diff --git a/src/context/tcp/tcp.go b/src/context/tcp/tcp.go index aaeffaf0..8ada84e9 100644 --- a/src/context/tcp/tcp.go +++ b/src/context/tcp/tcp.go @@ -29,6 +29,7 @@ func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server } func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { + tcp.Context.Master(nil) if tcp.Context == Index { Pulse = m } @@ -48,7 +49,7 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { switch arg[0] { case "dial": - if m.Cap("security") != "false" { + if m.Caps("security") { cert, e := tls.LoadX509KeyPair(m.Conf("cert"), m.Conf("key")) m.Assert(e) conf := &tls.Config{Certificates: []tls.Certificate{cert}} @@ -62,18 +63,18 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { tcp.Conn = c } - msg := m.Reply("open").Put("option", "io", tcp.Conn) - msg.Cmd("open") - m.Log("info", nil, "%s dial %s", Pulse.Cap("nclient"), msg.Cap("stream", m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())))) + msg := m.Reply("open").Put("option", "io", tcp.Conn).Cmd("open") + m.Log("info", nil, "%s dial %s", Pulse.Cap("nclient"), + msg.Cap("stream", m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())))) return false case "accept": c, e := m.Data["io"].(net.Conn) m.Assert(e) tcp.Conn = c - msg := m.Spawn(m.Data["source"].(*ctx.Context), "open").Put("option", "io", tcp.Conn) - msg.Cmd("open") - m.Log("info", nil, "%s accept %s", Pulse.Cap("nclient"), msg.Cap("stream", m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))) + msg := m.Spawn(m.Data["source"].(*ctx.Context), "open").Put("option", "io", tcp.Conn).Cmd("open") + m.Log("info", nil, "%s accept %s", Pulse.Cap("nclient"), + msg.Cap("stream", m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))) return false default: if m.Cap("security") != "false" { @@ -96,7 +97,9 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { for { c, e := tcp.Accept() m.Assert(e) - m.Spawn(Index).Put("option", "io", c).Put("option", "source", m.Source()).Start(fmt.Sprintf("com%d", Pulse.Capi("nclient", 1)), "网络连接", "accept", c.RemoteAddr().String()) + msg := m.Spawn(Index).Put("option", "io", c).Put("option", "source", m.Source()) + msg.Start(fmt.Sprintf("com%d", Pulse.Capi("nclient", 1)), "网络连接", + "accept", c.RemoteAddr().String(), m.Cap("security"), m.Cap("protocol")) } return true @@ -138,27 +141,31 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心", "protocol": &ctx.Config{Name: "网络协议(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"}, }, Commands: map[string]*ctx.Command{ - "listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Start(fmt.Sprintf("pub%d", Pulse.Capi("nlisten", 1)), "网络监听", m.Meta["detail"]...) - }}, - "dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Start(fmt.Sprintf("com%d", Pulse.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) - }}, - "send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - tcp, ok := m.Target().Server.(*TCP) - m.Assert(ok && tcp.Conn != nil) - tcp.Conn.Write([]byte(arg[0])) - }}, - "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - tcp, ok := m.Target().Server.(*TCP) - m.Assert(ok && tcp.Conn != nil) - size, e := strconv.Atoi(arg[0]) - m.Assert(e) + "listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Start(fmt.Sprintf("pub%d", Pulse.Capi("nlisten", 1)), "网络监听", m.Meta["detail"]...) + }}, + "dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Start(fmt.Sprintf("com%d", Pulse.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) + }}, + "send": &ctx.Command{Name: "send message", Help: "发送消息", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + tcp, ok := m.Target().Server.(*TCP) + m.Assert(ok && tcp.Conn != nil) + tcp.Conn.Write([]byte(arg[0])) + }}, + "recv": &ctx.Command{Name: "recv size", Help: "接收消息", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + tcp, ok := m.Target().Server.(*TCP) + m.Assert(ok && tcp.Conn != nil) + size, e := strconv.Atoi(arg[0]) + m.Assert(e) - buf := make([]byte, size) - tcp.Conn.Read(buf) - m.Echo(string(buf)) - }}, + buf := make([]byte, size) + tcp.Conn.Read(buf) + m.Echo(string(buf)) + }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{ diff --git a/src/context/yac/yac.go b/src/context/yac/yac.go index 05680453..a71be1aa 100644 --- a/src/context/yac/yac.go +++ b/src/context/yac/yac.go @@ -3,6 +3,7 @@ package yac import ( "context" "fmt" + "strconv" "strings" ) @@ -185,20 +186,21 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po func (yac *YAC) parse(m *ctx.Message, cli *ctx.Context, page, void int, line string) (*ctx.Context, string, []string) { level := m.Capi("level", 1) - m.Sess("log").Cmd("log", "debug", fmt.Sprintf("%s\\%d %s(%d):", m.Cap("label")[0:level], level, yac.word[page], page)) + yac.Log("debug", nil, fmt.Sprintf("%s\\%d %s(%d):", m.Cap("label")[0:level], level, yac.word[page], page)) hash, word := 0, []string{} for star, s := 0, page; s != 0 && len(line) > 0; { - line = yac.Sess("lex").Cmd("parse", line, yac.name(void)).Result(2) + line = yac.Sess("lex").Cmd("parse", line, yac.name(void)).Result(1) lex := yac.Sess("lex").Cmd("parse", line, yac.name(s)) c := byte(lex.Resulti(0)) state := yac.mat[s][c] + if state != nil { - if key := yac.Sess("lex").Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(1)) <= len(lex.Result(1)) { - m.Log("debug", nil, "%s|%d get(%d,%d): %v \033[31m(%s)\033[0m", m.Cap("label")[0:level], level, s, c, state, lex.Result(1)) - line, word = lex.Result(2), append(word, lex.Result(1)) + if key := yac.Sess("lex").Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(2)) <= len(lex.Result(2)) { + m.Log("debug", nil, "%s|%d get(%d,%d): %v \033[31m(%s)\033[0m", m.Cap("label")[0:level], level, s, c, state, lex.Result(2)) + line, word = lex.Result(1), append(word, lex.Result(2)) } else { state = nil } @@ -206,16 +208,16 @@ func (yac *YAC) parse(m *ctx.Message, cli *ctx.Context, page, void int, line str if state == nil { for i := 0; i < yac.Capi("ncell"); i++ { - x := yac.mat[s][byte(i)] - if i >= m.Capi("nlang") || x == nil { - continue - } - m.Log("debug", nil, "%s|%d try(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x) - if c, l, w := yac.parse(m, cli, i, void, line); l != line { - m.Log("debug", nil, "%s|%d end(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x) - cli, line, state = c, l, x - word = append(word, w...) - break + if x := yac.mat[s][byte(i)]; i < m.Capi("nlang") && x != nil { + m.Log("debug", nil, "%s|%d try(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x) + + if c, l, w := yac.parse(m, cli, i, void, line); l != line { + m.Log("debug", nil, "%s|%d get(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x) + line, word = l, append(word, w...) + + cli, state = c, x + break + } } } } @@ -260,38 +262,44 @@ 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 { - if yac.Context == Index { + if yac.Message = m; yac.Context == Index { Pulse = m } yac.Context.Master(nil) - yac.Message = m yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"} - yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "16", Help: "语法集合的最大数量"} + yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"} yac.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "语法模板的数量"} yac.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "语法集合的数量"} yac.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "语句类型的数量"} - yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "16", Help: "状态机状态的数量"} - yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的数量"} + yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "32", Help: "状态机状态的数量"} + yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"} yac.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"} yac.Caches["level"] = &ctx.Cache{Name: "嵌套层级", Value: "0", Help: "语法解析嵌套层级"} yac.Caches["label"] = &ctx.Cache{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"} + if len(arg) > 0 { + if _, e := strconv.Atoi(arg[0]); yac.Assert(e) { + yac.Cap("nlang", arg[0]) + yac.Cap("nline", arg[0]) + } + } + yac.page = map[string]int{"nil": 0} yac.word = map[int]string{0: "nil"} yac.hash = map[string]int{"nil": 0} yac.hand = map[int]string{0: "nil"} - yac.state = map[State]*State{} yac.mat = make([]map[byte]*State, m.Capi("nlang")) + yac.state = map[State]*State{} + return yac } func (yac *YAC) Start(m *ctx.Message, arg ...string) bool { - yac.Context.Master(nil) yac.Message = m return false }