mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-03 15:27:45 +00:00
Update to tengo v2 (#976)
This commit is contained in:
34
vendor/github.com/d5/tengo/v2/stdlib/base64.go
generated
vendored
Normal file
34
vendor/github.com/d5/tengo/v2/stdlib/base64.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
var base64Module = map[string]tengo.Object{
|
||||
"encode": &tengo.UserFunction{
|
||||
Value: FuncAYRS(base64.StdEncoding.EncodeToString),
|
||||
},
|
||||
"decode": &tengo.UserFunction{
|
||||
Value: FuncASRYE(base64.StdEncoding.DecodeString),
|
||||
},
|
||||
"raw_encode": &tengo.UserFunction{
|
||||
Value: FuncAYRS(base64.RawStdEncoding.EncodeToString),
|
||||
},
|
||||
"raw_decode": &tengo.UserFunction{
|
||||
Value: FuncASRYE(base64.RawStdEncoding.DecodeString),
|
||||
},
|
||||
"url_encode": &tengo.UserFunction{
|
||||
Value: FuncAYRS(base64.URLEncoding.EncodeToString),
|
||||
},
|
||||
"url_decode": &tengo.UserFunction{
|
||||
Value: FuncASRYE(base64.URLEncoding.DecodeString),
|
||||
},
|
||||
"raw_url_encode": &tengo.UserFunction{
|
||||
Value: FuncAYRS(base64.RawURLEncoding.EncodeToString),
|
||||
},
|
||||
"raw_url_decode": &tengo.UserFunction{
|
||||
Value: FuncASRYE(base64.RawURLEncoding.DecodeString),
|
||||
},
|
||||
}
|
18
vendor/github.com/d5/tengo/v2/stdlib/builtin_modules.go
generated
vendored
Normal file
18
vendor/github.com/d5/tengo/v2/stdlib/builtin_modules.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
// BuiltinModules are builtin type standard library modules.
|
||||
var BuiltinModules = map[string]map[string]tengo.Object{
|
||||
"math": mathModule,
|
||||
"os": osModule,
|
||||
"text": textModule,
|
||||
"times": timesModule,
|
||||
"rand": randModule,
|
||||
"fmt": fmtModule,
|
||||
"json": jsonModule,
|
||||
"base64": base64Module,
|
||||
"hex": hexModule,
|
||||
}
|
12
vendor/github.com/d5/tengo/v2/stdlib/errors.go
generated
vendored
Normal file
12
vendor/github.com/d5/tengo/v2/stdlib/errors.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
func wrapError(err error) tengo.Object {
|
||||
if err == nil {
|
||||
return tengo.TrueValue
|
||||
}
|
||||
return &tengo.Error{Value: &tengo.String{Value: err.Error()}}
|
||||
}
|
101
vendor/github.com/d5/tengo/v2/stdlib/fmt.go
generated
vendored
Normal file
101
vendor/github.com/d5/tengo/v2/stdlib/fmt.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
var fmtModule = map[string]tengo.Object{
|
||||
"print": &tengo.UserFunction{Name: "print", Value: fmtPrint},
|
||||
"printf": &tengo.UserFunction{Name: "printf", Value: fmtPrintf},
|
||||
"println": &tengo.UserFunction{Name: "println", Value: fmtPrintln},
|
||||
"sprintf": &tengo.UserFunction{Name: "sprintf", Value: fmtSprintf},
|
||||
}
|
||||
|
||||
func fmtPrint(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
printArgs, err := getPrintArgs(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, _ = fmt.Print(printArgs...)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func fmtPrintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
numArgs := len(args)
|
||||
if numArgs == 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
format, ok := args[0].(*tengo.String)
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "format",
|
||||
Expected: "string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
if numArgs == 1 {
|
||||
fmt.Print(format)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
s, err := tengo.Format(format.Value, args[1:]...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Print(s)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func fmtPrintln(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
printArgs, err := getPrintArgs(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
printArgs = append(printArgs, "\n")
|
||||
_, _ = fmt.Print(printArgs...)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func fmtSprintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
numArgs := len(args)
|
||||
if numArgs == 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
format, ok := args[0].(*tengo.String)
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "format",
|
||||
Expected: "string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
if numArgs == 1 {
|
||||
// okay to return 'format' directly as String is immutable
|
||||
return format, nil
|
||||
}
|
||||
s, err := tengo.Format(format.Value, args[1:]...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tengo.String{Value: s}, nil
|
||||
}
|
||||
|
||||
func getPrintArgs(args ...tengo.Object) ([]interface{}, error) {
|
||||
var printArgs []interface{}
|
||||
l := 0
|
||||
for _, arg := range args {
|
||||
s, _ := tengo.ToString(arg)
|
||||
slen := len(s)
|
||||
// make sure length does not exceed the limit
|
||||
if l+slen > tengo.MaxStringLen {
|
||||
return nil, tengo.ErrStringLimit
|
||||
}
|
||||
l += slen
|
||||
printArgs = append(printArgs, s)
|
||||
}
|
||||
return printArgs, nil
|
||||
}
|
1049
vendor/github.com/d5/tengo/v2/stdlib/func_typedefs.go
generated
vendored
Normal file
1049
vendor/github.com/d5/tengo/v2/stdlib/func_typedefs.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
vendor/github.com/d5/tengo/v2/stdlib/hex.go
generated
vendored
Normal file
12
vendor/github.com/d5/tengo/v2/stdlib/hex.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
var hexModule = map[string]tengo.Object{
|
||||
"encode": &tengo.UserFunction{Value: FuncAYRS(hex.EncodeToString)},
|
||||
"decode": &tengo.UserFunction{Value: FuncASRYE(hex.DecodeString)},
|
||||
}
|
146
vendor/github.com/d5/tengo/v2/stdlib/json.go
generated
vendored
Normal file
146
vendor/github.com/d5/tengo/v2/stdlib/json.go
generated
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
gojson "encoding/json"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
"github.com/d5/tengo/v2/stdlib/json"
|
||||
)
|
||||
|
||||
var jsonModule = map[string]tengo.Object{
|
||||
"decode": &tengo.UserFunction{
|
||||
Name: "decode",
|
||||
Value: jsonDecode,
|
||||
},
|
||||
"encode": &tengo.UserFunction{
|
||||
Name: "encode",
|
||||
Value: jsonEncode,
|
||||
},
|
||||
"indent": &tengo.UserFunction{
|
||||
Name: "encode",
|
||||
Value: jsonIndent,
|
||||
},
|
||||
"html_escape": &tengo.UserFunction{
|
||||
Name: "html_escape",
|
||||
Value: jsonHTMLEscape,
|
||||
},
|
||||
}
|
||||
|
||||
func jsonDecode(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch o := args[0].(type) {
|
||||
case *tengo.Bytes:
|
||||
v, err := json.Decode(o.Value)
|
||||
if err != nil {
|
||||
return &tengo.Error{
|
||||
Value: &tengo.String{Value: err.Error()},
|
||||
}, nil
|
||||
}
|
||||
return v, nil
|
||||
case *tengo.String:
|
||||
v, err := json.Decode([]byte(o.Value))
|
||||
if err != nil {
|
||||
return &tengo.Error{
|
||||
Value: &tengo.String{Value: err.Error()},
|
||||
}, nil
|
||||
}
|
||||
return v, nil
|
||||
default:
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "bytes/string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func jsonEncode(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
b, err := json.Encode(args[0])
|
||||
if err != nil {
|
||||
return &tengo.Error{Value: &tengo.String{Value: err.Error()}}, nil
|
||||
}
|
||||
|
||||
return &tengo.Bytes{Value: b}, nil
|
||||
}
|
||||
|
||||
func jsonIndent(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 3 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
prefix, ok := tengo.ToString(args[1])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "prefix",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
indent, ok := tengo.ToString(args[2])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "indent",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[2].TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
switch o := args[0].(type) {
|
||||
case *tengo.Bytes:
|
||||
var dst bytes.Buffer
|
||||
err := gojson.Indent(&dst, o.Value, prefix, indent)
|
||||
if err != nil {
|
||||
return &tengo.Error{
|
||||
Value: &tengo.String{Value: err.Error()},
|
||||
}, nil
|
||||
}
|
||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
||||
case *tengo.String:
|
||||
var dst bytes.Buffer
|
||||
err := gojson.Indent(&dst, []byte(o.Value), prefix, indent)
|
||||
if err != nil {
|
||||
return &tengo.Error{
|
||||
Value: &tengo.String{Value: err.Error()},
|
||||
}, nil
|
||||
}
|
||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
||||
default:
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "bytes/string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func jsonHTMLEscape(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
switch o := args[0].(type) {
|
||||
case *tengo.Bytes:
|
||||
var dst bytes.Buffer
|
||||
gojson.HTMLEscape(&dst, o.Value)
|
||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
||||
case *tengo.String:
|
||||
var dst bytes.Buffer
|
||||
gojson.HTMLEscape(&dst, []byte(o.Value))
|
||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
||||
default:
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "bytes/string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
}
|
358
vendor/github.com/d5/tengo/v2/stdlib/json/decode.go
generated
vendored
Normal file
358
vendor/github.com/d5/tengo/v2/stdlib/json/decode.go
generated
vendored
Normal file
@ -0,0 +1,358 @@
|
||||
// A modified version of Go's JSON implementation.
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"unicode"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
// Decode parses the JSON-encoded data and returns the result object.
|
||||
func Decode(data []byte) (tengo.Object, error) {
|
||||
var d decodeState
|
||||
err := checkValid(data, &d.scan)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.init(data)
|
||||
d.scan.reset()
|
||||
d.scanWhile(scanSkipSpace)
|
||||
return d.value()
|
||||
}
|
||||
|
||||
// decodeState represents the state while decoding a JSON value.
|
||||
type decodeState struct {
|
||||
data []byte
|
||||
off int // next read offset in data
|
||||
opcode int // last read result
|
||||
scan scanner
|
||||
}
|
||||
|
||||
// readIndex returns the position of the last byte read.
|
||||
func (d *decodeState) readIndex() int {
|
||||
return d.off - 1
|
||||
}
|
||||
|
||||
const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?"
|
||||
|
||||
func (d *decodeState) init(data []byte) *decodeState {
|
||||
d.data = data
|
||||
d.off = 0
|
||||
return d
|
||||
}
|
||||
|
||||
// scanNext processes the byte at d.data[d.off].
|
||||
func (d *decodeState) scanNext() {
|
||||
if d.off < len(d.data) {
|
||||
d.opcode = d.scan.step(&d.scan, d.data[d.off])
|
||||
d.off++
|
||||
} else {
|
||||
d.opcode = d.scan.eof()
|
||||
d.off = len(d.data) + 1 // mark processed EOF with len+1
|
||||
}
|
||||
}
|
||||
|
||||
// scanWhile processes bytes in d.data[d.off:] until it
|
||||
// receives a scan code not equal to op.
|
||||
func (d *decodeState) scanWhile(op int) {
|
||||
s, data, i := &d.scan, d.data, d.off
|
||||
for i < len(data) {
|
||||
newOp := s.step(s, data[i])
|
||||
i++
|
||||
if newOp != op {
|
||||
d.opcode = newOp
|
||||
d.off = i
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
d.off = len(data) + 1 // mark processed EOF with len+1
|
||||
d.opcode = d.scan.eof()
|
||||
}
|
||||
|
||||
func (d *decodeState) value() (tengo.Object, error) {
|
||||
switch d.opcode {
|
||||
default:
|
||||
panic(phasePanicMsg)
|
||||
case scanBeginArray:
|
||||
o, err := d.array()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.scanNext()
|
||||
return o, nil
|
||||
case scanBeginObject:
|
||||
o, err := d.object()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.scanNext()
|
||||
return o, nil
|
||||
case scanBeginLiteral:
|
||||
return d.literal()
|
||||
}
|
||||
}
|
||||
|
||||
func (d *decodeState) array() (tengo.Object, error) {
|
||||
var arr []tengo.Object
|
||||
for {
|
||||
// Look ahead for ] - can only happen on first iteration.
|
||||
d.scanWhile(scanSkipSpace)
|
||||
if d.opcode == scanEndArray {
|
||||
break
|
||||
}
|
||||
o, err := d.value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arr = append(arr, o)
|
||||
|
||||
// Next token must be , or ].
|
||||
if d.opcode == scanSkipSpace {
|
||||
d.scanWhile(scanSkipSpace)
|
||||
}
|
||||
if d.opcode == scanEndArray {
|
||||
break
|
||||
}
|
||||
if d.opcode != scanArrayValue {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
}
|
||||
return &tengo.Array{Value: arr}, nil
|
||||
}
|
||||
|
||||
func (d *decodeState) object() (tengo.Object, error) {
|
||||
m := make(map[string]tengo.Object)
|
||||
for {
|
||||
// Read opening " of string key or closing }.
|
||||
d.scanWhile(scanSkipSpace)
|
||||
if d.opcode == scanEndObject {
|
||||
// closing } - can only happen on first iteration.
|
||||
break
|
||||
}
|
||||
if d.opcode != scanBeginLiteral {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
|
||||
// Read string key.
|
||||
start := d.readIndex()
|
||||
d.scanWhile(scanContinue)
|
||||
item := d.data[start:d.readIndex()]
|
||||
key, ok := unquote(item)
|
||||
if !ok {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
|
||||
// Read : before value.
|
||||
if d.opcode == scanSkipSpace {
|
||||
d.scanWhile(scanSkipSpace)
|
||||
}
|
||||
if d.opcode != scanObjectKey {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
d.scanWhile(scanSkipSpace)
|
||||
|
||||
// Read value.
|
||||
o, err := d.value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m[key] = o
|
||||
|
||||
// Next token must be , or }.
|
||||
if d.opcode == scanSkipSpace {
|
||||
d.scanWhile(scanSkipSpace)
|
||||
}
|
||||
if d.opcode == scanEndObject {
|
||||
break
|
||||
}
|
||||
if d.opcode != scanObjectValue {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
}
|
||||
return &tengo.Map{Value: m}, nil
|
||||
}
|
||||
|
||||
func (d *decodeState) literal() (tengo.Object, error) {
|
||||
// All bytes inside literal return scanContinue op code.
|
||||
start := d.readIndex()
|
||||
d.scanWhile(scanContinue)
|
||||
|
||||
item := d.data[start:d.readIndex()]
|
||||
|
||||
switch c := item[0]; c {
|
||||
case 'n': // null
|
||||
return tengo.UndefinedValue, nil
|
||||
|
||||
case 't', 'f': // true, false
|
||||
if c == 't' {
|
||||
return tengo.TrueValue, nil
|
||||
}
|
||||
return tengo.FalseValue, nil
|
||||
|
||||
case '"': // string
|
||||
s, ok := unquote(item)
|
||||
if !ok {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
return &tengo.String{Value: s}, nil
|
||||
|
||||
default: // number
|
||||
if c != '-' && (c < '0' || c > '9') {
|
||||
panic(phasePanicMsg)
|
||||
}
|
||||
n, _ := strconv.ParseFloat(string(item), 10)
|
||||
return &tengo.Float{Value: n}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
|
||||
// or it returns -1.
|
||||
func getu4(s []byte) rune {
|
||||
if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
|
||||
return -1
|
||||
}
|
||||
var r rune
|
||||
for _, c := range s[2:6] {
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
c = c - '0'
|
||||
case 'a' <= c && c <= 'f':
|
||||
c = c - 'a' + 10
|
||||
case 'A' <= c && c <= 'F':
|
||||
c = c - 'A' + 10
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
r = r*16 + rune(c)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// unquote converts a quoted JSON string literal s into an actual string t.
|
||||
// The rules are different than for Go, so cannot use strconv.Unquote.
|
||||
func unquote(s []byte) (t string, ok bool) {
|
||||
s, ok = unquoteBytes(s)
|
||||
t = string(s)
|
||||
return
|
||||
}
|
||||
|
||||
func unquoteBytes(s []byte) (t []byte, ok bool) {
|
||||
if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
|
||||
return
|
||||
}
|
||||
s = s[1 : len(s)-1]
|
||||
|
||||
// Check for unusual characters. If there are none, then no unquoting is
|
||||
// needed, so return a slice of the original bytes.
|
||||
r := 0
|
||||
for r < len(s) {
|
||||
c := s[r]
|
||||
if c == '\\' || c == '"' || c < ' ' {
|
||||
break
|
||||
}
|
||||
if c < utf8.RuneSelf {
|
||||
r++
|
||||
continue
|
||||
}
|
||||
rr, size := utf8.DecodeRune(s[r:])
|
||||
if rr == utf8.RuneError && size == 1 {
|
||||
break
|
||||
}
|
||||
r += size
|
||||
}
|
||||
if r == len(s) {
|
||||
return s, true
|
||||
}
|
||||
|
||||
b := make([]byte, len(s)+2*utf8.UTFMax)
|
||||
w := copy(b, s[0:r])
|
||||
for r < len(s) {
|
||||
// Out of room? Can only happen if s is full of
|
||||
// malformed UTF-8 and we're replacing each
|
||||
// byte with RuneError.
|
||||
if w >= len(b)-2*utf8.UTFMax {
|
||||
nb := make([]byte, (len(b)+utf8.UTFMax)*2)
|
||||
copy(nb, b[0:w])
|
||||
b = nb
|
||||
}
|
||||
switch c := s[r]; {
|
||||
case c == '\\':
|
||||
r++
|
||||
if r >= len(s) {
|
||||
return
|
||||
}
|
||||
switch s[r] {
|
||||
default:
|
||||
return
|
||||
case '"', '\\', '/', '\'':
|
||||
b[w] = s[r]
|
||||
r++
|
||||
w++
|
||||
case 'b':
|
||||
b[w] = '\b'
|
||||
r++
|
||||
w++
|
||||
case 'f':
|
||||
b[w] = '\f'
|
||||
r++
|
||||
w++
|
||||
case 'n':
|
||||
b[w] = '\n'
|
||||
r++
|
||||
w++
|
||||
case 'r':
|
||||
b[w] = '\r'
|
||||
r++
|
||||
w++
|
||||
case 't':
|
||||
b[w] = '\t'
|
||||
r++
|
||||
w++
|
||||
case 'u':
|
||||
r--
|
||||
rr := getu4(s[r:])
|
||||
if rr < 0 {
|
||||
return
|
||||
}
|
||||
r += 6
|
||||
if utf16.IsSurrogate(rr) {
|
||||
rr1 := getu4(s[r:])
|
||||
dec := utf16.DecodeRune(rr, rr1)
|
||||
if dec != unicode.ReplacementChar {
|
||||
// A valid pair; consume.
|
||||
r += 6
|
||||
w += utf8.EncodeRune(b[w:], dec)
|
||||
break
|
||||
}
|
||||
// Invalid surrogate; fall back to replacement rune.
|
||||
rr = unicode.ReplacementChar
|
||||
}
|
||||
w += utf8.EncodeRune(b[w:], rr)
|
||||
}
|
||||
// Quote, control characters are invalid.
|
||||
case c == '"', c < ' ':
|
||||
return
|
||||
// ASCII
|
||||
case c < utf8.RuneSelf:
|
||||
b[w] = c
|
||||
r++
|
||||
w++
|
||||
// Coerce to well-formed UTF-8.
|
||||
default:
|
||||
rr, size := utf8.DecodeRune(s[r:])
|
||||
r += size
|
||||
w += utf8.EncodeRune(b[w:], rr)
|
||||
}
|
||||
}
|
||||
return b[0:w], true
|
||||
}
|
146
vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
generated
vendored
Normal file
146
vendor/github.com/d5/tengo/v2/stdlib/json/encode.go
generated
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
// A modified version of Go's JSON implementation.
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
// Encode returns the JSON encoding of the object.
|
||||
func Encode(o tengo.Object) ([]byte, error) {
|
||||
var b []byte
|
||||
|
||||
switch o := o.(type) {
|
||||
case *tengo.Array:
|
||||
b = append(b, '[')
|
||||
len1 := len(o.Value) - 1
|
||||
for idx, elem := range o.Value {
|
||||
eb, err := Encode(elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, eb...)
|
||||
if idx < len1 {
|
||||
b = append(b, ',')
|
||||
}
|
||||
}
|
||||
b = append(b, ']')
|
||||
case *tengo.ImmutableArray:
|
||||
b = append(b, '[')
|
||||
len1 := len(o.Value) - 1
|
||||
for idx, elem := range o.Value {
|
||||
eb, err := Encode(elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, eb...)
|
||||
if idx < len1 {
|
||||
b = append(b, ',')
|
||||
}
|
||||
}
|
||||
b = append(b, ']')
|
||||
case *tengo.Map:
|
||||
b = append(b, '{')
|
||||
len1 := len(o.Value) - 1
|
||||
idx := 0
|
||||
for key, value := range o.Value {
|
||||
b = strconv.AppendQuote(b, key)
|
||||
b = append(b, ':')
|
||||
eb, err := Encode(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, eb...)
|
||||
if idx < len1 {
|
||||
b = append(b, ',')
|
||||
}
|
||||
idx++
|
||||
}
|
||||
b = append(b, '}')
|
||||
case *tengo.ImmutableMap:
|
||||
b = append(b, '{')
|
||||
len1 := len(o.Value) - 1
|
||||
idx := 0
|
||||
for key, value := range o.Value {
|
||||
b = strconv.AppendQuote(b, key)
|
||||
b = append(b, ':')
|
||||
eb, err := Encode(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, eb...)
|
||||
if idx < len1 {
|
||||
b = append(b, ',')
|
||||
}
|
||||
idx++
|
||||
}
|
||||
b = append(b, '}')
|
||||
case *tengo.Bool:
|
||||
if o.IsFalsy() {
|
||||
b = strconv.AppendBool(b, false)
|
||||
} else {
|
||||
b = strconv.AppendBool(b, true)
|
||||
}
|
||||
case *tengo.Bytes:
|
||||
b = append(b, '"')
|
||||
encodedLen := base64.StdEncoding.EncodedLen(len(o.Value))
|
||||
dst := make([]byte, encodedLen)
|
||||
base64.StdEncoding.Encode(dst, o.Value)
|
||||
b = append(b, dst...)
|
||||
b = append(b, '"')
|
||||
case *tengo.Char:
|
||||
b = strconv.AppendInt(b, int64(o.Value), 10)
|
||||
case *tengo.Float:
|
||||
var y []byte
|
||||
|
||||
f := o.Value
|
||||
if math.IsInf(f, 0) || math.IsNaN(f) {
|
||||
return nil, errors.New("unsupported float value")
|
||||
}
|
||||
|
||||
// Convert as if by ES6 number to string conversion.
|
||||
// This matches most other JSON generators.
|
||||
abs := math.Abs(f)
|
||||
fmt := byte('f')
|
||||
if abs != 0 {
|
||||
if abs < 1e-6 || abs >= 1e21 {
|
||||
fmt = 'e'
|
||||
}
|
||||
}
|
||||
y = strconv.AppendFloat(y, f, fmt, -1, 64)
|
||||
if fmt == 'e' {
|
||||
// clean up e-09 to e-9
|
||||
n := len(y)
|
||||
if n >= 4 && y[n-4] == 'e' && y[n-3] == '-' && y[n-2] == '0' {
|
||||
y[n-2] = y[n-1]
|
||||
y = y[:n-1]
|
||||
}
|
||||
}
|
||||
|
||||
b = append(b, y...)
|
||||
case *tengo.Int:
|
||||
b = strconv.AppendInt(b, o.Value, 10)
|
||||
case *tengo.String:
|
||||
b = strconv.AppendQuote(b, o.Value)
|
||||
case *tengo.Time:
|
||||
y, err := o.Value.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = append(b, y...)
|
||||
case *tengo.Undefined:
|
||||
b = append(b, "null"...)
|
||||
default:
|
||||
// unknown type: ignore
|
||||
}
|
||||
return b, nil
|
||||
}
|
562
vendor/github.com/d5/tengo/v2/stdlib/json/scanner.go
generated
vendored
Normal file
562
vendor/github.com/d5/tengo/v2/stdlib/json/scanner.go
generated
vendored
Normal file
@ -0,0 +1,562 @@
|
||||
// A modified version of Go's JSON implementation.
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import "strconv"
|
||||
|
||||
func checkValid(data []byte, scan *scanner) error {
|
||||
scan.reset()
|
||||
for _, c := range data {
|
||||
scan.bytes++
|
||||
if scan.step(scan, c) == scanError {
|
||||
return scan.err
|
||||
}
|
||||
}
|
||||
if scan.eof() == scanError {
|
||||
return scan.err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A SyntaxError is a description of a JSON syntax error.
|
||||
type SyntaxError struct {
|
||||
msg string // description of error
|
||||
Offset int64 // error occurred after reading Offset bytes
|
||||
}
|
||||
|
||||
func (e *SyntaxError) Error() string { return e.msg }
|
||||
|
||||
// A scanner is a JSON scanning state machine.
|
||||
// Callers call scan.reset() and then pass bytes in one at a time
|
||||
// by calling scan.step(&scan, c) for each byte.
|
||||
// The return value, referred to as an opcode, tells the
|
||||
// caller about significant parsing events like beginning
|
||||
// and ending literals, objects, and arrays, so that the
|
||||
// caller can follow along if it wishes.
|
||||
// The return value scanEnd indicates that a single top-level
|
||||
// JSON value has been completed, *before* the byte that
|
||||
// just got passed in. (The indication must be delayed in order
|
||||
// to recognize the end of numbers: is 123 a whole value or
|
||||
// the beginning of 12345e+6?).
|
||||
type scanner struct {
|
||||
// The step is a func to be called to execute the next transition.
|
||||
// Also tried using an integer constant and a single func
|
||||
// with a switch, but using the func directly was 10% faster
|
||||
// on a 64-bit Mac Mini, and it's nicer to read.
|
||||
step func(*scanner, byte) int
|
||||
|
||||
// Reached end of top-level value.
|
||||
endTop bool
|
||||
|
||||
// Stack of what we're in the middle of - array values, object keys, object values.
|
||||
parseState []int
|
||||
|
||||
// Error that happened, if any.
|
||||
err error
|
||||
|
||||
// total bytes consumed, updated by decoder.Decode
|
||||
bytes int64
|
||||
}
|
||||
|
||||
// These values are returned by the state transition functions
|
||||
// assigned to scanner.state and the method scanner.eof.
|
||||
// They give details about the current state of the scan that
|
||||
// callers might be interested to know about.
|
||||
// It is okay to ignore the return value of any particular
|
||||
// call to scanner.state: if one call returns scanError,
|
||||
// every subsequent call will return scanError too.
|
||||
const (
|
||||
// Continue.
|
||||
scanContinue = iota // uninteresting byte
|
||||
scanBeginLiteral // end implied by next result != scanContinue
|
||||
scanBeginObject // begin object
|
||||
scanObjectKey // just finished object key (string)
|
||||
scanObjectValue // just finished non-last object value
|
||||
scanEndObject // end object (implies scanObjectValue if possible)
|
||||
scanBeginArray // begin array
|
||||
scanArrayValue // just finished array value
|
||||
scanEndArray // end array (implies scanArrayValue if possible)
|
||||
scanSkipSpace // space byte; can skip; known to be last "continue" result
|
||||
|
||||
// Stop.
|
||||
scanEnd // top-level value ended *before* this byte; known to be first "stop" result
|
||||
scanError // hit an error, scanner.err.
|
||||
)
|
||||
|
||||
// These values are stored in the parseState stack.
|
||||
// They give the current state of a composite value
|
||||
// being scanned. If the parser is inside a nested value
|
||||
// the parseState describes the nested state, outermost at entry 0.
|
||||
const (
|
||||
parseObjectKey = iota // parsing object key (before colon)
|
||||
parseObjectValue // parsing object value (after colon)
|
||||
parseArrayValue // parsing array value
|
||||
)
|
||||
|
||||
// reset prepares the scanner for use.
|
||||
// It must be called before calling s.step.
|
||||
func (s *scanner) reset() {
|
||||
s.step = stateBeginValue
|
||||
s.parseState = s.parseState[0:0]
|
||||
s.err = nil
|
||||
s.endTop = false
|
||||
}
|
||||
|
||||
// eof tells the scanner that the end of input has been reached.
|
||||
// It returns a scan status just as s.step does.
|
||||
func (s *scanner) eof() int {
|
||||
if s.err != nil {
|
||||
return scanError
|
||||
}
|
||||
if s.endTop {
|
||||
return scanEnd
|
||||
}
|
||||
s.step(s, ' ')
|
||||
if s.endTop {
|
||||
return scanEnd
|
||||
}
|
||||
if s.err == nil {
|
||||
s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
|
||||
}
|
||||
return scanError
|
||||
}
|
||||
|
||||
// pushParseState pushes a new parse state p onto the parse stack.
|
||||
func (s *scanner) pushParseState(p int) {
|
||||
s.parseState = append(s.parseState, p)
|
||||
}
|
||||
|
||||
// popParseState pops a parse state (already obtained) off the stack
|
||||
// and updates s.step accordingly.
|
||||
func (s *scanner) popParseState() {
|
||||
n := len(s.parseState) - 1
|
||||
s.parseState = s.parseState[0:n]
|
||||
if n == 0 {
|
||||
s.step = stateEndTop
|
||||
s.endTop = true
|
||||
} else {
|
||||
s.step = stateEndValue
|
||||
}
|
||||
}
|
||||
|
||||
func isSpace(c byte) bool {
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n'
|
||||
}
|
||||
|
||||
// stateBeginValueOrEmpty is the state after reading `[`.
|
||||
func stateBeginValueOrEmpty(s *scanner, c byte) int {
|
||||
if c <= ' ' && isSpace(c) {
|
||||
return scanSkipSpace
|
||||
}
|
||||
if c == ']' {
|
||||
return stateEndValue(s, c)
|
||||
}
|
||||
return stateBeginValue(s, c)
|
||||
}
|
||||
|
||||
// stateBeginValue is the state at the beginning of the input.
|
||||
func stateBeginValue(s *scanner, c byte) int {
|
||||
if c <= ' ' && isSpace(c) {
|
||||
return scanSkipSpace
|
||||
}
|
||||
switch c {
|
||||
case '{':
|
||||
s.step = stateBeginStringOrEmpty
|
||||
s.pushParseState(parseObjectKey)
|
||||
return scanBeginObject
|
||||
case '[':
|
||||
s.step = stateBeginValueOrEmpty
|
||||
s.pushParseState(parseArrayValue)
|
||||
return scanBeginArray
|
||||
case '"':
|
||||
s.step = stateInString
|
||||
return scanBeginLiteral
|
||||
case '-':
|
||||
s.step = stateNeg
|
||||
return scanBeginLiteral
|
||||
case '0': // beginning of 0.123
|
||||
s.step = state0
|
||||
return scanBeginLiteral
|
||||
case 't': // beginning of true
|
||||
s.step = stateT
|
||||
return scanBeginLiteral
|
||||
case 'f': // beginning of false
|
||||
s.step = stateF
|
||||
return scanBeginLiteral
|
||||
case 'n': // beginning of null
|
||||
s.step = stateN
|
||||
return scanBeginLiteral
|
||||
}
|
||||
if '1' <= c && c <= '9' { // beginning of 1234.5
|
||||
s.step = state1
|
||||
return scanBeginLiteral
|
||||
}
|
||||
return s.error(c, "looking for beginning of value")
|
||||
}
|
||||
|
||||
// stateBeginStringOrEmpty is the state after reading `{`.
|
||||
func stateBeginStringOrEmpty(s *scanner, c byte) int {
|
||||
if c <= ' ' && isSpace(c) {
|
||||
return scanSkipSpace
|
||||
}
|
||||
if c == '}' {
|
||||
n := len(s.parseState)
|
||||
s.parseState[n-1] = parseObjectValue
|
||||
return stateEndValue(s, c)
|
||||
}
|
||||
return stateBeginString(s, c)
|
||||
}
|
||||
|
||||
// stateBeginString is the state after reading `{"key": value,`.
|
||||
func stateBeginString(s *scanner, c byte) int {
|
||||
if c <= ' ' && isSpace(c) {
|
||||
return scanSkipSpace
|
||||
}
|
||||
if c == '"' {
|
||||
s.step = stateInString
|
||||
return scanBeginLiteral
|
||||
}
|
||||
return s.error(c, "looking for beginning of object key string")
|
||||
}
|
||||
|
||||
// stateEndValue is the state after completing a value,
|
||||
// such as after reading `{}` or `true` or `["x"`.
|
||||
func stateEndValue(s *scanner, c byte) int {
|
||||
n := len(s.parseState)
|
||||
if n == 0 {
|
||||
// Completed top-level before the current byte.
|
||||
s.step = stateEndTop
|
||||
s.endTop = true
|
||||
return stateEndTop(s, c)
|
||||
}
|
||||
if c <= ' ' && isSpace(c) {
|
||||
s.step = stateEndValue
|
||||
return scanSkipSpace
|
||||
}
|
||||
ps := s.parseState[n-1]
|
||||
switch ps {
|
||||
case parseObjectKey:
|
||||
if c == ':' {
|
||||
s.parseState[n-1] = parseObjectValue
|
||||
s.step = stateBeginValue
|
||||
return scanObjectKey
|
||||
}
|
||||
return s.error(c, "after object key")
|
||||
case parseObjectValue:
|
||||
if c == ',' {
|
||||
s.parseState[n-1] = parseObjectKey
|
||||
s.step = stateBeginString
|
||||
return scanObjectValue
|
||||
}
|
||||
if c == '}' {
|
||||
s.popParseState()
|
||||
return scanEndObject
|
||||
}
|
||||
return s.error(c, "after object key:value pair")
|
||||
case parseArrayValue:
|
||||
if c == ',' {
|
||||
s.step = stateBeginValue
|
||||
return scanArrayValue
|
||||
}
|
||||
if c == ']' {
|
||||
s.popParseState()
|
||||
return scanEndArray
|
||||
}
|
||||
return s.error(c, "after array element")
|
||||
}
|
||||
return s.error(c, "")
|
||||
}
|
||||
|
||||
// stateEndTop is the state after finishing the top-level value,
|
||||
// such as after reading `{}` or `[1,2,3]`.
|
||||
// Only space characters should be seen now.
|
||||
func stateEndTop(s *scanner, c byte) int {
|
||||
if !isSpace(c) {
|
||||
// Complain about non-space byte on next call.
|
||||
s.error(c, "after top-level value")
|
||||
}
|
||||
return scanEnd
|
||||
}
|
||||
|
||||
// stateInString is the state after reading `"`.
|
||||
func stateInString(s *scanner, c byte) int {
|
||||
if c == '"' {
|
||||
s.step = stateEndValue
|
||||
return scanContinue
|
||||
}
|
||||
if c == '\\' {
|
||||
s.step = stateInStringEsc
|
||||
return scanContinue
|
||||
}
|
||||
if c < 0x20 {
|
||||
return s.error(c, "in string literal")
|
||||
}
|
||||
return scanContinue
|
||||
}
|
||||
|
||||
// stateInStringEsc is the state after reading `"\` during a quoted string.
|
||||
func stateInStringEsc(s *scanner, c byte) int {
|
||||
switch c {
|
||||
case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
|
||||
s.step = stateInString
|
||||
return scanContinue
|
||||
case 'u':
|
||||
s.step = stateInStringEscU
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in string escape code")
|
||||
}
|
||||
|
||||
// stateInStringEscU is the state after reading `"\u` during a quoted string.
|
||||
func stateInStringEscU(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
|
||||
s.step = stateInStringEscU1
|
||||
return scanContinue
|
||||
}
|
||||
// numbers
|
||||
return s.error(c, "in \\u hexadecimal character escape")
|
||||
}
|
||||
|
||||
// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
|
||||
func stateInStringEscU1(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
|
||||
s.step = stateInStringEscU12
|
||||
return scanContinue
|
||||
}
|
||||
// numbers
|
||||
return s.error(c, "in \\u hexadecimal character escape")
|
||||
}
|
||||
|
||||
// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
|
||||
func stateInStringEscU12(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
|
||||
s.step = stateInStringEscU123
|
||||
return scanContinue
|
||||
}
|
||||
// numbers
|
||||
return s.error(c, "in \\u hexadecimal character escape")
|
||||
}
|
||||
|
||||
// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
|
||||
func stateInStringEscU123(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
|
||||
s.step = stateInString
|
||||
return scanContinue
|
||||
}
|
||||
// numbers
|
||||
return s.error(c, "in \\u hexadecimal character escape")
|
||||
}
|
||||
|
||||
// stateNeg is the state after reading `-` during a number.
|
||||
func stateNeg(s *scanner, c byte) int {
|
||||
if c == '0' {
|
||||
s.step = state0
|
||||
return scanContinue
|
||||
}
|
||||
if '1' <= c && c <= '9' {
|
||||
s.step = state1
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in numeric literal")
|
||||
}
|
||||
|
||||
// state1 is the state after reading a non-zero integer during a number,
|
||||
// such as after reading `1` or `100` but not `0`.
|
||||
func state1(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' {
|
||||
s.step = state1
|
||||
return scanContinue
|
||||
}
|
||||
return state0(s, c)
|
||||
}
|
||||
|
||||
// state0 is the state after reading `0` during a number.
|
||||
func state0(s *scanner, c byte) int {
|
||||
if c == '.' {
|
||||
s.step = stateDot
|
||||
return scanContinue
|
||||
}
|
||||
if c == 'e' || c == 'E' {
|
||||
s.step = stateE
|
||||
return scanContinue
|
||||
}
|
||||
return stateEndValue(s, c)
|
||||
}
|
||||
|
||||
// stateDot is the state after reading the integer and decimal point in a number,
|
||||
// such as after reading `1.`.
|
||||
func stateDot(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' {
|
||||
s.step = stateDot0
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "after decimal point in numeric literal")
|
||||
}
|
||||
|
||||
// stateDot0 is the state after reading the integer, decimal point, and subsequent
|
||||
// digits of a number, such as after reading `3.14`.
|
||||
func stateDot0(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' {
|
||||
return scanContinue
|
||||
}
|
||||
if c == 'e' || c == 'E' {
|
||||
s.step = stateE
|
||||
return scanContinue
|
||||
}
|
||||
return stateEndValue(s, c)
|
||||
}
|
||||
|
||||
// stateE is the state after reading the mantissa and e in a number,
|
||||
// such as after reading `314e` or `0.314e`.
|
||||
func stateE(s *scanner, c byte) int {
|
||||
if c == '+' || c == '-' {
|
||||
s.step = stateESign
|
||||
return scanContinue
|
||||
}
|
||||
return stateESign(s, c)
|
||||
}
|
||||
|
||||
// stateESign is the state after reading the mantissa, e, and sign in a number,
|
||||
// such as after reading `314e-` or `0.314e+`.
|
||||
func stateESign(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' {
|
||||
s.step = stateE0
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in exponent of numeric literal")
|
||||
}
|
||||
|
||||
// stateE0 is the state after reading the mantissa, e, optional sign,
|
||||
// and at least one digit of the exponent in a number,
|
||||
// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
|
||||
func stateE0(s *scanner, c byte) int {
|
||||
if '0' <= c && c <= '9' {
|
||||
return scanContinue
|
||||
}
|
||||
return stateEndValue(s, c)
|
||||
}
|
||||
|
||||
// stateT is the state after reading `t`.
|
||||
func stateT(s *scanner, c byte) int {
|
||||
if c == 'r' {
|
||||
s.step = stateTr
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal true (expecting 'r')")
|
||||
}
|
||||
|
||||
// stateTr is the state after reading `tr`.
|
||||
func stateTr(s *scanner, c byte) int {
|
||||
if c == 'u' {
|
||||
s.step = stateTru
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal true (expecting 'u')")
|
||||
}
|
||||
|
||||
// stateTru is the state after reading `tru`.
|
||||
func stateTru(s *scanner, c byte) int {
|
||||
if c == 'e' {
|
||||
s.step = stateEndValue
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal true (expecting 'e')")
|
||||
}
|
||||
|
||||
// stateF is the state after reading `f`.
|
||||
func stateF(s *scanner, c byte) int {
|
||||
if c == 'a' {
|
||||
s.step = stateFa
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal false (expecting 'a')")
|
||||
}
|
||||
|
||||
// stateFa is the state after reading `fa`.
|
||||
func stateFa(s *scanner, c byte) int {
|
||||
if c == 'l' {
|
||||
s.step = stateFal
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal false (expecting 'l')")
|
||||
}
|
||||
|
||||
// stateFal is the state after reading `fal`.
|
||||
func stateFal(s *scanner, c byte) int {
|
||||
if c == 's' {
|
||||
s.step = stateFals
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal false (expecting 's')")
|
||||
}
|
||||
|
||||
// stateFals is the state after reading `fals`.
|
||||
func stateFals(s *scanner, c byte) int {
|
||||
if c == 'e' {
|
||||
s.step = stateEndValue
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal false (expecting 'e')")
|
||||
}
|
||||
|
||||
// stateN is the state after reading `n`.
|
||||
func stateN(s *scanner, c byte) int {
|
||||
if c == 'u' {
|
||||
s.step = stateNu
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal null (expecting 'u')")
|
||||
}
|
||||
|
||||
// stateNu is the state after reading `nu`.
|
||||
func stateNu(s *scanner, c byte) int {
|
||||
if c == 'l' {
|
||||
s.step = stateNul
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal null (expecting 'l')")
|
||||
}
|
||||
|
||||
// stateNul is the state after reading `nul`.
|
||||
func stateNul(s *scanner, c byte) int {
|
||||
if c == 'l' {
|
||||
s.step = stateEndValue
|
||||
return scanContinue
|
||||
}
|
||||
return s.error(c, "in literal null (expecting 'l')")
|
||||
}
|
||||
|
||||
// stateError is the state after reaching a syntax error,
|
||||
// such as after reading `[1}` or `5.1.2`.
|
||||
func stateError(_ *scanner, _ byte) int {
|
||||
return scanError
|
||||
}
|
||||
|
||||
// error records an error and switches to the error state.
|
||||
func (s *scanner) error(c byte, context string) int {
|
||||
s.step = stateError
|
||||
s.err = &SyntaxError{
|
||||
msg: "invalid character " + quoteChar(c) + " " + context,
|
||||
Offset: s.bytes,
|
||||
}
|
||||
return scanError
|
||||
}
|
||||
|
||||
// quoteChar formats c as a quoted character literal
|
||||
func quoteChar(c byte) string {
|
||||
// special cases - different from quoted strings
|
||||
if c == '\'' {
|
||||
return `'\''`
|
||||
}
|
||||
if c == '"' {
|
||||
return `'"'`
|
||||
}
|
||||
|
||||
// use quoted string with different quotation marks
|
||||
s := strconv.Quote(string(c))
|
||||
return "'" + s[1:len(s)-1] + "'"
|
||||
}
|
233
vendor/github.com/d5/tengo/v2/stdlib/math.go
generated
vendored
Normal file
233
vendor/github.com/d5/tengo/v2/stdlib/math.go
generated
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
var mathModule = map[string]tengo.Object{
|
||||
"e": &tengo.Float{Value: math.E},
|
||||
"pi": &tengo.Float{Value: math.Pi},
|
||||
"phi": &tengo.Float{Value: math.Phi},
|
||||
"sqrt2": &tengo.Float{Value: math.Sqrt2},
|
||||
"sqrtE": &tengo.Float{Value: math.SqrtE},
|
||||
"sqrtPi": &tengo.Float{Value: math.SqrtPi},
|
||||
"sqrtPhi": &tengo.Float{Value: math.SqrtPhi},
|
||||
"ln2": &tengo.Float{Value: math.Ln2},
|
||||
"log2E": &tengo.Float{Value: math.Log2E},
|
||||
"ln10": &tengo.Float{Value: math.Ln10},
|
||||
"log10E": &tengo.Float{Value: math.Log10E},
|
||||
"abs": &tengo.UserFunction{
|
||||
Name: "abs",
|
||||
Value: FuncAFRF(math.Abs),
|
||||
},
|
||||
"acos": &tengo.UserFunction{
|
||||
Name: "acos",
|
||||
Value: FuncAFRF(math.Acos),
|
||||
},
|
||||
"acosh": &tengo.UserFunction{
|
||||
Name: "acosh",
|
||||
Value: FuncAFRF(math.Acosh),
|
||||
},
|
||||
"asin": &tengo.UserFunction{
|
||||
Name: "asin",
|
||||
Value: FuncAFRF(math.Asin),
|
||||
},
|
||||
"asinh": &tengo.UserFunction{
|
||||
Name: "asinh",
|
||||
Value: FuncAFRF(math.Asinh),
|
||||
},
|
||||
"atan": &tengo.UserFunction{
|
||||
Name: "atan",
|
||||
Value: FuncAFRF(math.Atan),
|
||||
},
|
||||
"atan2": &tengo.UserFunction{
|
||||
Name: "atan2",
|
||||
Value: FuncAFFRF(math.Atan2),
|
||||
},
|
||||
"atanh": &tengo.UserFunction{
|
||||
Name: "atanh",
|
||||
Value: FuncAFRF(math.Atanh),
|
||||
},
|
||||
"cbrt": &tengo.UserFunction{
|
||||
Name: "cbrt",
|
||||
Value: FuncAFRF(math.Cbrt),
|
||||
},
|
||||
"ceil": &tengo.UserFunction{
|
||||
Name: "ceil",
|
||||
Value: FuncAFRF(math.Ceil),
|
||||
},
|
||||
"copysign": &tengo.UserFunction{
|
||||
Name: "copysign",
|
||||
Value: FuncAFFRF(math.Copysign),
|
||||
},
|
||||
"cos": &tengo.UserFunction{
|
||||
Name: "cos",
|
||||
Value: FuncAFRF(math.Cos),
|
||||
},
|
||||
"cosh": &tengo.UserFunction{
|
||||
Name: "cosh",
|
||||
Value: FuncAFRF(math.Cosh),
|
||||
},
|
||||
"dim": &tengo.UserFunction{
|
||||
Name: "dim",
|
||||
Value: FuncAFFRF(math.Dim),
|
||||
},
|
||||
"erf": &tengo.UserFunction{
|
||||
Name: "erf",
|
||||
Value: FuncAFRF(math.Erf),
|
||||
},
|
||||
"erfc": &tengo.UserFunction{
|
||||
Name: "erfc",
|
||||
Value: FuncAFRF(math.Erfc),
|
||||
},
|
||||
"exp": &tengo.UserFunction{
|
||||
Name: "exp",
|
||||
Value: FuncAFRF(math.Exp),
|
||||
},
|
||||
"exp2": &tengo.UserFunction{
|
||||
Name: "exp2",
|
||||
Value: FuncAFRF(math.Exp2),
|
||||
},
|
||||
"expm1": &tengo.UserFunction{
|
||||
Name: "expm1",
|
||||
Value: FuncAFRF(math.Expm1),
|
||||
},
|
||||
"floor": &tengo.UserFunction{
|
||||
Name: "floor",
|
||||
Value: FuncAFRF(math.Floor),
|
||||
},
|
||||
"gamma": &tengo.UserFunction{
|
||||
Name: "gamma",
|
||||
Value: FuncAFRF(math.Gamma),
|
||||
},
|
||||
"hypot": &tengo.UserFunction{
|
||||
Name: "hypot",
|
||||
Value: FuncAFFRF(math.Hypot),
|
||||
},
|
||||
"ilogb": &tengo.UserFunction{
|
||||
Name: "ilogb",
|
||||
Value: FuncAFRI(math.Ilogb),
|
||||
},
|
||||
"inf": &tengo.UserFunction{
|
||||
Name: "inf",
|
||||
Value: FuncAIRF(math.Inf),
|
||||
},
|
||||
"is_inf": &tengo.UserFunction{
|
||||
Name: "is_inf",
|
||||
Value: FuncAFIRB(math.IsInf),
|
||||
},
|
||||
"is_nan": &tengo.UserFunction{
|
||||
Name: "is_nan",
|
||||
Value: FuncAFRB(math.IsNaN),
|
||||
},
|
||||
"j0": &tengo.UserFunction{
|
||||
Name: "j0",
|
||||
Value: FuncAFRF(math.J0),
|
||||
},
|
||||
"j1": &tengo.UserFunction{
|
||||
Name: "j1",
|
||||
Value: FuncAFRF(math.J1),
|
||||
},
|
||||
"jn": &tengo.UserFunction{
|
||||
Name: "jn",
|
||||
Value: FuncAIFRF(math.Jn),
|
||||
},
|
||||
"ldexp": &tengo.UserFunction{
|
||||
Name: "ldexp",
|
||||
Value: FuncAFIRF(math.Ldexp),
|
||||
},
|
||||
"log": &tengo.UserFunction{
|
||||
Name: "log",
|
||||
Value: FuncAFRF(math.Log),
|
||||
},
|
||||
"log10": &tengo.UserFunction{
|
||||
Name: "log10",
|
||||
Value: FuncAFRF(math.Log10),
|
||||
},
|
||||
"log1p": &tengo.UserFunction{
|
||||
Name: "log1p",
|
||||
Value: FuncAFRF(math.Log1p),
|
||||
},
|
||||
"log2": &tengo.UserFunction{
|
||||
Name: "log2",
|
||||
Value: FuncAFRF(math.Log2),
|
||||
},
|
||||
"logb": &tengo.UserFunction{
|
||||
Name: "logb",
|
||||
Value: FuncAFRF(math.Logb),
|
||||
},
|
||||
"max": &tengo.UserFunction{
|
||||
Name: "max",
|
||||
Value: FuncAFFRF(math.Max),
|
||||
},
|
||||
"min": &tengo.UserFunction{
|
||||
Name: "min",
|
||||
Value: FuncAFFRF(math.Min),
|
||||
},
|
||||
"mod": &tengo.UserFunction{
|
||||
Name: "mod",
|
||||
Value: FuncAFFRF(math.Mod),
|
||||
},
|
||||
"nan": &tengo.UserFunction{
|
||||
Name: "nan",
|
||||
Value: FuncARF(math.NaN),
|
||||
},
|
||||
"nextafter": &tengo.UserFunction{
|
||||
Name: "nextafter",
|
||||
Value: FuncAFFRF(math.Nextafter),
|
||||
},
|
||||
"pow": &tengo.UserFunction{
|
||||
Name: "pow",
|
||||
Value: FuncAFFRF(math.Pow),
|
||||
},
|
||||
"pow10": &tengo.UserFunction{
|
||||
Name: "pow10",
|
||||
Value: FuncAIRF(math.Pow10),
|
||||
},
|
||||
"remainder": &tengo.UserFunction{
|
||||
Name: "remainder",
|
||||
Value: FuncAFFRF(math.Remainder),
|
||||
},
|
||||
"signbit": &tengo.UserFunction{
|
||||
Name: "signbit",
|
||||
Value: FuncAFRB(math.Signbit),
|
||||
},
|
||||
"sin": &tengo.UserFunction{
|
||||
Name: "sin",
|
||||
Value: FuncAFRF(math.Sin),
|
||||
},
|
||||
"sinh": &tengo.UserFunction{
|
||||
Name: "sinh",
|
||||
Value: FuncAFRF(math.Sinh),
|
||||
},
|
||||
"sqrt": &tengo.UserFunction{
|
||||
Name: "sqrt",
|
||||
Value: FuncAFRF(math.Sqrt),
|
||||
},
|
||||
"tan": &tengo.UserFunction{
|
||||
Name: "tan",
|
||||
Value: FuncAFRF(math.Tan),
|
||||
},
|
||||
"tanh": &tengo.UserFunction{
|
||||
Name: "tanh",
|
||||
Value: FuncAFRF(math.Tanh),
|
||||
},
|
||||
"trunc": &tengo.UserFunction{
|
||||
Name: "trunc",
|
||||
Value: FuncAFRF(math.Trunc),
|
||||
},
|
||||
"y0": &tengo.UserFunction{
|
||||
Name: "y0",
|
||||
Value: FuncAFRF(math.Y0),
|
||||
},
|
||||
"y1": &tengo.UserFunction{
|
||||
Name: "y1",
|
||||
Value: FuncAFRF(math.Y1),
|
||||
},
|
||||
"yn": &tengo.UserFunction{
|
||||
Name: "yn",
|
||||
Value: FuncAIFRF(math.Yn),
|
||||
},
|
||||
}
|
564
vendor/github.com/d5/tengo/v2/stdlib/os.go
generated
vendored
Normal file
564
vendor/github.com/d5/tengo/v2/stdlib/os.go
generated
vendored
Normal file
@ -0,0 +1,564 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
var osModule = map[string]tengo.Object{
|
||||
"o_rdonly": &tengo.Int{Value: int64(os.O_RDONLY)},
|
||||
"o_wronly": &tengo.Int{Value: int64(os.O_WRONLY)},
|
||||
"o_rdwr": &tengo.Int{Value: int64(os.O_RDWR)},
|
||||
"o_append": &tengo.Int{Value: int64(os.O_APPEND)},
|
||||
"o_create": &tengo.Int{Value: int64(os.O_CREATE)},
|
||||
"o_excl": &tengo.Int{Value: int64(os.O_EXCL)},
|
||||
"o_sync": &tengo.Int{Value: int64(os.O_SYNC)},
|
||||
"o_trunc": &tengo.Int{Value: int64(os.O_TRUNC)},
|
||||
"mode_dir": &tengo.Int{Value: int64(os.ModeDir)},
|
||||
"mode_append": &tengo.Int{Value: int64(os.ModeAppend)},
|
||||
"mode_exclusive": &tengo.Int{Value: int64(os.ModeExclusive)},
|
||||
"mode_temporary": &tengo.Int{Value: int64(os.ModeTemporary)},
|
||||
"mode_symlink": &tengo.Int{Value: int64(os.ModeSymlink)},
|
||||
"mode_device": &tengo.Int{Value: int64(os.ModeDevice)},
|
||||
"mode_named_pipe": &tengo.Int{Value: int64(os.ModeNamedPipe)},
|
||||
"mode_socket": &tengo.Int{Value: int64(os.ModeSocket)},
|
||||
"mode_setuid": &tengo.Int{Value: int64(os.ModeSetuid)},
|
||||
"mode_setgui": &tengo.Int{Value: int64(os.ModeSetgid)},
|
||||
"mode_char_device": &tengo.Int{Value: int64(os.ModeCharDevice)},
|
||||
"mode_sticky": &tengo.Int{Value: int64(os.ModeSticky)},
|
||||
"mode_type": &tengo.Int{Value: int64(os.ModeType)},
|
||||
"mode_perm": &tengo.Int{Value: int64(os.ModePerm)},
|
||||
"path_separator": &tengo.Char{Value: os.PathSeparator},
|
||||
"path_list_separator": &tengo.Char{Value: os.PathListSeparator},
|
||||
"dev_null": &tengo.String{Value: os.DevNull},
|
||||
"seek_set": &tengo.Int{Value: int64(io.SeekStart)},
|
||||
"seek_cur": &tengo.Int{Value: int64(io.SeekCurrent)},
|
||||
"seek_end": &tengo.Int{Value: int64(io.SeekEnd)},
|
||||
"args": &tengo.UserFunction{
|
||||
Name: "args",
|
||||
Value: osArgs,
|
||||
}, // args() => array(string)
|
||||
"chdir": &tengo.UserFunction{
|
||||
Name: "chdir",
|
||||
Value: FuncASRE(os.Chdir),
|
||||
}, // chdir(dir string) => error
|
||||
"chmod": osFuncASFmRE("chmod", os.Chmod), // chmod(name string, mode int) => error
|
||||
"chown": &tengo.UserFunction{
|
||||
Name: "chown",
|
||||
Value: FuncASIIRE(os.Chown),
|
||||
}, // chown(name string, uid int, gid int) => error
|
||||
"clearenv": &tengo.UserFunction{
|
||||
Name: "clearenv",
|
||||
Value: FuncAR(os.Clearenv),
|
||||
}, // clearenv()
|
||||
"environ": &tengo.UserFunction{
|
||||
Name: "environ",
|
||||
Value: FuncARSs(os.Environ),
|
||||
}, // environ() => array(string)
|
||||
"exit": &tengo.UserFunction{
|
||||
Name: "exit",
|
||||
Value: FuncAIR(os.Exit),
|
||||
}, // exit(code int)
|
||||
"expand_env": &tengo.UserFunction{
|
||||
Name: "expand_env",
|
||||
Value: osExpandEnv,
|
||||
}, // expand_env(s string) => string
|
||||
"getegid": &tengo.UserFunction{
|
||||
Name: "getegid",
|
||||
Value: FuncARI(os.Getegid),
|
||||
}, // getegid() => int
|
||||
"getenv": &tengo.UserFunction{
|
||||
Name: "getenv",
|
||||
Value: FuncASRS(os.Getenv),
|
||||
}, // getenv(s string) => string
|
||||
"geteuid": &tengo.UserFunction{
|
||||
Name: "geteuid",
|
||||
Value: FuncARI(os.Geteuid),
|
||||
}, // geteuid() => int
|
||||
"getgid": &tengo.UserFunction{
|
||||
Name: "getgid",
|
||||
Value: FuncARI(os.Getgid),
|
||||
}, // getgid() => int
|
||||
"getgroups": &tengo.UserFunction{
|
||||
Name: "getgroups",
|
||||
Value: FuncARIsE(os.Getgroups),
|
||||
}, // getgroups() => array(string)/error
|
||||
"getpagesize": &tengo.UserFunction{
|
||||
Name: "getpagesize",
|
||||
Value: FuncARI(os.Getpagesize),
|
||||
}, // getpagesize() => int
|
||||
"getpid": &tengo.UserFunction{
|
||||
Name: "getpid",
|
||||
Value: FuncARI(os.Getpid),
|
||||
}, // getpid() => int
|
||||
"getppid": &tengo.UserFunction{
|
||||
Name: "getppid",
|
||||
Value: FuncARI(os.Getppid),
|
||||
}, // getppid() => int
|
||||
"getuid": &tengo.UserFunction{
|
||||
Name: "getuid",
|
||||
Value: FuncARI(os.Getuid),
|
||||
}, // getuid() => int
|
||||
"getwd": &tengo.UserFunction{
|
||||
Name: "getwd",
|
||||
Value: FuncARSE(os.Getwd),
|
||||
}, // getwd() => string/error
|
||||
"hostname": &tengo.UserFunction{
|
||||
Name: "hostname",
|
||||
Value: FuncARSE(os.Hostname),
|
||||
}, // hostname() => string/error
|
||||
"lchown": &tengo.UserFunction{
|
||||
Name: "lchown",
|
||||
Value: FuncASIIRE(os.Lchown),
|
||||
}, // lchown(name string, uid int, gid int) => error
|
||||
"link": &tengo.UserFunction{
|
||||
Name: "link",
|
||||
Value: FuncASSRE(os.Link),
|
||||
}, // link(oldname string, newname string) => error
|
||||
"lookup_env": &tengo.UserFunction{
|
||||
Name: "lookup_env",
|
||||
Value: osLookupEnv,
|
||||
}, // lookup_env(key string) => string/false
|
||||
"mkdir": osFuncASFmRE("mkdir", os.Mkdir), // mkdir(name string, perm int) => error
|
||||
"mkdir_all": osFuncASFmRE("mkdir_all", os.MkdirAll), // mkdir_all(name string, perm int) => error
|
||||
"readlink": &tengo.UserFunction{
|
||||
Name: "readlink",
|
||||
Value: FuncASRSE(os.Readlink),
|
||||
}, // readlink(name string) => string/error
|
||||
"remove": &tengo.UserFunction{
|
||||
Name: "remove",
|
||||
Value: FuncASRE(os.Remove),
|
||||
}, // remove(name string) => error
|
||||
"remove_all": &tengo.UserFunction{
|
||||
Name: "remove_all",
|
||||
Value: FuncASRE(os.RemoveAll),
|
||||
}, // remove_all(name string) => error
|
||||
"rename": &tengo.UserFunction{
|
||||
Name: "rename",
|
||||
Value: FuncASSRE(os.Rename),
|
||||
}, // rename(oldpath string, newpath string) => error
|
||||
"setenv": &tengo.UserFunction{
|
||||
Name: "setenv",
|
||||
Value: FuncASSRE(os.Setenv),
|
||||
}, // setenv(key string, value string) => error
|
||||
"symlink": &tengo.UserFunction{
|
||||
Name: "symlink",
|
||||
Value: FuncASSRE(os.Symlink),
|
||||
}, // symlink(oldname string newname string) => error
|
||||
"temp_dir": &tengo.UserFunction{
|
||||
Name: "temp_dir",
|
||||
Value: FuncARS(os.TempDir),
|
||||
}, // temp_dir() => string
|
||||
"truncate": &tengo.UserFunction{
|
||||
Name: "truncate",
|
||||
Value: FuncASI64RE(os.Truncate),
|
||||
}, // truncate(name string, size int) => error
|
||||
"unsetenv": &tengo.UserFunction{
|
||||
Name: "unsetenv",
|
||||
Value: FuncASRE(os.Unsetenv),
|
||||
}, // unsetenv(key string) => error
|
||||
"create": &tengo.UserFunction{
|
||||
Name: "create",
|
||||
Value: osCreate,
|
||||
}, // create(name string) => imap(file)/error
|
||||
"open": &tengo.UserFunction{
|
||||
Name: "open",
|
||||
Value: osOpen,
|
||||
}, // open(name string) => imap(file)/error
|
||||
"open_file": &tengo.UserFunction{
|
||||
Name: "open_file",
|
||||
Value: osOpenFile,
|
||||
}, // open_file(name string, flag int, perm int) => imap(file)/error
|
||||
"find_process": &tengo.UserFunction{
|
||||
Name: "find_process",
|
||||
Value: osFindProcess,
|
||||
}, // find_process(pid int) => imap(process)/error
|
||||
"start_process": &tengo.UserFunction{
|
||||
Name: "start_process",
|
||||
Value: osStartProcess,
|
||||
}, // start_process(name string, argv array(string), dir string, env array(string)) => imap(process)/error
|
||||
"exec_look_path": &tengo.UserFunction{
|
||||
Name: "exec_look_path",
|
||||
Value: FuncASRSE(exec.LookPath),
|
||||
}, // exec_look_path(file) => string/error
|
||||
"exec": &tengo.UserFunction{
|
||||
Name: "exec",
|
||||
Value: osExec,
|
||||
}, // exec(name, args...) => command
|
||||
"stat": &tengo.UserFunction{
|
||||
Name: "stat",
|
||||
Value: osStat,
|
||||
}, // stat(name) => imap(fileinfo)/error
|
||||
"read_file": &tengo.UserFunction{
|
||||
Name: "read_file",
|
||||
Value: osReadFile,
|
||||
}, // readfile(name) => array(byte)/error
|
||||
}
|
||||
|
||||
func osReadFile(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
fname, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
bytes, err := ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
if len(bytes) > tengo.MaxBytesLen {
|
||||
return nil, tengo.ErrBytesLimit
|
||||
}
|
||||
return &tengo.Bytes{Value: bytes}, nil
|
||||
}
|
||||
|
||||
func osStat(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
fname, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
stat, err := os.Stat(fname)
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
fstat := &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
"name": &tengo.String{Value: stat.Name()},
|
||||
"mtime": &tengo.Time{Value: stat.ModTime()},
|
||||
"size": &tengo.Int{Value: stat.Size()},
|
||||
"mode": &tengo.Int{Value: int64(stat.Mode())},
|
||||
},
|
||||
}
|
||||
if stat.IsDir() {
|
||||
fstat.Value["directory"] = tengo.TrueValue
|
||||
} else {
|
||||
fstat.Value["directory"] = tengo.FalseValue
|
||||
}
|
||||
return fstat, nil
|
||||
}
|
||||
|
||||
func osCreate(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
res, err := os.Create(s1)
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return makeOSFile(res), nil
|
||||
}
|
||||
|
||||
func osOpen(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
res, err := os.Open(s1)
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return makeOSFile(res), nil
|
||||
}
|
||||
|
||||
func osOpenFile(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 3 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
i2, ok := tengo.ToInt(args[1])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
}
|
||||
i3, ok := tengo.ToInt(args[2])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "third",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[2].TypeName(),
|
||||
}
|
||||
}
|
||||
res, err := os.OpenFile(s1, i2, os.FileMode(i3))
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return makeOSFile(res), nil
|
||||
}
|
||||
|
||||
func osArgs(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
arr := &tengo.Array{}
|
||||
for _, osArg := range os.Args {
|
||||
if len(osArg) > tengo.MaxStringLen {
|
||||
return nil, tengo.ErrStringLimit
|
||||
}
|
||||
arr.Value = append(arr.Value, &tengo.String{Value: osArg})
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
|
||||
func osFuncASFmRE(
|
||||
name string,
|
||||
fn func(string, os.FileMode) error,
|
||||
) *tengo.UserFunction {
|
||||
return &tengo.UserFunction{
|
||||
Name: name,
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
i2, ok := tengo.ToInt64(args[1])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
}
|
||||
return wrapError(fn(s1, os.FileMode(i2))), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func osLookupEnv(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
res, ok := os.LookupEnv(s1)
|
||||
if !ok {
|
||||
return tengo.FalseValue, nil
|
||||
}
|
||||
if len(res) > tengo.MaxStringLen {
|
||||
return nil, tengo.ErrStringLimit
|
||||
}
|
||||
return &tengo.String{Value: res}, nil
|
||||
}
|
||||
|
||||
func osExpandEnv(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
var vlen int
|
||||
var failed bool
|
||||
s := os.Expand(s1, func(k string) string {
|
||||
if failed {
|
||||
return ""
|
||||
}
|
||||
v := os.Getenv(k)
|
||||
|
||||
// this does not count the other texts that are not being replaced
|
||||
// but the code checks the final length at the end
|
||||
vlen += len(v)
|
||||
if vlen > tengo.MaxStringLen {
|
||||
failed = true
|
||||
return ""
|
||||
}
|
||||
return v
|
||||
})
|
||||
if failed || len(s) > tengo.MaxStringLen {
|
||||
return nil, tengo.ErrStringLimit
|
||||
}
|
||||
return &tengo.String{Value: s}, nil
|
||||
}
|
||||
|
||||
func osExec(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) == 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
name, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
var execArgs []string
|
||||
for idx, arg := range args[1:] {
|
||||
execArg, ok := tengo.ToString(arg)
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: fmt.Sprintf("args[%d]", idx),
|
||||
Expected: "string(compatible)",
|
||||
Found: args[1+idx].TypeName(),
|
||||
}
|
||||
}
|
||||
execArgs = append(execArgs, execArg)
|
||||
}
|
||||
return makeOSExecCommand(exec.Command(name, execArgs...)), nil
|
||||
}
|
||||
|
||||
func osFindProcess(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
i1, ok := tengo.ToInt(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
proc, err := os.FindProcess(i1)
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return makeOSProcess(proc), nil
|
||||
}
|
||||
|
||||
func osStartProcess(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 4 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
name, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
var argv []string
|
||||
var err error
|
||||
switch arg1 := args[1].(type) {
|
||||
case *tengo.Array:
|
||||
argv, err = stringArray(arg1.Value, "second")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *tengo.ImmutableArray:
|
||||
argv, err = stringArray(arg1.Value, "second")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "array",
|
||||
Found: arg1.TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
dir, ok := tengo.ToString(args[2])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "third",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[2].TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
var env []string
|
||||
switch arg3 := args[3].(type) {
|
||||
case *tengo.Array:
|
||||
env, err = stringArray(arg3.Value, "fourth")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *tengo.ImmutableArray:
|
||||
env, err = stringArray(arg3.Value, "fourth")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "fourth",
|
||||
Expected: "array",
|
||||
Found: arg3.TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
proc, err := os.StartProcess(name, argv, &os.ProcAttr{
|
||||
Dir: dir,
|
||||
Env: env,
|
||||
})
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return makeOSProcess(proc), nil
|
||||
}
|
||||
|
||||
func stringArray(arr []tengo.Object, argName string) ([]string, error) {
|
||||
var sarr []string
|
||||
for idx, elem := range arr {
|
||||
str, ok := elem.(*tengo.String)
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: fmt.Sprintf("%s[%d]", argName, idx),
|
||||
Expected: "string",
|
||||
Found: elem.TypeName(),
|
||||
}
|
||||
}
|
||||
sarr = append(sarr, str.Value)
|
||||
}
|
||||
return sarr, nil
|
||||
}
|
119
vendor/github.com/d5/tengo/v2/stdlib/os_exec.go
generated
vendored
Normal file
119
vendor/github.com/d5/tengo/v2/stdlib/os_exec.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
func makeOSExecCommand(cmd *exec.Cmd) *tengo.ImmutableMap {
|
||||
return &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
// combined_output() => bytes/error
|
||||
"combined_output": &tengo.UserFunction{
|
||||
Name: "combined_output",
|
||||
Value: FuncARYE(cmd.CombinedOutput),
|
||||
},
|
||||
// output() => bytes/error
|
||||
"output": &tengo.UserFunction{
|
||||
Name: "output",
|
||||
Value: FuncARYE(cmd.Output),
|
||||
}, //
|
||||
// run() => error
|
||||
"run": &tengo.UserFunction{
|
||||
Name: "run",
|
||||
Value: FuncARE(cmd.Run),
|
||||
}, //
|
||||
// start() => error
|
||||
"start": &tengo.UserFunction{
|
||||
Name: "start",
|
||||
Value: FuncARE(cmd.Start),
|
||||
}, //
|
||||
// wait() => error
|
||||
"wait": &tengo.UserFunction{
|
||||
Name: "wait",
|
||||
Value: FuncARE(cmd.Wait),
|
||||
}, //
|
||||
// set_path(path string)
|
||||
"set_path": &tengo.UserFunction{
|
||||
Name: "set_path",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
cmd.Path = s1
|
||||
return tengo.UndefinedValue, nil
|
||||
},
|
||||
},
|
||||
// set_dir(dir string)
|
||||
"set_dir": &tengo.UserFunction{
|
||||
Name: "set_dir",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
cmd.Dir = s1
|
||||
return tengo.UndefinedValue, nil
|
||||
},
|
||||
},
|
||||
// set_env(env array(string))
|
||||
"set_env": &tengo.UserFunction{
|
||||
Name: "set_env",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
var env []string
|
||||
var err error
|
||||
switch arg0 := args[0].(type) {
|
||||
case *tengo.Array:
|
||||
env, err = stringArray(arg0.Value, "first")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *tengo.ImmutableArray:
|
||||
env, err = stringArray(arg0.Value, "first")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "array",
|
||||
Found: arg0.TypeName(),
|
||||
}
|
||||
}
|
||||
cmd.Env = env
|
||||
return tengo.UndefinedValue, nil
|
||||
},
|
||||
},
|
||||
// process() => imap(process)
|
||||
"process": &tengo.UserFunction{
|
||||
Name: "process",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
return makeOSProcess(cmd.Process), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
117
vendor/github.com/d5/tengo/v2/stdlib/os_file.go
generated
vendored
Normal file
117
vendor/github.com/d5/tengo/v2/stdlib/os_file.go
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
func makeOSFile(file *os.File) *tengo.ImmutableMap {
|
||||
return &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
// chdir() => true/error
|
||||
"chdir": &tengo.UserFunction{
|
||||
Name: "chdir",
|
||||
Value: FuncARE(file.Chdir),
|
||||
}, //
|
||||
// chown(uid int, gid int) => true/error
|
||||
"chown": &tengo.UserFunction{
|
||||
Name: "chown",
|
||||
Value: FuncAIIRE(file.Chown),
|
||||
}, //
|
||||
// close() => error
|
||||
"close": &tengo.UserFunction{
|
||||
Name: "close",
|
||||
Value: FuncARE(file.Close),
|
||||
}, //
|
||||
// name() => string
|
||||
"name": &tengo.UserFunction{
|
||||
Name: "name",
|
||||
Value: FuncARS(file.Name),
|
||||
}, //
|
||||
// readdirnames(n int) => array(string)/error
|
||||
"readdirnames": &tengo.UserFunction{
|
||||
Name: "readdirnames",
|
||||
Value: FuncAIRSsE(file.Readdirnames),
|
||||
}, //
|
||||
// sync() => error
|
||||
"sync": &tengo.UserFunction{
|
||||
Name: "sync",
|
||||
Value: FuncARE(file.Sync),
|
||||
}, //
|
||||
// write(bytes) => int/error
|
||||
"write": &tengo.UserFunction{
|
||||
Name: "write",
|
||||
Value: FuncAYRIE(file.Write),
|
||||
}, //
|
||||
// write(string) => int/error
|
||||
"write_string": &tengo.UserFunction{
|
||||
Name: "write_string",
|
||||
Value: FuncASRIE(file.WriteString),
|
||||
}, //
|
||||
// read(bytes) => int/error
|
||||
"read": &tengo.UserFunction{
|
||||
Name: "read",
|
||||
Value: FuncAYRIE(file.Read),
|
||||
}, //
|
||||
// chmod(mode int) => error
|
||||
"chmod": &tengo.UserFunction{
|
||||
Name: "chmod",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
i1, ok := tengo.ToInt64(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
return wrapError(file.Chmod(os.FileMode(i1))), nil
|
||||
},
|
||||
},
|
||||
// seek(offset int, whence int) => int/error
|
||||
"seek": &tengo.UserFunction{
|
||||
Name: "seek",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
i1, ok := tengo.ToInt64(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
i2, ok := tengo.ToInt(args[1])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
}
|
||||
res, err := file.Seek(i1, i2)
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return &tengo.Int{Value: res}, nil
|
||||
},
|
||||
},
|
||||
// stat() => imap(fileinfo)/error
|
||||
"stat": &tengo.UserFunction{
|
||||
Name: "stat",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
return osStat(&tengo.String{Value: file.Name()})
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
76
vendor/github.com/d5/tengo/v2/stdlib/os_process.go
generated
vendored
Normal file
76
vendor/github.com/d5/tengo/v2/stdlib/os_process.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
func makeOSProcessState(state *os.ProcessState) *tengo.ImmutableMap {
|
||||
return &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
"exited": &tengo.UserFunction{
|
||||
Name: "exited",
|
||||
Value: FuncARB(state.Exited),
|
||||
},
|
||||
"pid": &tengo.UserFunction{
|
||||
Name: "pid",
|
||||
Value: FuncARI(state.Pid),
|
||||
},
|
||||
"string": &tengo.UserFunction{
|
||||
Name: "string",
|
||||
Value: FuncARS(state.String),
|
||||
},
|
||||
"success": &tengo.UserFunction{
|
||||
Name: "success",
|
||||
Value: FuncARB(state.Success),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func makeOSProcess(proc *os.Process) *tengo.ImmutableMap {
|
||||
return &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
"kill": &tengo.UserFunction{
|
||||
Name: "kill",
|
||||
Value: FuncARE(proc.Kill),
|
||||
},
|
||||
"release": &tengo.UserFunction{
|
||||
Name: "release",
|
||||
Value: FuncARE(proc.Release),
|
||||
},
|
||||
"signal": &tengo.UserFunction{
|
||||
Name: "signal",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
i1, ok := tengo.ToInt64(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
return wrapError(proc.Signal(syscall.Signal(i1))), nil
|
||||
},
|
||||
},
|
||||
"wait": &tengo.UserFunction{
|
||||
Name: "wait",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
state, err := proc.Wait()
|
||||
if err != nil {
|
||||
return wrapError(err), nil
|
||||
}
|
||||
return makeOSProcessState(state), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
138
vendor/github.com/d5/tengo/v2/stdlib/rand.go
generated
vendored
Normal file
138
vendor/github.com/d5/tengo/v2/stdlib/rand.go
generated
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
var randModule = map[string]tengo.Object{
|
||||
"int": &tengo.UserFunction{
|
||||
Name: "int",
|
||||
Value: FuncARI64(rand.Int63),
|
||||
},
|
||||
"float": &tengo.UserFunction{
|
||||
Name: "float",
|
||||
Value: FuncARF(rand.Float64),
|
||||
},
|
||||
"intn": &tengo.UserFunction{
|
||||
Name: "intn",
|
||||
Value: FuncAI64RI64(rand.Int63n),
|
||||
},
|
||||
"exp_float": &tengo.UserFunction{
|
||||
Name: "exp_float",
|
||||
Value: FuncARF(rand.ExpFloat64),
|
||||
},
|
||||
"norm_float": &tengo.UserFunction{
|
||||
Name: "norm_float",
|
||||
Value: FuncARF(rand.NormFloat64),
|
||||
},
|
||||
"perm": &tengo.UserFunction{
|
||||
Name: "perm",
|
||||
Value: FuncAIRIs(rand.Perm),
|
||||
},
|
||||
"seed": &tengo.UserFunction{
|
||||
Name: "seed",
|
||||
Value: FuncAI64R(rand.Seed),
|
||||
},
|
||||
"read": &tengo.UserFunction{
|
||||
Name: "read",
|
||||
Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
y1, ok := args[0].(*tengo.Bytes)
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "bytes",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
res, err := rand.Read(y1.Value)
|
||||
if err != nil {
|
||||
ret = wrapError(err)
|
||||
return
|
||||
}
|
||||
return &tengo.Int{Value: int64(res)}, nil
|
||||
},
|
||||
},
|
||||
"rand": &tengo.UserFunction{
|
||||
Name: "rand",
|
||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
i1, ok := tengo.ToInt64(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
src := rand.NewSource(i1)
|
||||
return randRand(rand.New(src)), nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func randRand(r *rand.Rand) *tengo.ImmutableMap {
|
||||
return &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
"int": &tengo.UserFunction{
|
||||
Name: "int",
|
||||
Value: FuncARI64(r.Int63),
|
||||
},
|
||||
"float": &tengo.UserFunction{
|
||||
Name: "float",
|
||||
Value: FuncARF(r.Float64),
|
||||
},
|
||||
"intn": &tengo.UserFunction{
|
||||
Name: "intn",
|
||||
Value: FuncAI64RI64(r.Int63n),
|
||||
},
|
||||
"exp_float": &tengo.UserFunction{
|
||||
Name: "exp_float",
|
||||
Value: FuncARF(r.ExpFloat64),
|
||||
},
|
||||
"norm_float": &tengo.UserFunction{
|
||||
Name: "norm_float",
|
||||
Value: FuncARF(r.NormFloat64),
|
||||
},
|
||||
"perm": &tengo.UserFunction{
|
||||
Name: "perm",
|
||||
Value: FuncAIRIs(r.Perm),
|
||||
},
|
||||
"seed": &tengo.UserFunction{
|
||||
Name: "seed",
|
||||
Value: FuncAI64R(r.Seed),
|
||||
},
|
||||
"read": &tengo.UserFunction{
|
||||
Name: "read",
|
||||
Value: func(args ...tengo.Object) (
|
||||
ret tengo.Object,
|
||||
err error,
|
||||
) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
y1, ok := args[0].(*tengo.Bytes)
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "bytes",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
res, err := r.Read(y1.Value)
|
||||
if err != nil {
|
||||
ret = wrapError(err)
|
||||
return
|
||||
}
|
||||
return &tengo.Int{Value: int64(res)}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
8
vendor/github.com/d5/tengo/v2/stdlib/source_modules.go
generated
vendored
Normal file
8
vendor/github.com/d5/tengo/v2/stdlib/source_modules.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// Code generated using gensrcmods.go; DO NOT EDIT.
|
||||
|
||||
package stdlib
|
||||
|
||||
// SourceModules are source type standard library modules.
|
||||
var SourceModules = map[string]string{
|
||||
"enum": "is_enumerable := func(x) {\n return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)\n}\n\nis_array_like := func(x) {\n return is_array(x) || is_immutable_array(x)\n}\n\nexport {\n // all returns true if the given function `fn` evaluates to a truthy value on\n // all of the items in `x`. It returns undefined if `x` is not enumerable.\n all: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if !fn(k, v) { return false }\n }\n\n return true\n },\n // any returns true if the given function `fn` evaluates to a truthy value on\n // any of the items in `x`. It returns undefined if `x` is not enumerable.\n any: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return true }\n }\n\n return false\n },\n // chunk returns an array of elements split into groups the length of size.\n // If `x` can't be split evenly, the final chunk will be the remaining elements.\n // It returns undefined if `x` is not array.\n chunk: func(x, size) {\n if !is_array_like(x) || !size { return undefined }\n\n numElements := len(x)\n if !numElements { return [] }\n\n res := []\n idx := 0\n for idx < numElements {\n res = append(res, x[idx:idx+size])\n idx += size\n }\n\n return res\n },\n // at returns an element at the given index (if `x` is array) or\n // key (if `x` is map). It returns undefined if `x` is not enumerable.\n at: func(x, key) {\n if !is_enumerable(x) { return undefined }\n\n if is_array_like(x) {\n if !is_int(key) { return undefined }\n } else {\n if !is_string(key) { return undefined }\n }\n\n return x[key]\n },\n // each iterates over elements of `x` and invokes `fn` for each element. `fn` is\n // invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It does not iterate\n // and returns undefined if `x` is not enumerable.\n each: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n fn(k, v)\n }\n },\n // filter iterates over elements of `x`, returning an array of all elements `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n filter: func(x, fn) {\n if !is_array_like(x) { return undefined }\n\n dst := []\n for k, v in x {\n if fn(k, v) { dst = append(dst, v) }\n }\n\n return dst\n },\n // find iterates over elements of `x`, returning value of the first element `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n find: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return v }\n }\n },\n // find_key iterates over elements of `x`, returning key or index of the first\n // element `fn` returns truthy for. `fn` is invoked with two arguments: `key`\n // and `value`. `key` is an int index if `x` is array. `key` is a string key if\n // `x` is map. It returns undefined if `x` is not enumerable.\n find_key: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return k }\n }\n },\n // map creates an array of values by running each element in `x` through `fn`.\n // `fn` is invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It returns undefined\n // if `x` is not enumerable.\n map: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n dst := []\n for k, v in x {\n dst = append(dst, fn(k, v))\n }\n\n return dst\n },\n // key returns the first argument.\n key: func(k, _) { return k },\n // value returns the second argument.\n value: func(_, v) { return v }\n}\n",
|
||||
}
|
128
vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo
generated
vendored
Normal file
128
vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
is_enumerable := func(x) {
|
||||
return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)
|
||||
}
|
||||
|
||||
is_array_like := func(x) {
|
||||
return is_array(x) || is_immutable_array(x)
|
||||
}
|
||||
|
||||
export {
|
||||
// all returns true if the given function `fn` evaluates to a truthy value on
|
||||
// all of the items in `x`. It returns undefined if `x` is not enumerable.
|
||||
all: func(x, fn) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
for k, v in x {
|
||||
if !fn(k, v) { return false }
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
// any returns true if the given function `fn` evaluates to a truthy value on
|
||||
// any of the items in `x`. It returns undefined if `x` is not enumerable.
|
||||
any: func(x, fn) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
for k, v in x {
|
||||
if fn(k, v) { return true }
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
// chunk returns an array of elements split into groups the length of size.
|
||||
// If `x` can't be split evenly, the final chunk will be the remaining elements.
|
||||
// It returns undefined if `x` is not array.
|
||||
chunk: func(x, size) {
|
||||
if !is_array_like(x) || !size { return undefined }
|
||||
|
||||
numElements := len(x)
|
||||
if !numElements { return [] }
|
||||
|
||||
res := []
|
||||
idx := 0
|
||||
for idx < numElements {
|
||||
res = append(res, x[idx:idx+size])
|
||||
idx += size
|
||||
}
|
||||
|
||||
return res
|
||||
},
|
||||
// at returns an element at the given index (if `x` is array) or
|
||||
// key (if `x` is map). It returns undefined if `x` is not enumerable.
|
||||
at: func(x, key) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
if is_array_like(x) {
|
||||
if !is_int(key) { return undefined }
|
||||
} else {
|
||||
if !is_string(key) { return undefined }
|
||||
}
|
||||
|
||||
return x[key]
|
||||
},
|
||||
// each iterates over elements of `x` and invokes `fn` for each element. `fn` is
|
||||
// invoked with two arguments: `key` and `value`. `key` is an int index
|
||||
// if `x` is array. `key` is a string key if `x` is map. It does not iterate
|
||||
// and returns undefined if `x` is not enumerable.
|
||||
each: func(x, fn) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
for k, v in x {
|
||||
fn(k, v)
|
||||
}
|
||||
},
|
||||
// filter iterates over elements of `x`, returning an array of all elements `fn`
|
||||
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
||||
// `key` is an int index if `x` is array. `key` is a string key if `x` is map.
|
||||
// It returns undefined if `x` is not enumerable.
|
||||
filter: func(x, fn) {
|
||||
if !is_array_like(x) { return undefined }
|
||||
|
||||
dst := []
|
||||
for k, v in x {
|
||||
if fn(k, v) { dst = append(dst, v) }
|
||||
}
|
||||
|
||||
return dst
|
||||
},
|
||||
// find iterates over elements of `x`, returning value of the first element `fn`
|
||||
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
||||
// `key` is an int index if `x` is array. `key` is a string key if `x` is map.
|
||||
// It returns undefined if `x` is not enumerable.
|
||||
find: func(x, fn) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
for k, v in x {
|
||||
if fn(k, v) { return v }
|
||||
}
|
||||
},
|
||||
// find_key iterates over elements of `x`, returning key or index of the first
|
||||
// element `fn` returns truthy for. `fn` is invoked with two arguments: `key`
|
||||
// and `value`. `key` is an int index if `x` is array. `key` is a string key if
|
||||
// `x` is map. It returns undefined if `x` is not enumerable.
|
||||
find_key: func(x, fn) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
for k, v in x {
|
||||
if fn(k, v) { return k }
|
||||
}
|
||||
},
|
||||
// map creates an array of values by running each element in `x` through `fn`.
|
||||
// `fn` is invoked with two arguments: `key` and `value`. `key` is an int index
|
||||
// if `x` is array. `key` is a string key if `x` is map. It returns undefined
|
||||
// if `x` is not enumerable.
|
||||
map: func(x, fn) {
|
||||
if !is_enumerable(x) { return undefined }
|
||||
|
||||
dst := []
|
||||
for k, v in x {
|
||||
dst = append(dst, fn(k, v))
|
||||
}
|
||||
|
||||
return dst
|
||||
},
|
||||
// key returns the first argument.
|
||||
key: func(k, _) { return k },
|
||||
// value returns the second argument.
|
||||
value: func(_, v) { return v }
|
||||
}
|
34
vendor/github.com/d5/tengo/v2/stdlib/stdlib.go
generated
vendored
Normal file
34
vendor/github.com/d5/tengo/v2/stdlib/stdlib.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package stdlib
|
||||
|
||||
//go:generate go run gensrcmods.go
|
||||
|
||||
import (
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
// AllModuleNames returns a list of all default module names.
|
||||
func AllModuleNames() []string {
|
||||
var names []string
|
||||
for name := range BuiltinModules {
|
||||
names = append(names, name)
|
||||
}
|
||||
for name := range SourceModules {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// GetModuleMap returns the module map that includes all modules
|
||||
// for the given module names.
|
||||
func GetModuleMap(names ...string) *tengo.ModuleMap {
|
||||
modules := tengo.NewModuleMap()
|
||||
for _, name := range names {
|
||||
if mod := BuiltinModules[name]; mod != nil {
|
||||
modules.AddBuiltinModule(name, mod)
|
||||
}
|
||||
if mod := SourceModules[name]; mod != "" {
|
||||
modules.AddSourceModule(name, []byte(mod))
|
||||
}
|
||||
}
|
||||
return modules
|
||||
}
|
1072
vendor/github.com/d5/tengo/v2/stdlib/text.go
generated
vendored
Normal file
1072
vendor/github.com/d5/tengo/v2/stdlib/text.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
251
vendor/github.com/d5/tengo/v2/stdlib/text_regexp.go
generated
vendored
Normal file
251
vendor/github.com/d5/tengo/v2/stdlib/text_regexp.go
generated
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
package stdlib
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||
return &tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
// match(text) => bool
|
||||
"match": &tengo.UserFunction{
|
||||
Value: func(args ...tengo.Object) (
|
||||
ret tengo.Object,
|
||||
err error,
|
||||
) {
|
||||
if len(args) != 1 {
|
||||
err = tengo.ErrWrongNumArguments
|
||||
return
|
||||
}
|
||||
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if re.MatchString(s1) {
|
||||
ret = tengo.TrueValue
|
||||
} else {
|
||||
ret = tengo.FalseValue
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
},
|
||||
|
||||
// find(text) => array(array({text:,begin:,end:}))/undefined
|
||||
// find(text, maxCount) => array(array({text:,begin:,end:}))/undefined
|
||||
"find": &tengo.UserFunction{
|
||||
Value: func(args ...tengo.Object) (
|
||||
ret tengo.Object,
|
||||
err error,
|
||||
) {
|
||||
numArgs := len(args)
|
||||
if numArgs != 1 && numArgs != 2 {
|
||||
err = tengo.ErrWrongNumArguments
|
||||
return
|
||||
}
|
||||
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if numArgs == 1 {
|
||||
m := re.FindStringSubmatchIndex(s1)
|
||||
if m == nil {
|
||||
ret = tengo.UndefinedValue
|
||||
return
|
||||
}
|
||||
|
||||
arr := &tengo.Array{}
|
||||
for i := 0; i < len(m); i += 2 {
|
||||
arr.Value = append(arr.Value,
|
||||
&tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
"text": &tengo.String{
|
||||
Value: s1[m[i]:m[i+1]],
|
||||
},
|
||||
"begin": &tengo.Int{
|
||||
Value: int64(m[i]),
|
||||
},
|
||||
"end": &tengo.Int{
|
||||
Value: int64(m[i+1]),
|
||||
},
|
||||
}})
|
||||
}
|
||||
|
||||
ret = &tengo.Array{Value: []tengo.Object{arr}}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
i2, ok := tengo.ToInt(args[1])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
m := re.FindAllStringSubmatchIndex(s1, i2)
|
||||
if m == nil {
|
||||
ret = tengo.UndefinedValue
|
||||
return
|
||||
}
|
||||
|
||||
arr := &tengo.Array{}
|
||||
for _, m := range m {
|
||||
subMatch := &tengo.Array{}
|
||||
for i := 0; i < len(m); i += 2 {
|
||||
subMatch.Value = append(subMatch.Value,
|
||||
&tengo.ImmutableMap{
|
||||
Value: map[string]tengo.Object{
|
||||
"text": &tengo.String{
|
||||
Value: s1[m[i]:m[i+1]],
|
||||
},
|
||||
"begin": &tengo.Int{
|
||||
Value: int64(m[i]),
|
||||
},
|
||||
"end": &tengo.Int{
|
||||
Value: int64(m[i+1]),
|
||||
},
|
||||
}})
|
||||
}
|
||||
|
||||
arr.Value = append(arr.Value, subMatch)
|
||||
}
|
||||
|
||||
ret = arr
|
||||
|
||||
return
|
||||
},
|
||||
},
|
||||
|
||||
// replace(src, repl) => string
|
||||
"replace": &tengo.UserFunction{
|
||||
Value: func(args ...tengo.Object) (
|
||||
ret tengo.Object,
|
||||
err error,
|
||||
) {
|
||||
if len(args) != 2 {
|
||||
err = tengo.ErrWrongNumArguments
|
||||
return
|
||||
}
|
||||
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
s2, ok := tengo.ToString(args[1])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
s, ok := doTextRegexpReplace(re, s1, s2)
|
||||
if !ok {
|
||||
return nil, tengo.ErrStringLimit
|
||||
}
|
||||
|
||||
ret = &tengo.String{Value: s}
|
||||
|
||||
return
|
||||
},
|
||||
},
|
||||
|
||||
// split(text) => array(string)
|
||||
// split(text, maxCount) => array(string)
|
||||
"split": &tengo.UserFunction{
|
||||
Value: func(args ...tengo.Object) (
|
||||
ret tengo.Object,
|
||||
err error,
|
||||
) {
|
||||
numArgs := len(args)
|
||||
if numArgs != 1 && numArgs != 2 {
|
||||
err = tengo.ErrWrongNumArguments
|
||||
return
|
||||
}
|
||||
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string(compatible)",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var i2 = -1
|
||||
if numArgs > 1 {
|
||||
i2, ok = tengo.ToInt(args[1])
|
||||
if !ok {
|
||||
err = tengo.ErrInvalidArgumentType{
|
||||
Name: "second",
|
||||
Expected: "int(compatible)",
|
||||
Found: args[1].TypeName(),
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
arr := &tengo.Array{}
|
||||
for _, s := range re.Split(s1, i2) {
|
||||
arr.Value = append(arr.Value,
|
||||
&tengo.String{Value: s})
|
||||
}
|
||||
|
||||
ret = arr
|
||||
|
||||
return
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Size-limit checking implementation of regexp.ReplaceAllString.
|
||||
func doTextRegexpReplace(re *regexp.Regexp, src, repl string) (string, bool) {
|
||||
idx := 0
|
||||
out := ""
|
||||
for _, m := range re.FindAllStringSubmatchIndex(src, -1) {
|
||||
var exp []byte
|
||||
exp = re.ExpandString(exp, repl, src, m)
|
||||
if len(out)+m[0]-idx+len(exp) > tengo.MaxStringLen {
|
||||
return "", false
|
||||
}
|
||||
out += src[idx:m[0]] + string(exp)
|
||||
idx = m[1]
|
||||
}
|
||||
if idx < len(src) {
|
||||
if len(out)+len(src)-idx > tengo.MaxStringLen {
|
||||
return "", false
|
||||
}
|
||||
out += src[idx:]
|
||||
}
|
||||
return out, true
|
||||
}
|
1135
vendor/github.com/d5/tengo/v2/stdlib/times.go
generated
vendored
Normal file
1135
vendor/github.com/d5/tengo/v2/stdlib/times.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user