forked from x/ContextOS
mac opt nfs
This commit is contained in:
parent
fbb34936fa
commit
bd5f8f3fc9
@ -1,4 +1,5 @@
|
||||
~cli config debug on
|
||||
~file1
|
||||
history load hi.cmd
|
||||
return
|
||||
scan_file etc/demo.shy
|
||||
echo "who"
|
||||
|
@ -51,6 +51,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
if len(arg) > 0 {
|
||||
s.target = c
|
||||
}
|
||||
s.target = cli.target
|
||||
return s
|
||||
}
|
||||
|
||||
@ -280,6 +281,10 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
return nil
|
||||
}, "parse", arg[1])
|
||||
m.Cap("stream", yac.Target().Name)
|
||||
|
||||
if arg[1] == "stdio" {
|
||||
m.Spawn().Cmd("scan_file", "etc/init.shy")
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
@ -930,11 +935,17 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Echo("%s", strings.Join(arg, ""))
|
||||
}},
|
||||
"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: 模块帮助",
|
||||
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.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{
|
||||
|
@ -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["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
|
||||
|
||||
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 {
|
||||
m.Meta = make(map[string][]string)
|
||||
}
|
||||
@ -1009,13 +1039,13 @@ func (m *Message) Add(meta string, key string, value ...string) *Message { // {{
|
||||
switch meta {
|
||||
case "detail", "result":
|
||||
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":
|
||||
if _, ok := m.Meta[key]; !ok {
|
||||
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] {
|
||||
if v == key {
|
||||
@ -1055,7 +1085,7 @@ func (m *Message) Set(meta string, arg ...string) *Message { // {{{
|
||||
}
|
||||
|
||||
if len(arg) > 0 {
|
||||
m.Add(meta, arg[0], arg[1:]...)
|
||||
m.Add(meta, arg[0], arg[1:])
|
||||
}
|
||||
|
||||
return m
|
||||
@ -1148,7 +1178,7 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // {
|
||||
|
||||
for _, k := range arg {
|
||||
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 {
|
||||
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 {
|
||||
return m
|
||||
}
|
||||
|
||||
//计算列宽
|
||||
width := make(map[string]int, len(m.Meta[m.Meta["append"][0]]))
|
||||
for _, k := range m.Meta["append"] {
|
||||
title := k
|
||||
@ -1182,6 +1213,7 @@ func (m *Message) Table(cb func(map[string]string, []string, int) bool) *Message
|
||||
}
|
||||
}
|
||||
|
||||
//输出字段名
|
||||
row := map[string]string{}
|
||||
wor := []string{}
|
||||
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{}
|
||||
for _, k := range m.Meta["append"] {
|
||||
data := m.Meta[k][i]
|
||||
//解析extra字段
|
||||
if m.Options("extras") && k == "extra" {
|
||||
var extra interface{}
|
||||
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 s := c; s != nil; s = s.context {
|
||||
|
||||
if x, ok := s.Commands[key]; ok && x.Hand != nil && c.Check(m, "commands", key) {
|
||||
m.TryCatch(m, true, func(m *Message) {
|
||||
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
|
||||
// }
|
||||
//
|
||||
m.Add("option", arg[i], arg[i+1:i+1+n]...)
|
||||
m.Add("option", arg[i], arg[i+1:i+1+n])
|
||||
i += n
|
||||
}
|
||||
arg = m.Meta["args"]
|
||||
@ -2414,7 +2446,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
for i, v := range msg.messages {
|
||||
if !all {
|
||||
switch v.target.Name {
|
||||
case "log", "yac":
|
||||
case "log", "yac", "lex":
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -3373,6 +3405,6 @@ func Start(args ...string) {
|
||||
Pulse.Options("terminal_color", true)
|
||||
Pulse.Sesss("log", "log").Conf("bench.log", Pulse.Conf("bench.log"))
|
||||
|
||||
Pulse.Find("cli").Cmd("scan_file", "etc/init.shy")
|
||||
Pulse.Find("cli").Cmd("scan_file", "stdio")
|
||||
cli := Pulse.Find("cli").Cmd("scan_file", "stdio", "async")
|
||||
<-cli.target.Exit
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import ( // {{{
|
||||
|
||||
type LOG struct {
|
||||
module map[string]map[string]bool
|
||||
slient map[string]bool
|
||||
silent map[string]bool
|
||||
color map[string]int
|
||||
*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 { // {{{
|
||||
if log.Context == Index {
|
||||
Pulse = m
|
||||
}
|
||||
log.Context.Master(nil)
|
||||
log.Message = m
|
||||
|
||||
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 m.Sess("nfs") == nil {
|
||||
os.Create(arg[0])
|
||||
m.Sess("nfs", "nfs").Cmd("open", arg[0])
|
||||
m.Sess("nfs", "nfs").Cmd("open", arg[0], "", "日志文件")
|
||||
}
|
||||
return arg[0]
|
||||
}
|
||||
@ -82,12 +78,12 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
|
||||
Caches: map[string]*ctx.Cache{},
|
||||
Configs: map[string]*ctx.Config{},
|
||||
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) { // {{{
|
||||
switch len(arg) {
|
||||
case 2:
|
||||
if len(arg) > 1 {
|
||||
log.slient[arg[0]] = ctx.Right(arg[1])
|
||||
log.silent[arg[0]] = ctx.Right(arg[1])
|
||||
}
|
||||
case 3:
|
||||
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])
|
||||
}
|
||||
|
||||
for k, v := range log.slient {
|
||||
for k, v := range log.silent {
|
||||
m.Echo("%s: %t\n", k, v)
|
||||
}
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
@ -216,7 +212,7 @@ func init() {
|
||||
"close": 36,
|
||||
"debug": 0,
|
||||
}
|
||||
log.slient = map[string]bool{
|
||||
log.silent = map[string]bool{
|
||||
// "lock": true,
|
||||
}
|
||||
log.module = map[string]map[string]bool{
|
||||
|
@ -9,9 +9,11 @@ import ( // {{{
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -21,17 +23,17 @@ import ( // {{{
|
||||
// }}}
|
||||
|
||||
type NFS struct {
|
||||
in *os.File
|
||||
out *os.File
|
||||
history []string
|
||||
|
||||
io io.ReadWriteCloser
|
||||
*bufio.Reader
|
||||
*bufio.Writer
|
||||
send map[int]*ctx.Message
|
||||
target *ctx.Context
|
||||
|
||||
in *os.File
|
||||
out *os.File
|
||||
|
||||
cli *ctx.Message
|
||||
buf []string
|
||||
pages []string
|
||||
|
||||
width, height int
|
||||
@ -40,6 +42,71 @@ type NFS struct {
|
||||
*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 { // {{{
|
||||
n := len(rest)
|
||||
l := len(letters)
|
||||
@ -207,7 +274,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{
|
||||
|
||||
back := buf
|
||||
|
||||
his := len(nfs.buf)
|
||||
his := len(nfs.history)
|
||||
|
||||
tab := []string{}
|
||||
tabi := 0
|
||||
@ -238,21 +305,21 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{
|
||||
return
|
||||
|
||||
case termbox.KeyCtrlP:
|
||||
for i := 0; i < len(nfs.buf); i++ {
|
||||
his = (his + len(nfs.buf) - 1) % len(nfs.buf)
|
||||
if strings.HasPrefix(nfs.buf[his], string(buf)) {
|
||||
for i := 0; i < len(nfs.history); i++ {
|
||||
his = (his + len(nfs.history) - 1) % len(nfs.history)
|
||||
if strings.HasPrefix(nfs.history[his], string(buf)) {
|
||||
rest = rest[:0]
|
||||
rest = append(rest, []rune(nfs.buf[his][len(buf):])...)
|
||||
rest = append(rest, []rune(nfs.history[his][len(buf):])...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case termbox.KeyCtrlN:
|
||||
for i := 0; i < len(nfs.buf); i++ {
|
||||
his = (his + len(nfs.buf) + 1) % len(nfs.buf)
|
||||
if strings.HasPrefix(nfs.buf[his], string(buf)) {
|
||||
for i := 0; i < len(nfs.history); i++ {
|
||||
his = (his + len(nfs.history) + 1) % len(nfs.history)
|
||||
if strings.HasPrefix(nfs.history[his], string(buf)) {
|
||||
rest = rest[:0]
|
||||
rest = append(rest, []rune(nfs.buf[his][len(buf):])...)
|
||||
rest = append(rest, []rune(nfs.history[his][len(buf):])...)
|
||||
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 { // {{{
|
||||
if len(arg) > 0 && arg[0] == "scan_file" {
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
nfs.Message = m
|
||||
c.Caches = map[string]*ctx.Cache{
|
||||
"nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"},
|
||||
"nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"},
|
||||
}
|
||||
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 {
|
||||
c.Caches = map[string]*ctx.Cache{
|
||||
"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 { // {{{
|
||||
nfs.Message = m
|
||||
nfs.Context.Master(nil)
|
||||
if nfs.Context == Index {
|
||||
Pulse = m
|
||||
}
|
||||
return nfs
|
||||
}
|
||||
|
||||
// }}}
|
||||
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.in = m.Optionv("in").(*os.File)
|
||||
bio := bufio.NewScanner(nfs)
|
||||
|
||||
if m.Options("stdout", m.Cap("stream", arg[1]) == "stdio") {
|
||||
if m.Cap("stream", arg[1]) == "stdio" {
|
||||
termbox.Init()
|
||||
defer termbox.Close()
|
||||
nfs.out = m.Optionv("out").(*os.File)
|
||||
}
|
||||
|
||||
line := ""
|
||||
for nfs.prompt(); bio.Scan(); nfs.prompt() {
|
||||
text := bio.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") {
|
||||
break
|
||||
}
|
||||
@ -462,10 +538,21 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
m.Capi("nwrite", len(v))
|
||||
nfs.print(v)
|
||||
}
|
||||
line = ""
|
||||
}
|
||||
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.Sessions["nfs"] = m
|
||||
|
||||
@ -596,95 +683,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
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
|
||||
}
|
||||
|
||||
@ -696,6 +694,14 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
nfs.in.Close()
|
||||
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():
|
||||
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: "存储中心",
|
||||
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{
|
||||
"size": &ctx.Config{Name: "size", Value: "1024", Help: "读取文件的默认大小值"},
|
||||
"color": &ctx.Config{Name: "color", Value: "9", Help: "读取文件的默认大小值"},
|
||||
"backcolor": &ctx.Config{Name: "backcolor", Value: "9", Help: "读取文件的默认大小值"},
|
||||
"pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "读取文件的默认大小值"},
|
||||
"statuscolor": &ctx.Config{Name: "statuspscolor", Value: "1", 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 { // {{{
|
||||
return arg[0]
|
||||
}
|
||||
return fmt.Sprintf("%s%d", x.Value, m.Capi("nfile", 1))
|
||||
// }}}
|
||||
}},
|
||||
"nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"},
|
||||
"buffer_size": &ctx.Config{Name: "buffer_size", Value: "1024", Help: "缓存区大小"},
|
||||
"help": &ctx.Config{Name: "help", Value: "file", 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{
|
||||
"scan_file": &ctx.Command{
|
||||
Name: "scan_file filename [nfs_name [nfs_help]]",
|
||||
Help: "扫描文件, filename: 文件名, nfs_name: 模块名, nfs_help: 模块帮助",
|
||||
"scan": &ctx.Command{
|
||||
Name: "scan filename [name [help]]",
|
||||
Help: "扫描文件, filename: 文件名, name: 模块名, help: 模块帮助",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{
|
||||
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.Optionv("in", os.Stdin)
|
||||
m.Optionv("out", os.Stdout)
|
||||
} else if f, e := os.Open(arg[0]); m.Assert(e) {
|
||||
m.Optionv("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) {
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.buf != nil { // {{{
|
||||
for i, v := range nfs.buf {
|
||||
"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) { // {{{
|
||||
if len(arg) == 0 {
|
||||
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) {
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && len(nfs.buf) > 0 { // {{{
|
||||
begin, end := 0, len(nfs.buf)
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && len(nfs.history) > 0 { // {{{
|
||||
begin, end := 0, len(nfs.history)
|
||||
if len(arg) > 1 {
|
||||
i, e := strconv.Atoi(arg[1])
|
||||
m.Assert(e)
|
||||
@ -768,24 +1058,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
m.Assert(e)
|
||||
end = i
|
||||
}
|
||||
m.Put("option", "buf", nfs.buf[begin:end])
|
||||
m.Put("option", "buf", nfs.history[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" { // {{{
|
||||
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) {
|
||||
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.Put("option", "target", m.Source())
|
||||
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
|
||||
}, m.Meta["detail"])
|
||||
}
|
||||
@ -805,7 +1081,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
sub := com.Spawn(m.Target())
|
||||
sub.Put("option", "target", m.Source())
|
||||
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
|
||||
}, m.Meta["detail"])
|
||||
}
|
||||
@ -916,132 +1192,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
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{
|
||||
"void": &ctx.Context{Name: "void",
|
||||
|
@ -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"))
|
||||
|
||||
for k, v := range r.Form {
|
||||
msg.Add("option", k, v...)
|
||||
msg.Add("option", k, v)
|
||||
}
|
||||
for _, v := range r.Cookies() {
|
||||
msg.Option(v.Name, v.Value)
|
||||
@ -537,7 +537,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
value := []string{}
|
||||
json.Unmarshal([]byte(m.Option("value")), &value)
|
||||
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{}
|
||||
json.Unmarshal([]byte(m.Option("value")), &value)
|
||||
if len(value) > 0 {
|
||||
msg.Add("detail", value[0], value[1:]...)
|
||||
msg.Add("detail", value[0], value[1:])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) { // {{{
|
||||
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{}
|
||||
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 {
|
||||
word = word[:0]
|
||||
} else {
|
||||
msg := m.Spawn(m.Source()).Add("detail", yac.hand[hash], word...)
|
||||
if m.Back(msg); msg.Hand {
|
||||
} else { //执行命令
|
||||
msg := m.Spawn(m.Source()).Add("detail", yac.hand[hash], word)
|
||||
if m.Back(msg); msg.Hand { //命令替换
|
||||
m.Assert(!msg.Has("return"))
|
||||
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
|
||||
}
|
||||
|
||||
@ -276,17 +276,16 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
return yac
|
||||
}
|
||||
|
||||
yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"}
|
||||
yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"}
|
||||
yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: m.Confx("ncell", arg, 0), 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["npage"] = &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.word = map[int]string{0: "nil"}
|
||||
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)
|
||||
next := make(chan bool, 1)
|
||||
|
||||
//加载文件
|
||||
m.Options("scan_end", false)
|
||||
nfs := m.Find("nfs").Call(func(buf *ctx.Message) *ctx.Message {
|
||||
out = buf
|
||||
data <- buf.Detail(0) + "; "
|
||||
<-next
|
||||
return nil
|
||||
}, "scan_file", arg[1])
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
m.Target().Close(m.Spawn())
|
||||
if e := recover(); e != nil {
|
||||
m.Option("scan_end", true)
|
||||
next <- true
|
||||
}
|
||||
}()
|
||||
|
||||
//加载文件
|
||||
nfs := m.Find("nfs").Call(func(buf *ctx.Message) *ctx.Message {
|
||||
out = buf
|
||||
data <- buf.Detail(0) + "; "
|
||||
<-next
|
||||
return nil
|
||||
}, "scan", arg[1], "", "扫描文件")
|
||||
|
||||
m.Find("log").Cmd("silent", yac.Context.Name, "debug", 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)
|
||||
if len(word) > 0 {
|
||||
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")
|
||||
}
|
||||
}
|
||||
out.Result(0, word)
|
||||
}
|
||||
}()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
@ -359,6 +358,8 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
"nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"},
|
||||
},
|
||||
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 {
|
||||
if len(arg) > 0 { // {{{
|
||||
return arg[0]
|
||||
@ -372,6 +373,39 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
"label": &ctx.Config{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"},
|
||||
},
|
||||
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) {
|
||||
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{
|
||||
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{
|
||||
Name: "parse filename [name [help]] [line line] [void void]",
|
||||
Help: "解析文件, filename: name:模块名, help:模块帮助, 文件名, line: 默认语法, void: 默认空白",
|
||||
|
Loading…
x
Reference in New Issue
Block a user