diff options
Diffstat (limited to 'vendor/github.com/d5/tengo/stdlib/fmt.go')
-rw-r--r-- | vendor/github.com/d5/tengo/stdlib/fmt.go | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/vendor/github.com/d5/tengo/stdlib/fmt.go b/vendor/github.com/d5/tengo/stdlib/fmt.go new file mode 100644 index 00000000..9c75fc33 --- /dev/null +++ b/vendor/github.com/d5/tengo/stdlib/fmt.go @@ -0,0 +1,116 @@ +package stdlib + +import ( + "fmt" + + "github.com/d5/tengo" + "github.com/d5/tengo/objects" +) + +var fmtModule = map[string]objects.Object{ + "print": &objects.UserFunction{Name: "print", Value: fmtPrint}, + "printf": &objects.UserFunction{Name: "printf", Value: fmtPrintf}, + "println": &objects.UserFunction{Name: "println", Value: fmtPrintln}, + "sprintf": &objects.UserFunction{Name: "sprintf", Value: fmtSprintf}, +} + +func fmtPrint(args ...objects.Object) (ret objects.Object, err error) { + printArgs, err := getPrintArgs(args...) + if err != nil { + return nil, err + } + + _, _ = fmt.Print(printArgs...) + + return nil, nil +} + +func fmtPrintf(args ...objects.Object) (ret objects.Object, err error) { + numArgs := len(args) + if numArgs == 0 { + return nil, objects.ErrWrongNumArguments + } + + format, ok := args[0].(*objects.String) + if !ok { + return nil, objects.ErrInvalidArgumentType{ + Name: "format", + Expected: "string", + Found: args[0].TypeName(), + } + } + if numArgs == 1 { + fmt.Print(format) + return nil, nil + } + + formatArgs := make([]interface{}, numArgs-1, numArgs-1) + for idx, arg := range args[1:] { + formatArgs[idx] = objects.ToInterface(arg) + } + + fmt.Printf(format.Value, formatArgs...) + + return nil, nil +} + +func fmtPrintln(args ...objects.Object) (ret objects.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 ...objects.Object) (ret objects.Object, err error) { + numArgs := len(args) + if numArgs == 0 { + return nil, objects.ErrWrongNumArguments + } + + format, ok := args[0].(*objects.String) + if !ok { + return nil, objects.ErrInvalidArgumentType{ + Name: "format", + Expected: "string", + Found: args[0].TypeName(), + } + } + if numArgs == 1 { + return format, nil // okay to return 'format' directly as String is immutable + } + + formatArgs := make([]interface{}, numArgs-1, numArgs-1) + for idx, arg := range args[1:] { + formatArgs[idx] = objects.ToInterface(arg) + } + + s := fmt.Sprintf(format.Value, formatArgs...) + + if len(s) > tengo.MaxStringLen { + return nil, objects.ErrStringLimit + } + + return &objects.String{Value: s}, nil +} + +func getPrintArgs(args ...objects.Object) ([]interface{}, error) { + var printArgs []interface{} + l := 0 + for _, arg := range args { + s, _ := objects.ToString(arg) + slen := len(s) + if l+slen > tengo.MaxStringLen { // make sure length does not exceed the limit + return nil, objects.ErrStringLimit + } + l += slen + + printArgs = append(printArgs, s) + } + + return printArgs, nil +} |