143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
// expander-context.go
|
|
package text
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"portale-stac.it/packages/golang"
|
|
)
|
|
|
|
const varIntro = '$'
|
|
|
|
type ExpanderFunc func(ctx ExpanderContext, varValue string, args []string) (result string, err error)
|
|
|
|
type ExpanderFuncBlock struct {
|
|
name string
|
|
expFunc ExpanderFunc
|
|
minArgs int
|
|
maxArgs int
|
|
description string
|
|
}
|
|
|
|
func (self *ExpanderFuncBlock) CheckNumArgs(n int) (ok bool) {
|
|
ok = (self.minArgs < 0 || n >= self.minArgs) && (self.maxArgs < 0 || n <= self.maxArgs)
|
|
return
|
|
}
|
|
|
|
func (self *ExpanderFuncBlock) synopsys(sb *strings.Builder) {
|
|
if self.minArgs < 0 && self.maxArgs < 0 {
|
|
sb.WriteString("[...]")
|
|
} else {
|
|
var i int
|
|
for i = 0; i < self.minArgs; i++ {
|
|
if i > 0 {
|
|
sb.WriteByte(' ')
|
|
}
|
|
sb.WriteString("arg")
|
|
sb.WriteString(strconv.Itoa(i + 1))
|
|
}
|
|
if self.maxArgs < 0 {
|
|
sb.WriteString("...")
|
|
} else if i < self.maxArgs {
|
|
for j := i; j < self.maxArgs; j++ {
|
|
if j > 0 {
|
|
sb.WriteByte(' ')
|
|
}
|
|
sb.WriteString("[arg")
|
|
sb.WriteString(strconv.Itoa(j + 1))
|
|
}
|
|
for j := i; j < self.maxArgs; j++ {
|
|
sb.WriteByte(']')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (self *ExpanderFuncBlock) String() string {
|
|
var sb strings.Builder
|
|
sb.WriteString(self.name)
|
|
sb.WriteByte(' ')
|
|
self.synopsys(&sb)
|
|
if len(self.description) > 0 {
|
|
sb.WriteString(" -- ")
|
|
if len(self.description) > 80 {
|
|
sb.WriteString(self.description[0:80])
|
|
sb.WriteString("...")
|
|
} else {
|
|
sb.WriteString(self.description)
|
|
}
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
type ExpanderContext interface {
|
|
VariableHandler
|
|
GetFunc(name string) (f ExpanderFunc, err error)
|
|
AddFunc(name string, f ExpanderFunc, minArgs, maxArgs int, description string)
|
|
GetVar(name string) (value string, exists bool)
|
|
SetVar(name string, value string) (repeatedValue string)
|
|
}
|
|
|
|
type BaseExpander struct {
|
|
functions map[string]*ExpanderFuncBlock
|
|
}
|
|
|
|
func (self *BaseExpander) GetVar(name string) (value string, exists bool) {
|
|
return
|
|
}
|
|
|
|
func (self *BaseExpander) SetVar(name string, value string) (repeatedValue string) {
|
|
return value
|
|
}
|
|
|
|
func NewExpander() *BaseExpander {
|
|
return &BaseExpander{
|
|
functions: make(map[string]*ExpanderFuncBlock),
|
|
}
|
|
}
|
|
|
|
func (self *BaseExpander) Init() {
|
|
if self.functions == nil {
|
|
self.functions = make(map[string]*ExpanderFuncBlock)
|
|
}
|
|
}
|
|
|
|
func (self *BaseExpander) GetFunc(name string) (f ExpanderFunc, err error) {
|
|
var ok bool
|
|
var info *ExpanderFuncBlock
|
|
if info, ok = self.functions[name]; !ok {
|
|
err = fmt.Errorf("unknown function %q", name)
|
|
} else {
|
|
f = info.expFunc
|
|
}
|
|
return
|
|
}
|
|
|
|
func (self *BaseExpander) AddFunc(name string, f ExpanderFunc, minArgs, maxArgs int, description string) {
|
|
self.functions[name] = &ExpanderFuncBlock{
|
|
name: name,
|
|
expFunc: f,
|
|
minArgs: minArgs,
|
|
maxArgs: maxArgs,
|
|
description: description,
|
|
}
|
|
}
|
|
|
|
func (self *BaseExpander) Handle(varSpec string, flags ScannerFlag) (value string, err error) {
|
|
err = errors.New("maybe you did somwthing wrong")
|
|
return
|
|
}
|
|
|
|
func (self *BaseExpander) IterateFunc(op func(funcInfo *ExpanderFuncBlock) (err error)) (err error) {
|
|
if op != nil {
|
|
err = golang.IterateSortedMap(self.functions, func(key string, info *ExpanderFuncBlock) error {
|
|
return op(info)
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|