1
0
forked from x/icebergs

add lex.matrix

This commit is contained in:
shaoying 2021-06-05 17:57:05 +08:00
parent 44fdfc3ce1
commit 922172e7fd
24 changed files with 579 additions and 134 deletions

View File

@ -104,18 +104,6 @@ func init() {
},
Commands: map[string]*ice.Command{
ROLE: {Name: "role role auto create", Help: "角色", Action: map[string]*ice.Action{
BLACK: {Name: "black role chain...", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
_role_black(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
}},
WHITE: {Name: "white role chain...", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
_role_white(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
}},
RIGHT: {Name: "right role chain...", Help: "查看权限", Hand: func(m *ice.Message, arg ...string) {
if _role_right(m, arg[0], kit.Split(strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), ".")...) {
m.Echo(ice.OK)
}
}},
mdb.CREATE: {Name: "create role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) {
list := value[m.Option(kit.MDB_ZONE)].(map[string]interface{})
@ -130,6 +118,18 @@ func init() {
delete(list, m.Option(kit.MDB_KEY))
})
}},
BLACK: {Name: "black role chain...", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
_role_black(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
}},
WHITE: {Name: "white role chain...", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
_role_white(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
}},
RIGHT: {Name: "right role chain...", Help: "查看权限", Hand: func(m *ice.Message, arg ...string) {
if _role_right(m, arg[0], kit.Split(strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), ".")...) {
m.Echo(ice.OK)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 { // 角色列表
_role_list(m, kit.Select("", arg, 0))

View File

@ -41,6 +41,9 @@ func SessCheck(m *ice.Message, sessid string) {
_sess_check(m, sessid)
}
func SessCreate(m *ice.Message, username string) string {
if username == "" {
return ""
}
return m.Option(ice.MSG_SESSID, _sess_create(m, username))
}
func SessIsCli(m *ice.Message) bool {
@ -68,23 +71,21 @@ func init() {
Commands: map[string]*ice.Command{
SESS: {Name: "sess hash auto prunes", Help: "会话", Action: map[string]*ice.Action{
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.FIELDS, "time,username,userrole,ip,ua")
m.Option(mdb.FIELDS, "time,hash,username,userrole,ip,ua")
m.Cmdy(mdb.DELETE, SESS, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
list := []string{}
m.Richs(SESS, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Option(mdb.FIELDS, "time,hash,username,userrole,ip,ua")
m.Cmd(mdb.PRUNES, SESS, "", mdb.HASH, func(key string, value map[string]interface{}) bool {
if value = kit.GetMeta(value); kit.Time(kit.Format(value[kit.MDB_TIME])) < kit.Time(m.Option("before")) {
list = append(list, key)
m.Push(key, value, kit.Split(m.Option(mdb.FIELDS)))
return true
}
return false
})
m.Option(mdb.FIELDS, "time,username,userrole,ip,ua")
for _, v := range list {
m.Cmdy(mdb.DELETE, SESS, "", mdb.HASH, kit.MDB_HASH, v)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Fields(len(arg) == 0, "time,hash,username,userrole")
m.Fields(len(arg) == 0, "time,hash,username,userrole,ip")
m.Cmdy(mdb.SELECT, SESS, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction(mdb.REMOVE)
}},

View File

@ -69,7 +69,7 @@ func init() {
m.Cmd(mdb.INSERT, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME),
SECRET, m.Option(SECRET), PERIOD, m.Option(PERIOD), NUMBER, m.Option(NUMBER),
)
m.ProcessRefresh("1ms")
m.ProcessRefresh("30ms")
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME))

View File

@ -11,6 +11,60 @@ import (
kit "github.com/shylinux/toolkits"
)
func _cli_init(m *ice.Message) {
// 启动配置
for _, k := range []string{CTX_SELF, CTX_DEV, CTX_SHY, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} {
m.Conf(RUNTIME, kit.Keys(CONF, k), os.Getenv(k))
}
// 主机信息
m.Conf(RUNTIME, kit.Keys(HOST, "GOARCH"), runtime.GOARCH)
m.Conf(RUNTIME, kit.Keys(HOST, "GOOS"), runtime.GOOS)
m.Conf(RUNTIME, kit.Keys(HOST, "pid"), os.Getpid())
// 启动信息
if name, e := os.Hostname(); e == nil {
m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Select(name, os.Getenv("HOSTNAME")))
}
if name, e := os.Getwd(); e == nil {
name = path.Base(kit.Select(name, os.Getenv("PWD")))
ls := strings.Split(name, "/")
name = ls[len(ls)-1]
ls = strings.Split(name, "\\")
name = ls[len(ls)-1]
m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), name)
}
if m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(os.Getenv(USER), os.Getenv(CTX_USER))) == "" {
if user, e := user.Current(); e == nil && user.Name != "" {
m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(user.Name, os.Getenv(CTX_USER)))
}
}
ice.Info.HostName = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME))
ice.Info.PathName = m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))
ice.Info.UserName = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME))
ice.Info.CtxShare = m.Conf(RUNTIME, kit.Keys(CONF, CTX_SHARE))
ice.Info.CtxRiver = m.Conf(RUNTIME, kit.Keys(CONF, CTX_RIVER))
// 启动次数
count := kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, kit.MDB_COUNT))) + 1
m.Conf(RUNTIME, kit.Keys(BOOT, kit.MDB_COUNT), count)
// 节点信息
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TIME), m.Time())
NodeInfo(m, "worker", m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME)))
m.Info("runtime %v", kit.Formats(m.Confv(RUNTIME)))
n := kit.Int(kit.Select("1", m.Conf(RUNTIME, kit.Keys(HOST, "GOMAXPROCS"))))
m.Logs(HOST, "GOMAXPROCS", n)
runtime.GOMAXPROCS(n)
// 版本信息
kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Build)), func(key string, value interface{}) {
m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(key)), value)
})
}
func NodeInfo(m *ice.Message, kind, name string) {
name = strings.ReplaceAll(name, ".", "_")
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TYPE), kind)
@ -46,58 +100,7 @@ var Index = &ice.Context{Name: CLI, Help: "命令模块",
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
// 启动配置
for _, k := range []string{CTX_SELF, CTX_DEV, CTX_SHY, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} {
m.Conf(RUNTIME, kit.Keys(CONF, k), os.Getenv(k))
}
// 主机信息
m.Conf(RUNTIME, kit.Keys(HOST, "GOARCH"), runtime.GOARCH)
m.Conf(RUNTIME, kit.Keys(HOST, "GOOS"), runtime.GOOS)
m.Conf(RUNTIME, kit.Keys(HOST, "pid"), os.Getpid())
// 启动信息
if name, e := os.Hostname(); e == nil {
m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Select(name, os.Getenv("HOSTNAME")))
}
if name, e := os.Getwd(); e == nil {
name = path.Base(kit.Select(name, os.Getenv("PWD")))
ls := strings.Split(name, "/")
name = ls[len(ls)-1]
ls = strings.Split(name, "\\")
name = ls[len(ls)-1]
m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), name)
}
if m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(os.Getenv(USER), os.Getenv(CTX_USER))) == "" {
if user, e := user.Current(); e == nil && user.Name != "" {
m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(user.Name, os.Getenv(CTX_USER)))
}
}
ice.Info.HostName = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME))
ice.Info.PathName = m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))
ice.Info.UserName = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME))
ice.Info.CtxShare = m.Conf(RUNTIME, kit.Keys(CONF, CTX_SHARE))
ice.Info.CtxRiver = m.Conf(RUNTIME, kit.Keys(CONF, CTX_RIVER))
// 启动次数
count := kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, kit.MDB_COUNT))) + 1
m.Conf(RUNTIME, kit.Keys(BOOT, kit.MDB_COUNT), count)
// 节点信息
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TIME), m.Time())
NodeInfo(m, "worker", m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME)))
m.Info("runtime %v", kit.Formats(m.Confv(RUNTIME)))
n := kit.Int(kit.Select("1", m.Conf(RUNTIME, kit.Keys(HOST, "GOMAXPROCS"))))
m.Logs(HOST, "GOMAXPROCS", n)
runtime.GOMAXPROCS(n)
// 版本信息
kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Build)), func(key string, value interface{}) {
m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(key)), value)
})
_cli_init(m)
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save()

View File

@ -86,18 +86,9 @@ func init() {
DAEMON: {Name: DAEMON, Help: "守护进程", Value: kit.Data(kit.MDB_PATH, path.Join(ice.USR_LOCAL, DAEMON))},
},
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
list := []string{}
m.Richs(DAEMON, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if value = kit.GetMeta(value); kit.Value(value, mdb.CACHE_CLEAR_ON_EXIT) == ice.TRUE {
list = append(list, key)
}
})
for _, k := range list {
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, k), "")
}
m.Cmd(mdb.PRUNES, DAEMON, "", mdb.HASH, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
}},
DAEMON: {Name: "daemon hash auto start prunes", Help: "守护进程", Action: map[string]*ice.Action{
@ -107,10 +98,9 @@ func init() {
m.Cmdy(DAEMON, START)
}},
START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Option(CMD_TYPE, DAEMON)
m.Option(CMD_DIR, m.Option(DIR))
m.Option(CMD_ENV, kit.Split(m.Option(ENV), " ="))
m.Cmdy(SYSTEM, kit.Split(m.Option(CMD)))
m.Cmdy(DAEMON, kit.Split(m.Option(CMD)))
}},
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir,env")
@ -130,8 +120,7 @@ func init() {
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { // 进程列表
m.Fields(len(arg) == 0, "time,hash,status,pid,cmd,dir,env")
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH)
m.Table(func(index int, value map[string]string, head []string) {
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH).Table(func(index int, value map[string]string, head []string) {
switch value[kit.MDB_STATUS] {
case START:
m.PushButton(RESTART, STOP)

View File

@ -7,11 +7,10 @@ import (
"strconv"
"strings"
"github.com/skip2/go-qrcode"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
kit "github.com/shylinux/toolkits"
"github.com/skip2/go-qrcode"
)
var _trans_web = map[string]color.Color{
@ -126,7 +125,7 @@ func init() {
m.Option(FG, kit.Select(BLUE, arg, 1))
if aaa.SessIsCli(m) {
_qrcode_cli(m, kit.Select(m.Conf("web.share", kit.Keym(kit.MDB_DOMAIN)), arg))
_qrcode_cli(m, kit.Select(m.Conf("web.share", kit.Keym(kit.MDB_DOMAIN)), arg, 0))
} else {
_qrcode_web(m, kit.Select(m.Option(ice.MSG_USERWEB), arg, 0))
}

View File

@ -37,7 +37,7 @@ func init() {
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { // 事件列表
m.Option(mdb.FIELDS, "time,event,count")
m.Fields(len(arg) == 0, "time,event,count")
m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH)
m.PushAction(ACTION, mdb.REMOVE)
return

View File

@ -48,6 +48,7 @@ const (
BUILD = "build"
SPAWN = "spawn"
START = "start"
ERROR = "error"
STOP = "stop"
STATUS = "status"

View File

@ -3,5 +3,4 @@ chapter "gdb"
field "协程池" routine
field "信号量" signal
field "事件流" event
field "定时器" timer

View File

@ -1,9 +1,10 @@
package gdb
import (
"strings"
"path"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
)
@ -34,6 +35,7 @@ func init() {
}},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.FIELDS, "time,hash,status,fileline")
m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, ERROR)
m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, STOP)
}},
@ -43,15 +45,9 @@ func init() {
m.Cmdy(INNER, arg[1:])
default:
ls := kit.Split(m.Option("fileline"), ":")
switch kit.Split(ls[0], "/")[0] {
case "usr":
ls[0] = strings.TrimPrefix(ls[0], "usr/icebergs/")
case "icebergs":
ls[0] = strings.TrimPrefix(ls[0], "icebergs/")
}
m.ShowPlugin("", INNER, kit.SSH_RUN)
m.Push("args", kit.Format([]string{"usr/icebergs/", ls[0], ls[1]}))
m.ProcessField(INNER, kit.SSH_RUN)
m.Option(kit.SSH_ARG, kit.Format([]string{path.Dir(ls[0]), path.Base(ls[0]), ls[1]}))
m.Cmdy(ctx.COMMAND, INNER)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -25,7 +25,7 @@ func _timer_action(m *ice.Message, arg ...string) {
m.Logs(TIMER, kit.MDB_KEY, key, ORDER, order)
msg := m.Cmd(value[kit.SSH_CMD])
m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict("res", msg.Result()))
m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.SSH_RES, msg.Result()))
if value[ORDER] = kit.Format(order - 1); order > 1 {
value[NEXT] = msg.Time(value[INTERVAL])
}

View File

@ -1,15 +1,460 @@
package lex
import (
"sort"
"strconv"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
)
type Seed struct {
page int
hash int
word string
}
type Point struct {
s int
c byte
}
type State struct {
star bool
next int
hash int
}
type Matrix struct {
nlang int
ncell int
seed []*Seed
page map[string]int
hand map[int]string
hash map[string]int
word map[int]string
trans map[byte][]byte
state map[State]*State
mat []map[byte]*State
*ice.Context
nseed int
npage int
nhash int
nline int
nnode int
nreal int
}
func NewMatrix(m *ice.Message, nlang, ncell int) *Matrix {
mat := &Matrix{}
mat.nlang = nlang
mat.ncell = ncell
mat.page = map[string]int{"nil": 0}
mat.hand = map[int]string{0: "nil"}
mat.hash = map[string]int{"nil": 0}
mat.word = map[int]string{0: "nil"}
mat.trans = map[byte][]byte{}
for k, v := range map[byte]string{
't': "\t", 'n': "\n", 'b': "\t ", 's': "\t \n",
'd': "0123456789", 'x': "0123456789ABCDEFabcdef",
} {
mat.trans[k] = []byte(v)
}
mat.state = make(map[State]*State)
mat.mat = make([]map[byte]*State, nlang)
mat.nline = nlang
return mat
}
func (mat *Matrix) char(c byte) []byte {
if cs, ok := mat.trans[c]; ok {
return cs
}
return []byte{c}
}
func (mat *Matrix) index(m *ice.Message, hash string, h string) int {
which, names := mat.hash, mat.word
if hash == NPAGE {
which, names = mat.page, mat.hand
}
if x, e := strconv.Atoi(h); e == nil {
if hash == NPAGE {
m.Assert(x <= mat.npage)
} else {
mat.hash[h] = x
}
return x
}
if x, ok := which[h]; ok {
return x
}
if hash == NPAGE {
mat.npage++
which[h] = mat.npage
} else {
mat.nhash++
which[h] = mat.nhash
}
names[which[h]] = h
m.Assert(hash != NPAGE || mat.npage < mat.nlang)
return which[h]
}
func (mat *Matrix) train(m *ice.Message, page int, hash int, seed []byte) int {
m.Debug("%s %s page: %v hash: %v seed: %v", "train", "lex", page, hash, string(seed))
ss := []int{page}
cn := make([]bool, mat.ncell)
cc := make([]byte, 0, mat.ncell)
sn := make([]bool, mat.nline)
points := []*Point{}
for p := 0; p < len(seed); p++ {
switch seed[p] {
case '[':
set := true
if p++; seed[p] == '^' {
set, p = false, p+1
}
for ; seed[p] != ']'; p++ {
if seed[p] == '\\' {
p++
for _, c := range mat.char(seed[p]) {
cn[c] = true
}
continue
}
if seed[p+1] == '-' {
begin, end := seed[p], seed[p+2]
if begin > end {
begin, end = end, begin
}
for c := begin; c <= end; c++ {
cn[c] = true
}
p += 2
continue
}
cn[seed[p]] = true
}
for c := 0; c < len(cn); c++ {
if (set && cn[c]) || (!set && !cn[c]) {
cc = append(cc, byte(c))
}
cn[c] = false
}
case '.':
for c := 0; c < len(cn); c++ {
cc = append(cc, byte(c))
}
case '\\':
p++
for _, c := range mat.char(seed[p]) {
cc = append(cc, c)
}
default:
cc = append(cc, seed[p])
}
m.Debug("page: \033[31m%d %v\033[0m", len(ss), ss)
m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc)
flag := '\000'
if p+1 < len(seed) {
switch flag = rune(seed[p+1]); flag {
case '?', '+', '*':
p++
}
}
for _, s := range ss {
for _, c := range cc {
state := &State{}
if mat.mat[s][c] != nil {
*state = *mat.mat[s][c]
} else {
mat.nnode++
}
m.Debug("GET(%d,%d): %v", s, c, state)
switch flag {
case '+':
state.star = true
case '*':
state.star = true
sn[s] = true
case '?':
sn[s] = true
}
if state.next == 0 {
mat.mat = append(mat.mat, make(map[byte]*State))
sn = append(sn, false)
state.next = mat.nline
mat.nline++
}
sn[state.next] = true
mat.mat[s][c] = state
points = append(points, &Point{s, c})
m.Debug("SET(%d,%d): %v(%d,%d)", s, c, state, mat.nnode, mat.nreal)
}
}
cc, ss = cc[:0], ss[:0]
for s, b := range sn {
if sn[s] = false; b && s > 0 {
ss = append(ss, s)
}
}
}
for _, s := range ss {
if s < mat.nlang || s >= len(mat.mat) {
continue
}
if len(mat.mat[s]) == 0 {
last := mat.nline - 1
mat.mat, mat.nline = mat.mat[:s], s
m.Debug("DEL: %d-%d", last, mat.nline)
}
}
for _, s := range ss {
for _, p := range points {
state := &State{}
*state = *mat.mat[p.s][p.c]
if state.next == s {
m.Debug("GET(%d, %d): %v", p.s, p.c, state)
if state.hash = hash; state.next >= len(mat.mat) {
state.next = 0
}
mat.mat[p.s][p.c] = state
m.Debug("SET(%d, %d): %v", p.s, p.c, state)
}
if x, ok := mat.state[*state]; !ok {
mat.state[*state] = mat.mat[p.s][p.c]
mat.nreal++
} else {
mat.mat[p.s][p.c] = x
}
}
}
m.Debug("%s %s npage: %v nhash: %v nseed: %v", "train", "lex", mat.npage, mat.nhash, len(mat.seed))
return hash
}
func (mat *Matrix) parse(m *ice.Message, page int, line []byte) (hash int, rest []byte, word []byte) {
m.Debug("%s %s page: %v line: %v", "parse", "lex", page, line)
pos := 0
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
c := line[pos]
if c == '\\' && pos < len(line)-1 { //跳过转义
pos++
c = mat.char(line[pos])[0]
}
if c > 127 { //跳过中文
word = append(word, c)
continue
}
state := mat.mat[s][c]
if state == nil {
s, star, pos = star, 0, pos-1
continue
}
m.Debug("GET (%d,%d): %v", s, c, state)
word = append(word, c)
if state.star {
star = s
} else if x, ok := mat.mat[star][c]; !ok || !x.star {
star = 0
}
if s, hash = state.next, state.hash; s == 0 {
s, star = star, 0
}
}
if pos == len(line) {
// hash, pos, word = -1, 0, word[:0]
} else if hash == 0 {
pos, word = 0, word[:0]
}
rest = line[pos:]
m.Debug("%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest)
return
}
func (mat *Matrix) show(m *ice.Message, page string) {
rows := map[int]bool{}
cols := map[int]bool{}
nrow := []int{mat.page[page]}
for i := 0; i < len(nrow); i++ {
line := nrow[i]
rows[line] = true
for i := 1; i < mat.ncell; i++ {
if node := mat.mat[line][byte(i)]; node != nil {
if cols[i] = true; node.next != 0 {
nrow = append(nrow, node.next)
}
}
}
}
nrow = nrow[:0]
ncol := []int{}
for k := range rows {
nrow = append(nrow, k)
}
for k := range cols {
ncol = append(ncol, k)
}
sort.Ints(nrow)
sort.Ints(ncol)
for _, i := range nrow {
m.Push("0", kit.Select(kit.Format(i), mat.hand[i]))
for _, j := range ncol {
node := mat.mat[i][byte(j)]
if node != nil {
m.Push(kit.Format("%c", j), kit.Format("%v", node.next))
} else {
m.Push(kit.Format("%c", j), "")
}
}
}
}
const (
NLANG = "nlang"
NCELL = "ncell"
NSEED = "nseed"
NPAGE = "npage"
NHASH = "nhash"
)
const (
TRAIN = "train"
PARSE = "parse"
)
const MATRIX = "matrix"
const LEX = "lex"
var Index = &ice.Context{Name: LEX, Help: "词法模块",
Configs: map[string]*ice.Config{
MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo("hello %s world", c.Name)
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Load()
m.Richs(m.Prefix(MATRIX), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
value = kit.GetMeta(value)
mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("256", value[NCELL])))
m.Grows(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
page := mat.index(m, NPAGE, kit.Format(value[NPAGE]))
hash := mat.index(m, NHASH, kit.Format(value[NHASH]))
if mat.mat[page] == nil {
mat.mat[page] = map[byte]*State{}
}
mat.seed = append(mat.seed, &Seed{page, hash, kit.Format(value[kit.MDB_TEXT])})
mat.train(m, page, hash, []byte(kit.Format(value[kit.MDB_TEXT])))
})
value[MATRIX] = mat
})
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Save()
}},
MATRIX: {Name: "matrix hash npage text auto", Help: "魔方矩阵", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create nlang=32 ncell=256", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("256", m.Option(NCELL))))
m.Rich(m.Prefix(MATRIX), "", kit.Data(kit.MDB_TIME, m.Time(), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell))
}},
mdb.INSERT: {Name: "insert npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix)
page := mat.index(m, NPAGE, m.Option(NPAGE))
hash := mat.index(m, NHASH, m.Option(NHASH))
if mat.mat[page] == nil {
mat.mat[page] = map[byte]*State{}
}
mat.seed = append(mat.seed, &Seed{page, hash, m.Option(kit.MDB_TEXT)})
m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict(
kit.MDB_TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), kit.MDB_TEXT, m.Option(kit.MDB_TEXT),
))
mat.train(m, page, hash, []byte(m.Option(kit.MDB_TEXT)))
value[NSEED] = len(mat.seed)
value[NPAGE] = len(mat.page) - 1
value[NHASH] = len(mat.hash) - 1
})
}},
mdb.REMOVE: {Name: "create", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, m.Prefix(MATRIX), "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表
m.Fields(len(arg) == 0, "time,hash,npage,nhash")
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH)
m.PushAction(mdb.INSERT, mdb.REMOVE)
return
}
if m.Action(mdb.INSERT); len(arg) == 1 { // 词法列表
m.Fields(len(arg) == 1, "time,npage,nhash,text")
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST)
return
}
m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) {
value = kit.GetMeta(value)
mat, _ := value[MATRIX].(*Matrix)
m.Debug("what %#v", mat)
if len(arg) == 2 { // 词法矩阵
mat.show(m, arg[1])
return
}
hash, rest, word := mat.parse(m, mat.index(m, NPAGE, arg[1]), []byte(arg[2]))
m.Push("time", m.Time())
m.Push("hash", mat.word[hash])
m.Push("word", string(word))
m.Push("rest", string(rest))
})
}},
},
}

View File

@ -21,7 +21,7 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
return &Frame{}
}
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
f.p = make(chan *Log, 4096)
f.p = make(chan *Log, ice.MOD_BUFS)
ice.Log = func(msg *ice.Message, p, l, s string) {
f.p <- &Log{m: msg, p: p, l: l, s: s}
}
@ -40,17 +40,17 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
bio := m.Confv(FILE, kit.Keys(file, FILE)).(*bufio.Writer)
bio.WriteString(l.p)
bio.WriteString(" ")
bio.WriteString(ice.MOD_SP)
if p, ok := view[PREFIX].(string); ok {
bio.WriteString(p)
}
bio.WriteString(l.l)
bio.WriteString(" ")
bio.WriteString(ice.MOD_SP)
bio.WriteString(l.s)
if p, ok := view[SUFFIX].(string); ok {
bio.WriteString(p)
}
bio.WriteString("\n")
bio.WriteString(ice.MOD_NL)
bio.Flush()
}
}

View File

@ -114,10 +114,17 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{})
}
for i := 0; i < len(arg)-1; i += 2 {
if val[arg[i]] != arg[i+1] {
switch cb := m.Optionv(kit.Keycb(PRUNES)).(type) {
case func(string, map[string]interface{}) bool:
if !cb(key, val) {
return
}
default:
for i := 0; i < len(arg)-1; i += 2 {
if val[arg[i]] != arg[i+1] {
return
}
}
}
m.Push(key, val, fields)
})
@ -170,9 +177,6 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
}
}
})
// if m.Option(FIELDS) != DETAIL {
// m.SortIntR(kit.MDB_ID)
// }
}
func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
m.Grows(prefix, chain, field, value, func(index int, val map[string]interface{}) {

View File

@ -66,9 +66,9 @@ func init() {
m.ProcessRewrite("offend", offend)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0))
m.Fields(true, kit.Select("time,hash,count,name,file", "time,id,file,text", len(arg) > 1 && arg[1] != ""))
m.Option(mdb.CACHE_OFFEND, kit.Select("0", arg, 3))
m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2))
m.Option("cache.offend", kit.Select("0", arg, 3))
if m.Cmdy(mdb.SELECT, TAIL, "", mdb.ZONE, arg); len(arg) == 0 {
m.PushAction(mdb.REMOVE)

View File

@ -57,7 +57,7 @@ func init() {
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,hash,file,from")
m.Fields(len(arg) == 0, "time,hash,file,from")
m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH)
m.PushAction(mdb.REVERT, mdb.REMOVE)
return

View File

@ -12,6 +12,7 @@ import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
@ -28,8 +29,8 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) string {
res := msg.Result()
// 输出结果
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
fmt.Fprint(msg.O, "\n")
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.MOD_NL) {
fmt.Fprint(msg.O, ice.MOD_NL)
}
return res
@ -41,8 +42,8 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) string {
}
// 输出结果
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
fmt.Fprint(msg.O, "\n")
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.MOD_NL) {
fmt.Fprint(msg.O, ice.MOD_NL)
}
return res
}
@ -167,7 +168,7 @@ func (f *Frame) option(m *ice.Message, ls []string) []string {
}
func (f *Frame) change(m *ice.Message, ls []string) []string {
if len(ls) == 1 && ls[0] == "~" { // 模块列表
ls = []string{"context"}
ls = []string{ctx.CONTEXT}
} else if len(ls) > 0 && strings.HasPrefix(ls[0], "~") { // 切换模块
target := ls[0][1:]
@ -282,11 +283,9 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
return f
}
func (f *Frame) close() {
fmt.Printf("what %v\n", 123)
if stdin, ok := f.stdin.(io.Closer); ok {
stdin.Close()
f.stdin = nil
fmt.Printf("what %v\n", 123)
}
}
@ -406,18 +405,15 @@ func init() {
f := m.Target().Server().(*Frame)
m.Search(arg[0]+".", func(p *ice.Context, s *ice.Context, key string) { f.target = s })
f.prompt(m)
m.Echo(arg[0])
}},
PROMPT: {Name: "prompt arg 执行:button", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
f.ps1 = arg
f.prompt(m)
m.Echo(arg[0])
}},
PRINTF: {Name: "printf 执行:button text:textarea", Help: "输出显示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)
f.printf(m, arg[0])
m.Echo(arg[0])
}},
SCREEN: {Name: "screen 执行:button text:textarea", Help: "输出命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
f := m.Target().Server().(*Frame)

View File

@ -75,7 +75,7 @@ func init() {
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok {
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD)))
w.Write([]byte(m.Option(CMD) + "\n"))
w.Write([]byte(m.Option(CMD) + ice.MOD_NL))
}
})
m.ProcessRefresh("300ms")

View File

@ -73,7 +73,7 @@ func init() {
m.Assert(e)
cb(c)
case func(net.Conn, []byte, error):
b := make([]byte, 4096)
b := make([]byte, ice.MOD_BUFS)
for {
n, e := c.Read(b)
if cb(c, b[:n], e); e != nil {

View File

@ -77,7 +77,7 @@ func init() {
break
}
b := make([]byte, 4096)
b := make([]byte, ice.MOD_BUFS)
if n, e := c.Read(b); e == nil {
m.Info("nonce", string(b[:n]))
c.Write(b[:n])

View File

@ -229,7 +229,7 @@ func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SPACE: {Name: SPACE, Help: "空间站", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME,
"redial", kit.Dict("a", 3000, "b", 1000, "c", 1000, "r", 4096, "w", 4096),
"redial", kit.Dict("a", 3000, "b", 1000, "c", 1000, "r", ice.MOD_BUFS, "w", ice.MOD_BUFS),
"timeout", kit.Dict("c", "180s"),
)},
},

View File

@ -1,7 +1,7 @@
package yac
import (
"github.com/shylinux/icebergs"
ice "github.com/shylinux/icebergs"
)
const YAC = "yac"

View File

@ -1,6 +1,8 @@
package ice
const ( // MOD
MOD_SP = " "
MOD_NL = "\n"
MOD_DIR = 0750
MOD_FILE = 0640

10
misc.go
View File

@ -361,3 +361,13 @@ func (m *Message) OptionLoad(file string) *Message {
}
return m
}
func (m *Message) Confi(key string, sub string) int {
return kit.Int(m.Conf(key, sub))
}
func (m *Message) Capi(key string, val ...interface{}) int {
if len(val) > 0 {
m.Cap(key, kit.Int(m.Cap(key))+kit.Int(val[0]))
}
return kit.Int(m.Cap(key))
}