1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-29 18:19:22 +08:00

opt nfs.dir

This commit is contained in:
shaoying 2019-07-24 09:48:31 +08:00
parent 002b42b68e
commit d8c56f8eba
3 changed files with 270 additions and 295 deletions

View File

@ -4,5 +4,5 @@ var version = struct {
host string host string
self int self int
}{ }{
"2019-07-23 21:26:44", "ZYB-20190522USI", 232, "2019-07-24 09:10:27", "com.mac_14", 216,
} }

View File

@ -1,35 +1,34 @@
package nfs package nfs
import ( import (
"github.com/skip2/go-qrcode"
"contexts/ctx" "contexts/ctx"
"crypto/md5" "crypto/md5"
"toolkit" "toolkit"
"bufio"
"crypto/sha1" "crypto/sha1"
"encoding/csv" "encoding/csv"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/skip2/go-qrcode"
"net/url"
"regexp"
"strings"
"bufio"
"github.com/nsf/termbox-go"
"io" "io"
"io/ioutil" "io/ioutil"
"net/url"
"os" "os"
"os/exec" "os/exec"
"path" "path"
"regexp"
"sort" "sort"
"strings"
"time" "time"
) )
type NFS struct { type NFS struct {
io io.ReadWriter
in *os.File in *os.File
out *os.File out *os.File
io io.ReadWriter
send chan *ctx.Message send chan *ctx.Message
echo chan *ctx.Message echo chan *ctx.Message
@ -38,21 +37,19 @@ type NFS struct {
*ctx.Context *ctx.Context
} }
func dir(m *ctx.Message, name string, level int, deep bool, dir_type string, trip int, dir_reg *regexp.Regexp, fields []string, format string) { func dir(m *ctx.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string, format string) {
back, e := os.Getwd()
m.Assert(e)
if fs, e := ioutil.ReadDir(name); m.Assert(e) { if fs, e := ioutil.ReadDir(name); m.Assert(e) {
for _, f := range fs { for _, f := range fs {
if f.Name() == "." || f.Name() == ".." { if f.Name() == "." || f.Name() == ".." {
continue continue
} }
if strings.HasPrefix(f.Name(), ".") && dir_type != "all" { if strings.HasPrefix(f.Name(), ".") && dir_type != "all" {
continue continue
} }
f, e := os.Stat(path.Join(name, f.Name())) p := path.Join(name, f.Name())
f, e := os.Stat(p)
if e != nil { if e != nil {
m.Log("info", "%s", e) m.Log("info", "%s", e)
continue continue
@ -71,15 +68,21 @@ func dir(m *ctx.Message, name string, level int, deep bool, dir_type string, tri
} }
case "full": case "full":
if f.IsDir() { if f.IsDir() {
m.Add("append", "full", path.Join(back, name, f.Name())+"/") m.Add("append", "full", path.Join(root, name, f.Name())+"/")
} else { } else {
m.Add("append", "full", path.Join(back, name, f.Name())) m.Add("append", "full", path.Join(root, name, f.Name()))
} }
case "path": case "path":
if f.IsDir() { if f.IsDir() {
m.Add("append", "path", path.Join(back, name, f.Name())[trip:]+"/") m.Add("append", "path", path.Join(name, f.Name())+"/")
} else { } else {
m.Add("append", "path", path.Join(back, name, f.Name())[trip:]) m.Add("append", "path", path.Join(name, f.Name()))
}
case "name":
if f.IsDir() {
m.Add("append", "name", f.Name()+"/")
} else {
m.Add("append", "name", f.Name())
} }
case "tree": case "tree":
if level == 0 { if level == 0 {
@ -87,51 +90,39 @@ func dir(m *ctx.Message, name string, level int, deep bool, dir_type string, tri
} else { } else {
m.Add("append", "tree", strings.Repeat("| ", level-1)+"|-"+f.Name()) m.Add("append", "tree", strings.Repeat("| ", level-1)+"|-"+f.Name())
} }
case "filename":
if f.IsDir() {
m.Add("append", "filename", f.Name()+"/")
} else {
m.Add("append", "filename", f.Name())
}
case "size": case "size":
m.Add("append", "size", f.Size()) m.Add("append", "size", f.Size())
case "line": case "line":
nline := 0
if f.IsDir() { if f.IsDir() {
d, e := ioutil.ReadDir(path.Join(name, f.Name())) if d, e := ioutil.ReadDir(p); m.Assert(e) {
m.Assert(e) m.Add("append", "line", len(d))
nline = len(d) }
} else { } else {
f, e := os.Open(path.Join(name, f.Name())) nline := 0
m.Assert(e) if f, e := os.Open(p); m.Assert(e) {
defer f.Close() defer f.Close()
for bio := bufio.NewScanner(f); bio.Scan(); nline++ {
bio := bufio.NewScanner(f)
for bio.Scan() {
bio.Text() bio.Text()
nline++
} }
} }
m.Add("append", "line", nline) m.Add("append", "line", nline)
}
case "hash", "hashs": case "hash", "hashs":
var h [20]byte
if f.IsDir() { if f.IsDir() {
d, e := ioutil.ReadDir(path.Join(name, f.Name())) if d, e := ioutil.ReadDir(p); m.Assert(e) {
m.Assert(e)
meta := []string{} meta := []string{}
for _, v := range d { for _, v := range d {
meta = append(meta, fmt.Sprintf("%s%d%s", v.Name(), v.Size(), v.ModTime())) meta = append(meta, fmt.Sprintf("%s%d%s", v.Name(), v.Size(), v.ModTime()))
} }
sort.Strings(meta) sort.Strings(meta)
h = sha1.Sum([]byte(strings.Join(meta, "")))
h := sha1.Sum([]byte(strings.Join(meta, ""))) }
m.Add("append", "hash", hex.EncodeToString(h[:])) } else {
break if f, e := ioutil.ReadFile(path.Join(name, f.Name())); m.Assert(e) {
h = sha1.Sum(f)
}
} }
f, e := ioutil.ReadFile(path.Join(name, f.Name()))
m.Assert(e)
h := sha1.Sum(f)
if field == "hash" { if field == "hash" {
m.Add("append", "hash", hex.EncodeToString(h[:])) m.Add("append", "hash", hex.EncodeToString(h[:]))
} else { } else {
@ -141,25 +132,65 @@ func dir(m *ctx.Message, name string, level int, deep bool, dir_type string, tri
} }
} }
if f.IsDir() && deep { if f.IsDir() && deep {
dir(m, path.Join(name, f.Name()), level+1, deep, dir_type, trip, dir_reg, fields, format) dir(m, root, p, level+1, deep, dir_type, dir_reg, fields, format)
} }
} }
} }
} }
func sed(m *ctx.Message, p string, args []string) error {
p0 := p + ".tmp0"
p1 := p + ".tmp1"
if _, e := os.Stat(p1); e == nil {
return e
}
out, e := os.Create(p1)
defer os.Remove(p1)
defer out.Close()
m.Log("info", "open %v", p1)
if _, e := os.Stat(p0); e != nil {
m.Cmd("nfs.copy", p0, p)
}
in, e := os.Open(p0)
defer in.Close()
m.Log("info", "open %v", p0)
switch args[0] {
case "set":
defer os.Rename(p1, p0)
defer os.Remove(p0)
index := kit.Int(args[1])
for bio, i := bufio.NewScanner(in), 0; bio.Scan(); i++ {
if i == index {
out.WriteString(args[2])
} else {
out.WriteString(bio.Text())
}
out.WriteString("\n")
}
return e
case "add":
out0, _ := os.OpenFile(p0, os.O_WRONLY|os.O_APPEND, 0666)
defer out0.Close()
out0.WriteString("\n")
case "put":
defer os.Rename(p0, p)
}
return nil
}
func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) { func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) {
if !path.IsAbs(name) { if !path.IsAbs(name) {
pwd := m.Confv("pwd").([]interface{}) m.Confm("pwd", func(i int, v string) bool {
for _, v := range pwd { p := path.Join(v, name)
p := path.Join(v.(string), name)
if len(arg) > 0 {
name = p
break
}
if s, e := os.Stat(p); e == nil && !s.IsDir() { if s, e := os.Stat(p); e == nil && !s.IsDir() {
name = p name = p
break return true
}
} }
return false
})
} }
flag := os.O_RDONLY flag := os.O_RDONLY
@ -170,9 +201,9 @@ func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) {
f, e := os.OpenFile(name, flag, 0660) f, e := os.OpenFile(name, flag, 0660)
if e == nil { if e == nil {
m.Log("info", "open %s", name) m.Log("info", "open %s", name)
return name, f, e } else {
}
m.Log("warn", "%v", e) m.Log("warn", "%v", e)
}
return name, f, e return name, f, e
} }
@ -382,7 +413,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
// 消息接收队列 // 消息接收队列
msg, code, head, body := m, "0", "result", "append" msg, code, head, body := m, "0", "result", "append"
bio := bufio.NewScanner(nfs.io) bio := bufio.NewScanner(nfs.io)
bio.Buffer(make([]byte, m.Confi("buf_size")), m.Confi("buf_size")) bio.Buffer(make([]byte, m.Confi("buf", "size")), m.Confi("buf", "size"))
for bio.Scan() { for bio.Scan() {
m.TryCatch(m, true, func(m *ctx.Message) { m.TryCatch(m, true, func(m *ctx.Message) {
@ -440,7 +471,7 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool {
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: "已经打开的文件数量"}, "bio": &ctx.Cache{Name: "bio", Value: "0", Help: "文件数量"},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"term": &ctx.Config{Name: "term", Value: map[string]interface{}{ "term": &ctx.Config{Name: "term", Value: map[string]interface{}{
@ -471,7 +502,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"help_next_auto": "=", "help_next_auto": "=",
"help_stack": []interface{}{}, "help_stack": []interface{}{},
"help_table": map[string]interface{}{}, "help_table": map[string]interface{}{},
}, Help: "二维码的默认大小"}, }, Help: "终端管理"},
"auto": &ctx.Config{Name: "auto", Value: map[string]interface{}{ "auto": &ctx.Config{Name: "auto", Value: map[string]interface{}{
"!": map[string]interface{}{ "!": map[string]interface{}{
"state": "message", "state": "message",
@ -516,12 +547,14 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"table": "cache", "field": "key", "table": "cache", "field": "key",
"format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"}, "format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"},
}, },
}, Help: "读取文件的缓存区的大小"}, }, Help: "自动补全"},
"buf_size": &ctx.Config{Name: "buf_size", Value: "81920", Help: "读取文件的缓存区的大小"}, "buf": &ctx.Config{Name: "buf", Value: map[string]interface{}{
"size": "81920",
}, Help: "文件缓存"},
"grep": &ctx.Config{Name: "grep", Value: map[string]interface{}{ "grep": &ctx.Config{Name: "grep", Value: map[string]interface{}{
"list": []interface{}{}, "list": []interface{}{},
}, Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"}, }, Help: "文件搜索"},
"git": &ctx.Config{Name: "git", Value: map[string]interface{}{ "git": &ctx.Config{Name: "git", Value: map[string]interface{}{
"args": []interface{}{"-C", "@git_dir"}, "args": []interface{}{"-C", "@git_dir"},
"info": map[string]interface{}{"cmds": []interface{}{"log", "status", "branch"}}, "info": map[string]interface{}{"cmds": []interface{}{"log", "status", "branch"}},
@ -535,14 +568,16 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"date": "--date=format:%m/%d %H:%M", "date": "--date=format:%m/%d %H:%M",
"pretty": "--pretty=format:%h %ad %an %s", "pretty": "--pretty=format:%h %ad %an %s",
}, },
}, Help: "命令集合"}, }, Help: "版本管理"},
"dir_fields": &ctx.Config{Name: "dir_fields(time/type/name/size/line/hash)", Value: "time size line filename", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"},
"dir_type": &ctx.Config{Name: "dir_type(file/dir/both/all)", Value: "both", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"},
"dir": &ctx.Config{Name: "dir", Value: map[string]interface{}{ "dir": &ctx.Config{Name: "dir", Value: map[string]interface{}{
"fields": "time size line path",
"type": "both",
"temp": "var/tmp/file", "temp": "var/tmp/file",
"trash": "var/tmp/trash", "trash": "var/tmp/trash",
}, Help: ""}, }, Help: "目录管理"},
"pwd": &ctx.Config{Name: "pwd", Value: []interface{}{"var", "usr", "bin", "etc", ""}, Help: "当前目录"}, "pwd": &ctx.Config{Name: "pwd", Value: []interface{}{
"var", "usr", "bin", "etc", "",
}, Help: "当前目录"},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
"_init": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "_init": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -551,9 +586,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
return return
}}, }},
"_exit": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "_exit": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Confs("term", "use") { m.Cmd("nfs.term", "exit")
termbox.Close()
}
return return
}}, }},
"path": &ctx.Command{Name: "path filename", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "path": &ctx.Command{Name: "path filename", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -593,7 +626,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
} }
return return
}}, }},
"dir": &ctx.Command{Name: "dir [path [fields...]]", Help: []string{"查看目录, path: 路径, fields...: 查询字段, time|type|full|path|tree|filename|size|line|hash", "dir": &ctx.Command{Name: "dir [path [fields...]]", Help: []string{
"查看目录, path: 路径, fields...: 查询字段, time|type|full|path|name|tree|size|line|hash|hashs",
"dir_deep: 递归查询", "dir_type both|file|dir|all: 文件类型", "dir_reg reg: 正则表达式", "dir_sort field order: 排序"}, "dir_deep: 递归查询", "dir_type both|file|dir|all: 文件类型", "dir_reg reg: 正则表达式", "dir_sort field order: 排序"},
Form: map[string]int{"dir_deep": 0, "dir_type": 1, "dir_reg": 1, "dir_sort": 2, "dir_sed": -1}, Form: map[string]int{"dir_deep": 0, "dir_type": 1, "dir_reg": 1, "dir_sort": 2, "dir_sed": -1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -601,86 +635,41 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
arg = append(arg, "") arg = append(arg, "")
} }
p := arg[0]
p0 := p + ".tmp0"
p1 := p + ".tmp1"
if args := kit.Trans(m.Optionv("dir_sed")); len(args) > 0 { if args := kit.Trans(m.Optionv("dir_sed")); len(args) > 0 {
if _, e := os.Stat(p1); e == nil { return sed(m, arg[0], args)
return e
} }
out, e := os.Create(p1)
defer os.Remove(p1)
defer out.Close()
m.Log("info", "open %v", p1)
if _, e := os.Stat(p0); e != nil {
m.Cmd("nfs.copy", p0, p)
}
in, e := os.Open(p0)
defer in.Close()
m.Log("info", "open %v", p0)
switch args[0] {
case "set":
defer os.Rename(p1, p0)
defer os.Remove(p0)
index := kit.Int(args[1])
for bio, i := bufio.NewScanner(in), 0; bio.Scan(); i++ {
if i == index {
out.WriteString(args[2])
} else {
out.WriteString(bio.Text())
}
out.WriteString("\n")
}
return e
case "add":
out0, _ := os.OpenFile(p0, os.O_WRONLY|os.O_APPEND, 0666)
defer out0.Close()
out0.WriteString("\n")
case "put":
defer os.Rename(p0, p)
}
return e
}
wd, e := os.Getwd()
m.Assert(e)
trip := len(wd) + 1
rg, e := regexp.Compile(m.Option("dir_reg"))
m.Confm("pwd", func(index int, value string) bool { m.Confm("pwd", func(index int, value string) bool {
// p := path.Join(value, m.Option("dir_root"), arg[0]) // p := path.Join(value, m.Option("dir_root"), arg[0])
p := path.Join(value, arg[0]) p := path.Join(value, arg[0])
if s, e := os.Stat(p); e == nil { if s, e := os.Stat(p); e == nil {
if s.IsDir() { if s.IsDir() {
dir(m, p, 0, kit.Right(m.Has("dir_deep")), m.Confx("dir_type"), trip, rg, rg, _ := regexp.Compile(m.Option("dir_reg"))
strings.Split(m.Confx("dir_fields", strings.Join(arg[1:], " ")), " "), dir_type := kit.Select(m.Conf("dir", "type"), m.Option("dir_type"))
m.Conf("time", "format")) fields := strings.Split(kit.Select(m.Conf("dir", "fields"), strings.Join(arg[1:], " ")), " ")
dir(m, kit.Pwd(), p, 0, kit.Right(m.Has("dir_deep")),
dir_type, rg, fields, m.Conf("time", "format"))
} else if s.Size() > int64(m.Confi("buf", "size")) {
m.Append("directory", p)
} else { } else {
if s.Size() < int64(m.Confi("buf_size")) {
p0 := p + ".tmp0" p0 := p + ".tmp0"
f, e := os.Open(p0) f, e := os.Open(p0)
if e != nil { if e != nil {
f, e = os.Open(p) if f, e = os.Open(p); e == nil {
m.Log("info", "open %v", p) p0 = p
} else {
p = p0
m.Log("info", "open %v", p0)
} }
}
m.Log("info", "open %v", p0)
for bio := bufio.NewScanner(f); bio.Scan(); { for bio := bufio.NewScanner(f); bio.Scan(); {
m.Echo(bio.Text()) m.Echo(bio.Text())
} }
m.Append("file", p) m.Append("file", p)
m.Append("size", s.Size()) m.Append("size", s.Size())
m.Append("time", s.ModTime().Format(m.Conf("time", "format"))) m.Append("time", s.ModTime().Format(m.Conf("time", "format")))
} else {
m.Append("directory", p)
}
} }
return true return true
} }
@ -696,10 +685,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Echo(v).Echo(" ") m.Echo(v).Echo(" ")
} }
} else { } else {
if !m.Appends("file") {
m.Table() m.Table()
} }
}
return return
}}, }},
"git": &ctx.Command{Name: "git sum", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "git": &ctx.Command{Name: "git sum", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -920,7 +907,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
if p, f, e := open(m, arg[0]); e == nil { if p, f, e := open(m, arg[0]); e == nil {
defer f.Close() defer f.Close()
size := kit.Int(m.Confx("buf_size", arg, 1)) size := kit.Int(kit.Select(m.Conf("buf", "size"), arg, 1))
if size == -1 { if size == -1 {
if s, e := f.Stat(); m.Assert(e) { if s, e := f.Stat(); m.Assert(e) {
size = int(s.Size()) size = int(s.Size())
@ -1099,7 +1086,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Cap("pos", arg[1]) m.Cap("pos", arg[1])
} }
buf := make([]byte, kit.Int(m.Confx("buf_size", arg, 0))) buf := make([]byte, kit.Int(kit.Select(m.Conf("buf", "size"), arg, 0)))
if n, e := nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e == io.EOF || m.Assert(e) { if n, e := nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e == io.EOF || m.Assert(e) {
m.Capi("nread", n) m.Capi("nread", n)
if m.Capi("pos", n); n == 0 { if m.Capi("pos", n); n == 0 {
@ -1133,33 +1120,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
return return
}}, }},
"printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
nfs.print(arg...)
}
return
}},
"prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
nfs.prompt(arg)
}
return
}},
"term": &ctx.Command{Name: "term action args...", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
nfs.Term(m, arg[0], arg[1:])
}
return
}},
"action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
msg := m.Cmd("cli.source", arg)
// nfs.print(msg.Conf("prompt"), arg, "\n")
nfs.print(msg.Meta["result"]...)
}
return
}},
"source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 { if len(arg) == 0 {
m.Cmdy("dir", "src", "time", "line", "path", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$") m.Cmdy("dir", "src", "time", "line", "path", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$")
@ -1180,26 +1140,42 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
} }
return return
}}, }},
"arguments": &ctx.Command{Name: "arguments", Help: "脚本参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
args := kit.Trans(m.Optionv("bio.args")) if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
if len(arg) == 0 { nfs.prompt(strings.Join(arg, ""))
m.Set("result", args) }
} else { return
m.Echo(kit.Select("", args, kit.Int(arg[0]))) }},
"printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
nfs.print(arg...)
}
return
}},
"action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
msg := m.Cmd("nfs.source", arg)
nfs.print(msg.Meta["result"]...)
}
return
}},
"term": &ctx.Command{Name: "term action args...", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
nfs.Term(m, arg[0], arg[1:])
} }
return return
}}, }},
"remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "remote": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{ if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message { m.Sess("tcp").Call(func(msg *ctx.Message) *ctx.Message {
if sub.Has("node.port") { if msg.Has("node.port") {
return sub return msg
} }
sub.Sess("ms_source", sub) msg.Sess("ms_source", msg)
sub.Sess("ms_target", m.Source()) msg.Sess("ms_target", m.Source())
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件") msg.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
return sub return msg
}, arg) }, arg)
} }
return return

View File

@ -243,7 +243,7 @@ func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, stack *kit.Stack, page i
word = word[:0] word = word[:0]
} else if !m.Confs("exec", []string{"disable", yac.hand[hash]}) { } else if !m.Confs("exec", []string{"disable", yac.hand[hash]}) {
if stack.Peek().Run || m.Confs("exec", []string{"always", yac.hand[hash]}) { if stack == nil || stack.Peek().Run || m.Confs("exec", []string{"always", yac.hand[hash]}) {
//执行命令 //执行命令
cmd := msg.Spawn(m.Optionv("bio.ctx")) cmd := msg.Spawn(m.Optionv("bio.ctx"))
if cmd.Cmd(yac.hand[hash], word); cmd.Hand { if cmd.Cmd(yac.hand[hash], word); cmd.Hand {
@ -317,8 +317,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "<", "<=", ">", ">=", "==", "!=", "}"}}, map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "<", "<=", ">", ">=", "==", "!=", "}"}},
map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}"}}, map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}"}},
map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"val", "rep{", "op2", "val", "}"}}, map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"val", "rep{", "op2", "val", "}"}},
map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "opt{", "=", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}}, map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}},
// 命令语句 // 命令语句
@ -329,12 +327,13 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
// 复合语句 // 复合语句
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"$", "(", "cmd", ")"}}, map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"$", "(", "cmd", ")"}},
map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "opt{", "=", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}}, map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}},
map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}}, map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "key", "}"}},
map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else", "opt{", "if", "exp", "}"}}, map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else", "opt{", "if", "exp", "}"}},
map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}}, map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}},
map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "key", "}"}},
/* /*
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-z", "-n", "}"}}, map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-z", "-n", "}"}},
@ -420,7 +419,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
}}, }},
"parse": &ctx.Command{Name: "parse line", Help: "解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "parse": &ctx.Command{Name: "parse line", Help: "解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
stack := m.Optionv("bio.stack").(*kit.Stack) stack, _ := m.Optionv("bio.stack").(*kit.Stack)
m.Optioni("yac.page", yac.page[m.Conf("nline")]) m.Optioni("yac.page", yac.page[m.Conf("nline")])
m.Optioni("yac.void", yac.page[m.Conf("nvoid")]) m.Optioni("yac.void", yac.page[m.Conf("nvoid")])
@ -734,29 +733,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
m.Echo("%s", num[0]) m.Echo("%s", num[0])
return return
}}, }},
"let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[2] {
case "=":
m.Cap(arg[1], arg[3])
m.Log("stack", "let %v = %v", arg[1], arg[3])
case "<-":
m.Cap(arg[1], m.Cap("last_msg"))
}
m.Echo(m.Cap(arg[1]))
return
}},
"var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 {
switch arg[2] {
case "=":
m.Cap(arg[1], arg[3])
case "<-":
m.Cap(arg[1], m.Cap("last_msg"))
}
}
m.Echo(m.Cap(arg[1]))
return
}},
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Appends("bio.end", true) m.Appends("bio.end", true)
m.Result(arg[1:]) m.Result(arg[1:])
@ -956,6 +932,29 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
return return
}}, }},
"var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 {
switch arg[2] {
case "=":
m.Cap(arg[1], arg[3])
case "<-":
m.Cap(arg[1], m.Cap("last_msg"))
}
}
m.Echo(m.Cap(arg[1]))
return
}},
"let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[2] {
case "=":
m.Cap(arg[1], arg[3])
m.Log("stack", "let %v = %v", arg[1], arg[3])
case "<-":
m.Cap(arg[1], m.Cap("last_msg"))
}
m.Echo(m.Cap(arg[1]))
return
}},
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
stack := m.Optionv("bio.stack").(*kit.Stack) stack := m.Optionv("bio.stack").(*kit.Stack)
p := stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos")) p := stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos"))
@ -965,77 +964,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
} }
return return
}}, }},
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Peek()
p.Run = !p.Done && !p.Run && (len(arg) == 1 || kit.Right(arg[2]))
m.Log("stack", "set: run = %v", p.Run)
if p.Run {
p.Done = true
}
return
}},
"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Pop()
m.Log("stack", "pop: %v", p.String("/"))
switch p.Key {
case "for":
if p.Run {
m.Appendi("bio.pos0", p.Pos)
}
case "fun":
end := m.Optioni("stack.pos")
self := p.Data.(*ctx.Command)
help := []string{}
for i, v := range m.Optionv("input").([]interface{}) {
if p.Pos < i && i < end {
val := v.(map[string]interface{})
help = append(help, val["line"].(string))
}
}
self.Help = help
}
return
}},
"fun": &ctx.Command{Name: "fun", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Push(arg[0], false, m.Optioni("stack.pos"))
m.Log("stack", "push %v", p.String("\\"))
self := &ctx.Command{Name: strings.Join(arg[1:], " "), Help: []string{"pwd", "ls"}}
self.Hand = func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
stack := &kit.Stack{}
stack.Push("fun", true, 0)
m.Optionv("bio.stack", stack)
help := self.Help.([]string)
// 解析数据
for i := 0; i < len(help); i++ {
line := help[i]
m.Optioni("stack.pos", i)
// 执行语句
msg := m.Cmd("yac.parse", line+"\n")
// 跳转语句
if msg.Appends("bio.pos0") {
i = int(msg.Appendi("bio.pos0")) - 1
msg.Append("bio.pos0", "")
}
// 结束脚本
if msg.Appends("bio.end") {
m.Copy(msg, "append")
m.Copy(msg, "result")
msg.Appends("bio.end", "")
break
}
}
return
}
m.Target().Commands[arg[1]] = self
p.Data = self
return
}},
"for": &ctx.Command{Name: "for [[express ;] condition]|[index message meta value]", "for": &ctx.Command{Name: "for [[express ;] condition]|[index message meta value]",
Help: "循环语句, express: 每次循环运行的表达式, condition: 循环条件, index: 索引消息, message: 消息编号, meta: value: ", Help: "循环语句, express: 每次循环运行的表达式, condition: 循环条件, index: 索引消息, message: 消息编号, meta: value: ",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
@ -1100,6 +1028,77 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
*/ */
return return
}}, }},
"fun": &ctx.Command{Name: "fun", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Push(arg[0], false, m.Optioni("stack.pos"))
m.Log("stack", "push %v", p.String("\\"))
self := &ctx.Command{Name: strings.Join(arg[1:], " "), Help: []string{"pwd", "ls"}}
self.Hand = func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
stack := &kit.Stack{}
stack.Push("fun", true, 0)
m.Optionv("bio.stack", stack)
help := self.Help.([]string)
// 解析数据
for i := 0; i < len(help); i++ {
line := help[i]
m.Optioni("stack.pos", i)
// 执行语句
msg := m.Cmd("yac.parse", line+"\n")
// 跳转语句
if msg.Appends("bio.pos0") {
i = int(msg.Appendi("bio.pos0")) - 1
msg.Append("bio.pos0", "")
}
// 结束脚本
if msg.Appends("bio.end") {
m.Copy(msg, "append")
m.Copy(msg, "result")
msg.Appends("bio.end", "")
break
}
}
return
}
m.Target().Commands[arg[1]] = self
p.Data = self
return
}},
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Peek()
p.Run = !p.Done && !p.Run && (len(arg) == 1 || kit.Right(arg[2]))
m.Log("stack", "set: run = %v", p.Run)
if p.Run {
p.Done = true
}
return
}},
"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
p := m.Optionv("bio.stack").(*kit.Stack).Pop()
m.Log("stack", "pop: %v", p.String("/"))
switch p.Key {
case "for":
if p.Run {
m.Appendi("bio.pos0", p.Pos)
}
case "fun":
end := m.Optioni("stack.pos")
self := p.Data.(*ctx.Command)
help := []string{}
for i, v := range m.Optionv("input").([]interface{}) {
if p.Pos < i && i < end {
val := v.(map[string]interface{})
help = append(help, val["line"].(string))
}
}
self.Help = help
}
return
}},
"label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { "label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) { if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {