1
0
forked from x/ContextOS

mac opt nfs

This commit is contained in:
shaoying 2018-07-16 10:36:22 +08:00
parent fbb34936fa
commit bd5f8f3fc9
7 changed files with 562 additions and 362 deletions

View File

@ -1,4 +1,5 @@
~cli config debug on ~file1
history load hi.cmd
return return
scan_file etc/demo.shy scan_file etc/demo.shy
echo "who" echo "who"

View File

@ -51,6 +51,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
if len(arg) > 0 { if len(arg) > 0 {
s.target = c s.target = c
} }
s.target = cli.target
return s return s
} }
@ -280,6 +281,10 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
return nil return nil
}, "parse", arg[1]) }, "parse", arg[1])
m.Cap("stream", yac.Target().Name) m.Cap("stream", yac.Target().Name)
if arg[1] == "stdio" {
m.Spawn().Cmd("scan_file", "etc/init.shy")
}
return false return false
} }
@ -844,7 +849,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
}}, }},
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, rusult: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "return": &ctx.Command{Name: "return result...", Help: "结束脚本, rusult: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
m.Add("append", "return", arg[1:]...) m.Add("append", "return", arg[1:])
} // }}} } // }}}
}}, }},
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
@ -930,11 +935,17 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
m.Echo("%s", strings.Join(arg, "")) m.Echo("%s", strings.Join(arg, ""))
}}, }},
"scan_file": &ctx.Command{ "scan_file": &ctx.Command{
Name: "scan_file filename [cli_name [cli_help]]", Name: "scan_file filename [async [cli_name [cli_help]]",
Help: "解析脚本, filename: 文件名, cli_name: 模块名, cli_help: 模块帮助", Help: "解析脚本, filename: 文件名, cli_name: 模块名, cli_help: 模块帮助",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
m.Start(m.Confx("cli_name", arg, 1), m.Confx("cli_help", arg, 2), key, arg[0]) if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
<-m.Target().Exit m.Start(m.Confx("cli_name", arg, 2), m.Confx("cli_help", arg, 3), key, arg[0])
if len(arg) > 1 && arg[1] != "async" {
<-m.Target().Exit
sub := m.Target().Server.(*CLI)
cli.target = sub.target
}
}
}}, }},
}, },
Index: map[string]*ctx.Context{ Index: map[string]*ctx.Context{

View File

@ -107,7 +107,11 @@ func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{
} }
// }}} // }}}
func (c *Context) Begin(m *Message) *Context { // {{{ func (c *Context) Begin(m *Message, arg ...string) *Context { // {{{
if len(arg) > 0 {
m.Meta["detail"] = arg
}
c.Caches["status"] = &Cache{Name: "服务状态(begin/start/close)", Value: "begin", Help: "服务状态begin:初始完成start:正在运行close:未在运行"} c.Caches["status"] = &Cache{Name: "服务状态(begin/start/close)", Value: "begin", Help: "服务状态begin:初始完成start:正在运行close:未在运行"}
c.Caches["stream"] = &Cache{Name: "服务数据", Value: "", Help: "服务数据"} c.Caches["stream"] = &Cache{Name: "服务数据", Value: "", Help: "服务数据"}
@ -145,7 +149,11 @@ func (c *Context) Begin(m *Message) *Context { // {{{
} }
// }}} // }}}
func (c *Context) Start(m *Message) bool { // {{{ func (c *Context) Start(m *Message, arg ...string) bool { // {{{
if len(arg) > 0 {
m.Meta["detail"] = arg
}
m.Hand = true m.Hand = true
if m != c.Requests[0] { if m != c.Requests[0] {
@ -998,7 +1006,29 @@ func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg
// }}} // }}}
func (m *Message) Add(meta string, key string, value ...string) *Message { // {{{ func (m *Message) Trans(arg ...interface{}) []string {
ls := []string{}
for _, v := range arg {
value := ""
switch val := v.(type) {
case []string:
ls = append(ls, val...)
continue
case string:
value = val
case bool:
value = fmt.Sprintf("%t", val)
case int, int8, int16, int32, int64:
value = fmt.Sprintf("%d", val)
default:
value = fmt.Sprintf("%v", val)
}
ls = append(ls, value)
}
return ls
}
func (m *Message) Add(meta string, key string, value ...interface{}) *Message { // {{{
if m.Meta == nil { if m.Meta == nil {
m.Meta = make(map[string][]string) m.Meta = make(map[string][]string)
} }
@ -1009,13 +1039,13 @@ func (m *Message) Add(meta string, key string, value ...string) *Message { // {{
switch meta { switch meta {
case "detail", "result": case "detail", "result":
m.Meta[meta] = append(m.Meta[meta], key) m.Meta[meta] = append(m.Meta[meta], key)
m.Meta[meta] = append(m.Meta[meta], value...) m.Meta[meta] = append(m.Meta[meta], m.Trans(value...)...)
case "option", "append": case "option", "append":
if _, ok := m.Meta[key]; !ok { if _, ok := m.Meta[key]; !ok {
m.Meta[key] = make([]string, 0, 3) m.Meta[key] = make([]string, 0, 3)
} }
m.Meta[key] = append(m.Meta[key], value...) m.Meta[key] = append(m.Meta[key], m.Trans(value...)...)
for _, v := range m.Meta[meta] { for _, v := range m.Meta[meta] {
if v == key { if v == key {
@ -1055,7 +1085,7 @@ func (m *Message) Set(meta string, arg ...string) *Message { // {{{
} }
if len(arg) > 0 { if len(arg) > 0 {
m.Add(meta, arg[0], arg[1:]...) m.Add(meta, arg[0], arg[1:])
} }
return m return m
@ -1148,7 +1178,7 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // {
for _, k := range arg { for _, k := range arg {
if v, ok := msg.Meta[k]; ok { if v, ok := msg.Meta[k]; ok {
m.Set(meta, k).Add(meta, k, v...) m.Set(meta, k).Add(meta, k, v)
} }
if v, ok := msg.Data[k]; ok { if v, ok := msg.Data[k]; ok {
m.Put(meta, k, v) m.Put(meta, k, v)
@ -1160,11 +1190,12 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // {
} }
// }}} // }}}
func (m *Message) Table(cb func(map[string]string, []string, int) bool) *Message { // {{{ func (m *Message) Table(cb func(maps map[string]string, list []string, line int) (goon bool)) *Message { // {{{
if len(m.Meta["append"]) == 0 { if len(m.Meta["append"]) == 0 {
return m return m
} }
//计算列宽
width := make(map[string]int, len(m.Meta[m.Meta["append"][0]])) width := make(map[string]int, len(m.Meta[m.Meta["append"][0]]))
for _, k := range m.Meta["append"] { for _, k := range m.Meta["append"] {
title := k title := k
@ -1182,6 +1213,7 @@ func (m *Message) Table(cb func(map[string]string, []string, int) bool) *Message
} }
} }
//输出字段名
row := map[string]string{} row := map[string]string{}
wor := []string{} wor := []string{}
for _, k := range m.Meta["append"] { for _, k := range m.Meta["append"] {
@ -1202,6 +1234,7 @@ func (m *Message) Table(cb func(map[string]string, []string, int) bool) *Message
wor := []string{} wor := []string{}
for _, k := range m.Meta["append"] { for _, k := range m.Meta["append"] {
data := m.Meta[k][i] data := m.Meta[k][i]
//解析extra字段
if m.Options("extras") && k == "extra" { if m.Options("extras") && k == "extra" {
var extra interface{} var extra interface{}
json.Unmarshal([]byte(data), &extra) json.Unmarshal([]byte(data), &extra)
@ -1569,7 +1602,6 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{
for _, c := range []*Context{m.target, m.target.master, m.target.Owner, m.source, m.source.master, m.source.Owner} { for _, c := range []*Context{m.target, m.target.master, m.target.Owner, m.source, m.source.master, m.source.Owner} {
for s := c; s != nil; s = s.context { for s := c; s != nil; s = s.context {
if x, ok := s.Commands[key]; ok && x.Hand != nil && c.Check(m, "commands", key) { if x, ok := s.Commands[key]; ok && x.Hand != nil && c.Check(m, "commands", key) {
m.TryCatch(m, true, func(m *Message) { m.TryCatch(m, true, func(m *Message) {
m.Log("cmd", s, "%d %s %v %v", len(m.target.Historys), key, arg, m.Meta["option"]) m.Log("cmd", s, "%d %s %v %v", len(m.target.Historys), key, arg, m.Meta["option"])
@ -1602,7 +1634,7 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{
// continue // continue
// } // }
// //
m.Add("option", arg[i], arg[i+1:i+1+n]...) m.Add("option", arg[i], arg[i+1:i+1+n])
i += n i += n
} }
arg = m.Meta["args"] arg = m.Meta["args"]
@ -2414,7 +2446,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
for i, v := range msg.messages { for i, v := range msg.messages {
if !all { if !all {
switch v.target.Name { switch v.target.Name {
case "log", "yac": case "log", "yac", "lex":
continue continue
} }
} }
@ -3373,6 +3405,6 @@ func Start(args ...string) {
Pulse.Options("terminal_color", true) Pulse.Options("terminal_color", true)
Pulse.Sesss("log", "log").Conf("bench.log", Pulse.Conf("bench.log")) Pulse.Sesss("log", "log").Conf("bench.log", Pulse.Conf("bench.log"))
Pulse.Find("cli").Cmd("scan_file", "etc/init.shy") cli := Pulse.Find("cli").Cmd("scan_file", "stdio", "async")
Pulse.Find("cli").Cmd("scan_file", "stdio") <-cli.target.Exit
} }

View File

@ -14,7 +14,7 @@ import ( // {{{
type LOG struct { type LOG struct {
module map[string]map[string]bool module map[string]map[string]bool
slient map[string]bool silent map[string]bool
color map[string]int color map[string]int
*Log.Logger *Log.Logger
@ -33,10 +33,6 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
// }}} // }}}
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
if log.Context == Index {
Pulse = m
}
log.Context.Master(nil)
log.Message = m log.Message = m
log.Configs["flag_date"] = &ctx.Config{Name: "输出日期", Value: "true", Help: "模块日志输出消息日期"} log.Configs["flag_date"] = &ctx.Config{Name: "输出日期", Value: "true", Help: "模块日志输出消息日期"}
@ -50,7 +46,7 @@ func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
if len(arg) > 0 { if len(arg) > 0 {
if m.Sess("nfs") == nil { if m.Sess("nfs") == nil {
os.Create(arg[0]) os.Create(arg[0])
m.Sess("nfs", "nfs").Cmd("open", arg[0]) m.Sess("nfs", "nfs").Cmd("open", arg[0], "", "日志文件")
} }
return arg[0] return arg[0]
} }
@ -82,12 +78,12 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
Caches: map[string]*ctx.Cache{}, Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{}, Configs: map[string]*ctx.Config{},
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"slient": &ctx.Command{Name: "slient [[module] level state]", Help: "查看或设置日志开关, module: 模块名, level: 日志类型, state(true/false): 是否打印日志", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "silent": &ctx.Command{Name: "silent [[module] level state]", Help: "查看或设置日志开关, module: 模块名, level: 日志类型, state(true/false): 是否打印日志", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{ if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{
switch len(arg) { switch len(arg) {
case 2: case 2:
if len(arg) > 1 { if len(arg) > 1 {
log.slient[arg[0]] = ctx.Right(arg[1]) log.silent[arg[0]] = ctx.Right(arg[1])
} }
case 3: case 3:
if log.module[arg[0]] == nil { if log.module[arg[0]] == nil {
@ -96,7 +92,7 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
log.module[arg[0]][arg[1]] = ctx.Right(arg[2]) log.module[arg[0]][arg[1]] = ctx.Right(arg[2])
} }
for k, v := range log.slient { for k, v := range log.silent {
m.Echo("%s: %t\n", k, v) m.Echo("%s: %t\n", k, v)
} }
for k, v := range log.module { for k, v := range log.module {
@ -121,7 +117,7 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
}}, }},
"log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{ if log, ok := m.Target().Server.(*LOG); m.Assert(ok) { // {{{
if s, ok := log.slient[arg[0]]; ok && s == true { if s, ok := log.silent[arg[0]]; ok && s == true {
return return
} }
@ -216,7 +212,7 @@ func init() {
"close": 36, "close": 36,
"debug": 0, "debug": 0,
} }
log.slient = map[string]bool{ log.silent = map[string]bool{
// "lock": true, // "lock": true,
} }
log.module = map[string]map[string]bool{ log.module = map[string]map[string]bool{

View File

@ -9,9 +9,11 @@ import ( // {{{
"bufio" "bufio"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/url" "net/url"
"os" "os"
"os/exec" "os/exec"
"path"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -21,17 +23,17 @@ import ( // {{{
// }}} // }}}
type NFS struct { type NFS struct {
in *os.File
out *os.File
history []string
io io.ReadWriteCloser io io.ReadWriteCloser
*bufio.Reader *bufio.Reader
*bufio.Writer *bufio.Writer
send map[int]*ctx.Message send map[int]*ctx.Message
target *ctx.Context target *ctx.Context
in *os.File
out *os.File
cli *ctx.Message cli *ctx.Message
buf []string
pages []string pages []string
width, height int width, height int
@ -40,6 +42,71 @@ type NFS struct {
*ctx.Context *ctx.Context
} }
func dir(m *ctx.Message, name string, level int) {
back, e := os.Getwd()
m.Assert(e)
os.Chdir(name)
defer os.Chdir(back)
if fs, e := ioutil.ReadDir("."); m.Assert(e) {
for _, f := range fs {
if f.Name()[0] == '.' {
continue
}
if f.IsDir() {
if m.Has("dirs") {
m.Optioni("dirs", m.Optioni("dirs")+1)
}
} else {
if m.Has("files") {
m.Optioni("files", m.Optioni("files")+1)
}
}
if m.Has("sizes") {
m.Optioni("sizes", m.Optioni("sizes")+int(f.Size()))
}
line := 0
if m.Has("lines") {
if !f.IsDir() {
f, e := os.Open(path.Join(back, name, f.Name()))
m.Assert(e)
defer f.Close()
bio := bufio.NewScanner(f)
for bio.Scan() {
bio.Text()
line++
}
m.Optioni("lines", m.Optioni("lines")+line)
}
}
filename := ""
if m.Confx("dir_name") == "name" {
filename = strings.Repeat(" ", level) + f.Name()
} else {
filename = path.Join(back, name, f.Name())
}
if !(m.Confx("dir_type") == "file" && f.IsDir() ||
m.Confx("dir_type") == "dir" && !f.IsDir()) {
m.Add("append", "filename", filename)
m.Add("append", "dir", f.IsDir())
m.Add("append", "size", f.Size())
m.Log("fuck", nil, "why %s %d", f.Name(), f.Size())
m.Add("append", "line", line)
m.Add("append", "time", f.ModTime().Format("2006-01-02 15:04:05"))
}
if f.IsDir() {
dir(m, f.Name(), level+1)
}
}
}
}
func (nfs *NFS) insert(rest []rune, letters []rune) []rune { // {{{ func (nfs *NFS) insert(rest []rune, letters []rune) []rune { // {{{
n := len(rest) n := len(rest)
l := len(letters) l := len(letters)
@ -207,7 +274,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{
back := buf back := buf
his := len(nfs.buf) his := len(nfs.history)
tab := []string{} tab := []string{}
tabi := 0 tabi := 0
@ -238,21 +305,21 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{
return return
case termbox.KeyCtrlP: case termbox.KeyCtrlP:
for i := 0; i < len(nfs.buf); i++ { for i := 0; i < len(nfs.history); i++ {
his = (his + len(nfs.buf) - 1) % len(nfs.buf) his = (his + len(nfs.history) - 1) % len(nfs.history)
if strings.HasPrefix(nfs.buf[his], string(buf)) { if strings.HasPrefix(nfs.history[his], string(buf)) {
rest = rest[:0] rest = rest[:0]
rest = append(rest, []rune(nfs.buf[his][len(buf):])...) rest = append(rest, []rune(nfs.history[his][len(buf):])...)
break break
} }
} }
case termbox.KeyCtrlN: case termbox.KeyCtrlN:
for i := 0; i < len(nfs.buf); i++ { for i := 0; i < len(nfs.history); i++ {
his = (his + len(nfs.buf) + 1) % len(nfs.buf) his = (his + len(nfs.history) + 1) % len(nfs.history)
if strings.HasPrefix(nfs.buf[his], string(buf)) { if strings.HasPrefix(nfs.history[his], string(buf)) {
rest = rest[:0] rest = rest[:0]
rest = append(rest, []rune(nfs.buf[his][len(buf):])...) rest = append(rest, []rune(nfs.history[his][len(buf):])...)
break break
} }
} }
@ -388,13 +455,19 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{
// }}} // }}}
func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
if len(arg) > 0 && arg[0] == "scan_file" { if len(arg) > 0 && arg[0] == "scan" {
nfs.Message = m nfs.Message = m
c.Caches = map[string]*ctx.Cache{ c.Caches = map[string]*ctx.Cache{
"nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"}, "nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"},
"nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"}, "nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"},
} }
c.Configs = map[string]*ctx.Config{} c.Configs = map[string]*ctx.Config{}
} else if len(arg) > 0 && arg[0] == "open" {
c.Caches = map[string]*ctx.Cache{
"pos": &ctx.Cache{Name: "pos", Value: "0", Help: "pos"},
"size": &ctx.Cache{Name: "size", Value: "0", Help: "size"},
}
c.Configs = map[string]*ctx.Config{}
} else { } else {
c.Caches = map[string]*ctx.Cache{ c.Caches = map[string]*ctx.Cache{
"pos": &ctx.Cache{Name: "读写位置", Value: "0", Help: "读写位置"}, "pos": &ctx.Cache{Name: "读写位置", Value: "0", Help: "读写位置"},
@ -429,31 +502,34 @@ 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.Message = m nfs.Message = m
nfs.Context.Master(nil)
if nfs.Context == Index {
Pulse = m
}
return nfs return nfs
} }
// }}} // }}}
func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
if len(arg) > 0 && arg[0] == "scan_file" { if len(arg) > 0 && arg[0] == "scan" {
nfs.Message = m nfs.Message = m
nfs.in = m.Optionv("in").(*os.File) nfs.in = m.Optionv("in").(*os.File)
bio := bufio.NewScanner(nfs) bio := bufio.NewScanner(nfs)
if m.Options("stdout", m.Cap("stream", arg[1]) == "stdio") { if m.Cap("stream", arg[1]) == "stdio" {
termbox.Init() termbox.Init()
defer termbox.Close() defer termbox.Close()
nfs.out = m.Optionv("out").(*os.File) nfs.out = m.Optionv("out").(*os.File)
} }
line := ""
for nfs.prompt(); bio.Scan(); nfs.prompt() { for nfs.prompt(); bio.Scan(); nfs.prompt() {
text := bio.Text() text := bio.Text()
m.Capi("nread", len(text)) m.Capi("nread", len(text))
msg := m.Spawn(m.Source()).Set("detail", text) if line += text; len(text) > 0 && text[len(text)-1] == '\\' {
line = line[:len(line)-1]
continue
}
nfs.history = append(nfs.history, line)
msg := m.Spawn(m.Source()).Set("detail", line)
if m.Back(msg); m.Options("scan_end") { if m.Back(msg); m.Options("scan_end") {
break break
} }
@ -462,10 +538,21 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
m.Capi("nwrite", len(v)) m.Capi("nwrite", len(v))
nfs.print(v) nfs.print(v)
} }
line = ""
} }
return true return true
} }
if len(arg) > 0 && arg[0] == "open" {
nfs.in = m.Optionv("in").(*os.File)
s, e := nfs.in.Stat()
m.Assert(e)
m.Capi("size", int(s.Size()))
nfs.out = m.Optionv("out").(*os.File)
m.Cap("stream", arg[1])
return false
}
m.Target().Sessions["nfs"] = m m.Target().Sessions["nfs"] = m
m.Sessions["nfs"] = m m.Sessions["nfs"] = m
@ -596,95 +683,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
return true 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
}
}
// cli := m.Reply()
cli := m.Sesss("cli")
nfs.cli = cli
yac := m.Sesss("yac", cli.Conf("yac"))
bio := bufio.NewScanner(nfs)
if m.Cap("stream") == "stdio" {
termbox.Init()
defer termbox.Close()
}
nfs.Context.Master(nil)
pos := 0
if buf, ok := m.Data["buf"]; ok {
nfs.buf = buf.([]string)
m.Capi("nline", len(nfs.buf))
goto out
}
nfs.pages = append(nfs.pages, nfs.cli.Conf("PS1"))
nfs.prompt()
for rest, text := "", ""; pos < m.Capi("nline") || bio.Scan(); {
if pos == m.Capi("nline") {
if text = bio.Text(); len(text) > 0 && text[len(text)-1] == '\\' {
rest += text[:len(text)-1]
continue
}
if text, rest = rest+text, ""; len(text) == 0 && len(nfs.buf) > 0 && nfs.in == os.Stdin {
pos--
} else {
nfs.buf = append(nfs.buf, text)
m.Capi("nline", 1)
}
}
for ; pos < m.Capi("nline"); pos++ {
for text = nfs.buf[pos] + "\n"; text != ""; {
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")
}
}
}
}
nfs.pages = append(nfs.pages, fmt.Sprintf("\033[32m%s\033[m", nfs.cli.Conf("PS1")))
nfs.prompt()
}
out:
if len(arg) > 1 {
cli.Cmd("end")
} else {
m.Cap("status", "stop")
}
return false return false
} }
@ -696,6 +694,14 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{
nfs.in.Close() nfs.in.Close()
nfs.in = nil nfs.in = nil
} }
if nfs.out != nil {
nfs.out.Close()
nfs.out = nil
}
if nfs.io != nil {
nfs.io.Close()
nfs.io = nil
}
case m.Source(): case m.Source():
m.Source().Close(m.Spawn(m.Source())) m.Source().Close(m.Spawn(m.Source()))
} }
@ -707,57 +713,341 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{
// }}} // }}}
var Pulse *ctx.Message
var Index = &ctx.Context{Name: "nfs", Help: "存储中心", var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
Caches: map[string]*ctx.Cache{ Caches: map[string]*ctx.Cache{
"nfile": &ctx.Cache{Name: "nfile", Value: "0", Help: "已经打开的文件数量"}, "nfile": &ctx.Cache{Name: "nfile", Value: "-1", Help: "已经打开的文件数量"},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"size": &ctx.Config{Name: "size", Value: "1024", Help: "读取文件的默认大小值"},
"color": &ctx.Config{Name: "color", Value: "9", Help: "读取文件的默认大小值"}, "color": &ctx.Config{Name: "color", Value: "9", Help: "读取文件的默认大小值"},
"backcolor": &ctx.Config{Name: "backcolor", Value: "9", Help: "读取文件的默认大小值"}, "backcolor": &ctx.Config{Name: "backcolor", Value: "9", Help: "读取文件的默认大小值"},
"pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "读取文件的默认大小值"}, "pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "读取文件的默认大小值"},
"statuscolor": &ctx.Config{Name: "statuspscolor", Value: "1", Help: "读取文件的默认大小值"}, "statuscolor": &ctx.Config{Name: "statuspscolor", Value: "1", Help: "读取文件的默认大小值"},
"statusbackcolor": &ctx.Config{Name: "statusbackcolor", Value: "2", Help: "读取文件的默认大小值"}, "statusbackcolor": &ctx.Config{Name: "statusbackcolor", Value: "2", Help: "读取文件的默认大小值"},
"nfs_name": &ctx.Config{Name: "nfs_name", Value: "file", Help: "默认模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { "name": &ctx.Config{Name: "name", Value: "file", Help: "默认模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
if len(arg) > 0 { // {{{ if len(arg) > 0 { // {{{
return arg[0] return arg[0]
} }
return fmt.Sprintf("%s%d", x.Value, m.Capi("nfile", 1)) return fmt.Sprintf("%s%d", x.Value, m.Capi("nfile", 1))
// }}} // }}}
}}, }},
"nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"}, "help": &ctx.Config{Name: "help", Value: "file", Help: "默认模块帮助"},
"buffer_size": &ctx.Config{Name: "buffer_size", Value: "1024", Help: "缓存区大小"}, "buf_size": &ctx.Config{Name: "buf_size", Value: "1024", Help: "读取文件的默认大小值"},
"qr_size": &ctx.Config{Name: "qr_size", Value: "256", Help: "读取文件的默认大小值"},
"dir_name": &ctx.Config{Name: "dir_name", Value: "name", Help: "读取文件的默认大小值"},
"dir_info": &ctx.Config{Name: "dir_info", Value: "info", Help: "读取文件的默认大小值"},
"dir_type": &ctx.Config{Name: "dir_type", Value: "type", Help: "读取文件的默认大小值"},
"sort_field": &ctx.Config{Name: "sort_field", Value: "line", Help: "读取文件的默认大小值"},
"sort_type": &ctx.Config{Name: "sort_type", Value: "int", Help: "读取文件的默认大小值"},
"git_status": &ctx.Config{Name: "git_status", Value: "-sb", Help: "读取文件的默认大小值"},
"git_path": &ctx.Config{Name: "git_path", Value: ".", Help: "读取文件的默认大小值"},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"scan_file": &ctx.Command{ "scan": &ctx.Command{
Name: "scan_file filename [nfs_name [nfs_help]]", Name: "scan filename [name [help]]",
Help: "扫描文件, filename: 文件名, nfs_name: 模块名, nfs_help: 模块帮助", Help: "扫描文件, filename: 文件名, name: 模块名, help: 模块帮助",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{
if arg[0] == "stdio" { if arg[0] == "stdio" {
m.Put("option", "in", os.Stdin) m.Optionv("in", os.Stdin)
m.Put("option", "out", os.Stdout) m.Optionv("out", os.Stdout)
} else { } else if f, e := os.Open(arg[0]); m.Assert(e) {
f, e := os.Open(arg[0]) m.Optionv("in", f)
m.Assert(e)
m.Put("option", "in", f)
} }
m.Start(m.Confx("nfs_name", arg, 1), m.Confx("nfs_help", arg, 2), key, arg[0]) m.Start(m.Confx("name", arg, 1), m.Confx("help", arg, 2), key, arg[0])
} // }}} } // }}}
}}, }},
"buffer": &ctx.Command{Name: "buffer [index string]", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "history": &ctx.Command{Name: "history [save|load filename [lines [pos]]] [find|search string]", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.buf != nil { // {{{ if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{
for i, v := range nfs.buf { if len(arg) == 0 {
m.Echo("%d: %s\n", i, v) for i, v := range nfs.history {
m.Echo("%d: %s\n", i, v)
}
return
}
switch arg[0] {
case "load":
f, e := os.Open(arg[1])
m.Assert(e)
defer f.Close()
pos, lines := 0, -1
if len(arg) > 3 {
i, e := strconv.Atoi(arg[3])
m.Assert(e)
pos = i
}
if len(arg) > 2 {
i, e := strconv.Atoi(arg[2])
m.Assert(e)
lines = i
}
bio := bufio.NewScanner(f)
for i := 0; bio.Scan(); i++ {
if i < pos {
continue
}
if lines != -1 && (i-pos) >= lines {
break
}
nfs.history = append(nfs.history, bio.Text())
}
case "save":
f, e := os.Create(arg[1])
m.Assert(e)
defer f.Close()
pos, lines := 0, -1
if len(arg) > 3 {
i, e := strconv.Atoi(arg[3])
m.Assert(e)
pos = i
}
if len(arg) > 2 {
i, e := strconv.Atoi(arg[2])
m.Assert(e)
lines = i
}
for i, v := range nfs.history {
if i < pos {
continue
}
if lines != -1 && (i-pos) >= lines {
break
}
fmt.Fprintln(f, v)
}
case "find":
for i, v := range nfs.history {
if strings.HasPrefix(v, arg[1]) {
m.Echo("%d: %s\n", i, v)
}
}
case "search":
default:
if i, e := strconv.Atoi(arg[0]); e == nil && i < len(nfs.history) {
m.Echo(nfs.history[i])
}
} }
} // }}} } // }}}
}}, }},
"open": &ctx.Command{
Name: "open filename [name [help]]",
Help: "打开文件, filename: 文件名, name: 模块名, help: 模块帮助",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if m.Has("io") { // {{{
} 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(m.Confx("name", arg, 1), m.Confx("help", arg, 2), "open", arg[0])
m.Echo(m.Target().Name)
// }}}
}},
"read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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.Echo(string(buf))
if m.Capi("pos", n); n == 0 {
m.Cap("pos", "0")
}
} // }}}
}},
"write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
m.Cap("size", m.Cap("pos"))
}
nfs.out.Sync()
}
m.Echo(m.Cap("pos"))
} // }}}
}},
"load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if f, e := os.Open(arg[0]); m.Assert(e) { // {{{
defer f.Close()
pos := 0
if len(arg) > 2 {
i, e := strconv.Atoi(arg[2])
m.Assert(e)
pos = i
}
s, e := strconv.Atoi(m.Confx("buf_size", arg, 1))
m.Assert(e)
buf := make([]byte, s)
if l, e := f.ReadAt(buf, int64(pos)); e == io.EOF || m.Assert(e) {
m.Log("info", nil, "read %d", l)
m.Echo(string(buf[:l]))
}
} // }}}
}},
"save": &ctx.Command{Name: "save file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if f, e := os.Create(arg[0]); m.Assert(e) { // {{{
defer f.Close()
for _, v := range arg[1:] {
fmt.Fprint(f, v)
}
} // }}}
}},
"print": &ctx.Command{Name: "print file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if f, e := os.OpenFile(arg[0], os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666); m.Assert(e) { // {{{
defer f.Close()
for _, v := range arg[1:] {
fmt.Fprint(f, v)
}
fmt.Fprint(f, "\n")
} // }}}
}},
"genqr": &ctx.Command{Name: "genqr [qr_size size] file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if size, e := strconv.Atoi(m.Confx("qr_size")); m.Assert(e) { // {{{
qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, arg[0])
} // }}}
}},
"json": &ctx.Command{Name: "json [key value]...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
data := map[string]interface{}{} // {{{
for _, k := range m.Meta["option"] {
if v, ok := m.Data[k]; ok {
data[k] = v
continue
}
data[k] = m.Meta[k]
}
for i := 1; i < len(arg)-1; i += 2 {
data[arg[i]] = arg[i+1]
}
buf, e := json.Marshal(data)
m.Assert(e)
m.Echo(string(buf))
// }}}
}},
"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) // }}}
}},
"dir": &ctx.Command{
Name: "dir dir [dir_info info] [dir_name name|path|full] [dir_type file|dir] [sort_field name] [sort_type type]",
Help: "查看目录, dir: 目录名, dir_info: 显示统计信息, dir_name: 文件名类型, dir_type: 文件类型, sort_field: 排序字段, sort_type: 排序类型",
Form: map[string]int{"dir_info": 1, "dir_name": 1, "dir_type": 1, "sort_field": 1, "sort_type": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
d := "." // {{{
if len(arg) > 0 {
d = arg[0]
}
trip := 0
if m.Confx("dir_name") == "path" {
wd, e := os.Getwd()
m.Assert(e)
trip = len(wd) + 1
}
if m.Confx("dir_info") == "info" {
m.Option("sizes", 0)
m.Option("lines", 0)
m.Option("files", 0)
m.Option("dirs", 0)
}
dir(m, d, 0)
m.Sort(m.Confx("sort_field"), m.Confx("sort_type"))
m.Table(func(maps map[string]string, list []string, line int) bool {
for i, v := range list {
key := m.Meta["append"][i]
switch key {
case "filename":
if trip > 0 {
v = v[trip:]
}
case "dir":
continue
}
m.Echo("%s\t", v)
}
m.Echo("\n")
return true
})
if m.Confx("dir_info") == "info" {
m.Echo("sizes: %s\n", m.Option("sizes"))
m.Echo("lines: %s\n", m.Option("lines"))
m.Echo("files: %s\n", m.Option("files"))
m.Echo("dirs: %s\n", m.Option("dirs"))
}
// }}}
}},
"git": &ctx.Command{
Name: "git cmd",
Help: "写入文件, string: 写入内容, pos: 写入位置",
Form: map[string]int{"git_path": 1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
cmds := []string{arg[0]} // {{{
if arg[0] == "info" {
cmds = []string{"branch", "status"}
}
wd, e := os.Getwd()
m.Assert(e)
if !m.Has("git_path") {
m.Option("git_path", m.Conf("git_path"))
}
for _, p := range m.Meta["git_path"] {
if !path.IsAbs(p) {
p = path.Join(wd, p)
}
for _, c := range cmds {
args := []string{}
switch c {
case "status":
args = append(args, m.Confx("git_status", arg, 1))
default:
args = append(args, arg[1:]...)
}
m.Log("fuck", nil, "cmd %p", m.Trans("-C", p, c, args))
cmd := exec.Command("git", m.Trans("-C", p, c, args)...)
if out, e := cmd.CombinedOutput(); e != nil {
m.Echo("error: ")
m.Echo("%s\n", e)
} else {
m.Echo(string(out))
}
}
} // }}}
}},
"copy": &ctx.Command{Name: "copy name [begin [end]]", Help: "复制文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "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.history) > 0 { // {{{
begin, end := 0, len(nfs.buf) begin, end := 0, len(nfs.history)
if len(arg) > 1 { if len(arg) > 1 {
i, e := strconv.Atoi(arg[1]) i, e := strconv.Atoi(arg[1])
m.Assert(e) m.Assert(e)
@ -768,24 +1058,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Assert(e) m.Assert(e)
end = i end = i
} }
m.Put("option", "buf", nfs.buf[begin:end]) m.Put("option", "buf", nfs.history[begin:end])
m.Start(arg[0], "扫描文件", key) 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" { // {{{
m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout).Start("stdio", "扫描文件", m.Meta["detail"]...)
} else if f, e := os.Open(arg[0]); m.Assert(e) {
m.Put("option", "in", f).Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "扫描文件", m.Meta["detail"]...)
}
// }}}
}},
"print": &ctx.Command{Name: "print str", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil { // {{{
fmt.Fprintf(nfs.out, "%s\n", arg[0])
}
// }}}
}},
"listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{ if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
@ -793,7 +1069,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
sub := com.Spawn(m.Target()) sub := com.Spawn(m.Target())
sub.Put("option", "target", m.Source()) sub.Put("option", "target", m.Source())
sub.Put("option", "io", com.Data["io"]) sub.Put("option", "io", com.Data["io"])
sub.Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "打开文件") sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "打开文件")
return sub return sub
}, m.Meta["detail"]) }, m.Meta["detail"])
} }
@ -805,7 +1081,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
sub := com.Spawn(m.Target()) sub := com.Spawn(m.Target())
sub.Put("option", "target", m.Source()) sub.Put("option", "target", m.Source())
sub.Put("option", "io", com.Data["io"]) sub.Put("option", "io", com.Data["io"])
sub.Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "打开文件") sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "打开文件")
return sub return sub
}, m.Meta["detail"]) }, m.Meta["detail"])
} }
@ -916,132 +1192,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
nfs.Writer.Flush() nfs.Writer.Flush()
} // }}} } // }}}
}}, }},
"open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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); e == nil {
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)
} // }}}
}},
"read": &ctx.Command{Name: "read [size [pos]]", Help: "读取文件, size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil { // {{{
var e error
n := m.Confi("size")
if len(arg) > 0 {
n, e = strconv.Atoi(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.Echo(string(buf))
if m.Capi("pos", n); m.Capi("pos") == m.Capi("size") {
m.Cap("pos", "0")
}
} // }}}
}},
"write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
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.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
m.Cap("size", m.Cap("pos"))
}
nfs.out.Sync()
}
m.Echo(m.Cap("pos"))
} // }}}
}},
"load": &ctx.Command{Name: "load file [size]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if f, e := os.Open(arg[0]); m.Assert(e) { // {{{
defer f.Close()
m.Meta = nil
size := 1024
if len(arg) > 1 {
if s, e := strconv.Atoi(arg[1]); m.Assert(e) {
size = s
}
}
buf := make([]byte, size)
if l, e := f.Read(buf); m.Assert(e) {
m.Log("info", nil, "read %d", l)
m.Echo(string(buf[:l]))
}
} // }}}
}},
"save": &ctx.Command{Name: "save file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if f, e := os.Create(arg[0]); m.Assert(e) { // {{{
defer f.Close()
fmt.Fprint(f, strings.Join(arg[1:], ""))
} // }}}
}},
"append": &ctx.Command{Name: "append file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if f, e := os.OpenFile(arg[0], os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666); m.Assert(e) { // {{{
defer f.Close()
fmt.Fprint(f, strings.Join(arg[1:], ""))
} // }}}
}},
"genqr": &ctx.Command{Name: "genqr [size] file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
size := 256 // {{{
if len(arg) > 2 {
if s, e := strconv.Atoi(arg[0]); e == nil {
arg = arg[1:]
size = s
}
}
qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, arg[0]) // }}}
}},
"json": &ctx.Command{Name: "json file", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
buf, e := json.Marshal(m.Data["data"]) // {{{
m.Assert(e)
f, e := os.Create(arg[0])
m.Assert(e)
f.Write(buf)
f.Close()
m.Echo(string(buf))
// }}}
}},
"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) // }}}
}},
"git": &ctx.Command{Name: "git", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
cmd := exec.Command("git", arg...) // {{{
if out, e := cmd.CombinedOutput(); e != nil {
m.Echo("error: ")
m.Echo("%s\n", e)
} else {
m.Echo(string(out))
}
// }}}
}},
}, },
Index: map[string]*ctx.Context{ Index: map[string]*ctx.Context{
"void": &ctx.Context{Name: "void", "void": &ctx.Context{Name: "void",

View File

@ -96,7 +96,7 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C
msg.Option("referer", r.Header.Get("Referer")) msg.Option("referer", r.Header.Get("Referer"))
for k, v := range r.Form { for k, v := range r.Form {
msg.Add("option", k, v...) msg.Add("option", k, v)
} }
for _, v := range r.Cookies() { for _, v := range r.Cookies() {
msg.Option(v.Name, v.Value) msg.Option(v.Name, v.Value)
@ -537,7 +537,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
value := []string{} value := []string{}
json.Unmarshal([]byte(m.Option("value")), &value) json.Unmarshal([]byte(m.Option("value")), &value)
if len(value) > 0 { if len(value) > 0 {
msg.Add("detail", value[0], value[1:]...) msg.Add("detail", value[0], value[1:])
} }
} }
@ -569,7 +569,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
value := []string{} value := []string{}
json.Unmarshal([]byte(m.Option("value")), &value) json.Unmarshal([]byte(m.Option("value")), &value)
if len(value) > 0 { if len(value) > 0 {
msg.Add("detail", value[0], value[1:]...) msg.Add("detail", value[0], value[1:])
} }
} }

View File

@ -186,7 +186,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
// }}} // }}}
func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int) (string, []string) { // {{{ func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int) (string, []string) { // {{{
m.Log("debug", nil, "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line) // m.Log("debug", nil, "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line)
hash, word := 0, []string{} hash, word := 0, []string{}
for star, s := 0, page; s != 0 && len(line) > 0; { for star, s := 0, page; s != 0 && len(line) > 0; {
@ -239,15 +239,15 @@ func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int
if hash == 0 { if hash == 0 {
word = word[:0] word = word[:0]
} else { } else { //执行命令
msg := m.Spawn(m.Source()).Add("detail", yac.hand[hash], word...) msg := m.Spawn(m.Source()).Add("detail", yac.hand[hash], word)
if m.Back(msg); msg.Hand { if m.Back(msg); msg.Hand { //命令替换
m.Assert(!msg.Has("return")) m.Assert(!msg.Has("return"))
word = msg.Meta["result"] word = msg.Meta["result"]
} }
} }
m.Log("debug", nil, "%s/%d %s(%d): %v", m.Conf("label")[0:level], level, yac.name(page), page, word) // m.Log("debug", nil, "%s/%d %s(%d): %v", m.Conf("label")[0:level], level, yac.name(page), page, word)
return line, word return line, word
} }
@ -276,17 +276,16 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
return yac return yac
} }
yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"} yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: m.Confx("ncell", arg, 0), Help: "词法集合的最大数量"}
yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"} yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: m.Confx("nlang", arg, 1), Help: "语法集合的最大数量"}
yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: m.Confx("nlang", arg, 1), Help: "状态机状态的数量"}
yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"}
yac.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"}
yac.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "语法模板的数量"} yac.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "语法模板的数量"}
yac.Caches["npage"] = &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["nhash"] = &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.page = map[string]int{"nil": 0} yac.page = map[string]int{"nil": 0}
yac.word = map[int]string{0: "nil"} yac.word = map[int]string{0: "nil"}
yac.hash = map[string]int{"nil": 0} yac.hash = map[string]int{"nil": 0}
@ -308,36 +307,36 @@ func (yac *YAC) Start(m *ctx.Message, arg ...string) bool { // {{{
data := make(chan string, 1) data := make(chan string, 1)
next := make(chan bool, 1) next := make(chan bool, 1)
//加载文件
m.Options("scan_end", false) m.Options("scan_end", false)
defer func() {
if e := recover(); e != nil {
m.Option("scan_end", true)
next <- true
}
}()
//加载文件
nfs := m.Find("nfs").Call(func(buf *ctx.Message) *ctx.Message { nfs := m.Find("nfs").Call(func(buf *ctx.Message) *ctx.Message {
out = buf out = buf
data <- buf.Detail(0) + "; " data <- buf.Detail(0) + "; "
<-next <-next
return nil return nil
}, "scan_file", arg[1]) }, "scan", arg[1], "", "扫描文件")
go func() { m.Find("log").Cmd("silent", yac.Context.Name, "debug", true)
defer func() {
m.Target().Close(m.Spawn())
if e := recover(); e != nil {
m.Option("scan_end", true)
next <- true
}
}()
//解析循环 //解析循环
for m.Cap("stream", nfs.Target().Name); !m.Options("scan_end"); next <- true { for m.Cap("stream", nfs.Target().Name); !m.Options("scan_end"); next <- true {
_, word := yac.parse(m, m.Optioni("page"), m.Optioni("void"), <-data, 1) _, word := yac.parse(m, m.Optioni("page"), m.Optioni("void"), <-data, 1)
if len(word) > 0 { if len(word) > 0 {
word = word[:len(word)-1] word = word[:len(word)-1]
if last := len(word) - 1; last > 0 && len(word[last]) > 0 && word[last][len(word[last])-1] != '\n' { if last := len(word) - 1; last >= 0 && len(word[last]) > 0 && word[last][len(word[last])-1] != '\n' {
word = append(word, "\n") word = append(word, "\n")
}
} }
out.Result(0, word)
} }
}() out.Result(0, word)
}
return true
} }
return false return false
@ -359,6 +358,8 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
"nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"}, "nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"ncell": &ctx.Config{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"},
"nlang": &ctx.Config{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"},
"name": &ctx.Config{Name: "name", Value: "parse", Help: "模块名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { "name": &ctx.Config{Name: "name", Value: "parse", Help: "模块名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
if len(arg) > 0 { // {{{ if len(arg) > 0 { // {{{
return arg[0] return arg[0]
@ -372,6 +373,39 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
"label": &ctx.Config{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"}, "label": &ctx.Config{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"init": &ctx.Command{Name: "init [ncell [nlang]]", Help: "初始化语法矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if _, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{
s := new(YAC)
s.Context = m.Target()
m.Target().Server = s
m.Target().Begin(m, arg...)
}
// }}}
}},
"info": &ctx.Command{Name: "info", Help: "查看语法矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{
for i, v := range yac.seed {
m.Echo("seed: %d %v\n", i, v)
}
for i, v := range yac.page {
m.Echo("page: %s %d\n", i, v)
}
for i, v := range yac.hash {
m.Echo("hash: %s %d\n", i, v)
}
for i, v := range yac.state {
m.Echo("node: %v %v\n", i, v)
}
for i, v := range yac.mat {
for k, v := range v {
if v != nil {
m.Echo("node: %s(%d,%d): %v\n", yac.name(i), i, k, v)
}
}
}
}
// }}}
}},
"train": &ctx.Command{Name: "train page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { "train": &ctx.Command{Name: "train page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{
page, ok := yac.page[arg[0]] page, ok := yac.page[arg[0]]
@ -409,30 +443,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
} }
// }}} // }}}
}}, }},
"info": &ctx.Command{Name: "info", Help: "显示缓存", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{
for i, v := range yac.seed {
m.Echo("seed: %d %v\n", i, v)
}
for i, v := range yac.page {
m.Echo("page: %s %d\n", i, v)
}
for i, v := range yac.hash {
m.Echo("hash: %s %d\n", i, v)
}
for i, v := range yac.state {
m.Echo("node: %v %v\n", i, v)
}
for i, v := range yac.mat {
for k, v := range v {
if v != nil {
m.Echo("node: %s(%d,%d): %v\n", yac.name(i), i, k, v)
}
}
}
}
// }}}
}},
"parse": &ctx.Command{ "parse": &ctx.Command{
Name: "parse filename [name [help]] [line line] [void void]", Name: "parse filename [name [help]] [line line] [void void]",
Help: "解析文件, filename: name:模块名, help:模块帮助, 文件名, line: 默认语法, void: 默认空白", Help: "解析文件, filename: name:模块名, help:模块帮助, 文件名, line: 默认语法, void: 默认空白",