forked from lug/matterbridge
		
	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
	 Wim
					Wim