github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/core/elvish/eval/builtin_fn_misc.go (about) 1 package eval 2 3 // Builtin functions. 4 5 import ( 6 "fmt" 7 "io/ioutil" 8 "path/filepath" 9 "time" 10 "unicode/utf8" 11 12 "github.com/u-root/u-root/cmds/core/elvish/eval/vals" 13 "github.com/u-root/u-root/cmds/core/elvish/parse" 14 ) 15 16 // Builtins that have not been put into their own groups go here. 17 18 func init() { 19 addBuiltinFns(map[string]interface{}{ 20 "-source": source, 21 }) 22 } 23 24 func nop(opts RawOptions, args ...interface{}) { 25 // Do nothing 26 } 27 28 func kindOf(fm *Frame, args ...interface{}) { 29 out := fm.ports[1].Chan 30 for _, a := range args { 31 out <- vals.Kind(a) 32 } 33 } 34 35 func constantly(args ...interface{}) Callable { 36 // XXX Repr of this fn is not right 37 return NewBuiltinFn( 38 "created by constantly", 39 func(fm *Frame) { 40 out := fm.ports[1].Chan 41 for _, v := range args { 42 out <- v 43 } 44 }, 45 ) 46 } 47 48 func resolve(fm *Frame, head string) string { 49 // Emulate static resolution of a command head. This needs to be kept in 50 // sync with (*compiler).form. 51 52 _, special := builtinSpecials[head] 53 if special { 54 return "special" 55 } else { 56 explode, ns, name := ParseVariableRef(head) 57 if !explode && fm.ResolveVar(ns, name+FnSuffix) != nil { 58 return "$" + head + FnSuffix 59 } else { 60 return "(external " + parse.Quote(head) + ")" 61 } 62 } 63 } 64 65 func source(fm *Frame, fname string) error { 66 path, err := filepath.Abs(fname) 67 if err != nil { 68 return err 69 } 70 code, err := readFileUTF8(path) 71 if err != nil { 72 return err 73 } 74 n, err := parse.Parse(fname, code) 75 if err != nil { 76 return err 77 } 78 scriptGlobal := fm.local.static() 79 for name := range fm.up.static() { 80 scriptGlobal.set(name) 81 } 82 op, err := compile(fm.Builtin.static(), 83 scriptGlobal, n, NewScriptSource(fname, path, code)) 84 if err != nil { 85 return err 86 } 87 return fm.Eval(op) 88 } 89 90 func readFileUTF8(fname string) (string, error) { 91 bytes, err := ioutil.ReadFile(fname) 92 if err != nil { 93 return "", err 94 } 95 if !utf8.Valid(bytes) { 96 return "", fmt.Errorf("%s: source is not valid UTF-8", fname) 97 } 98 return string(bytes), nil 99 } 100 101 func sleep(fm *Frame, t float64) error { 102 d := time.Duration(float64(time.Second) * t) 103 select { 104 case <-fm.Interrupts(): 105 return ErrInterrupted 106 case <-time.After(d): 107 return nil 108 } 109 } 110 111 func _time(fm *Frame, f Callable) error { 112 t0 := time.Now() 113 err := f.Call(fm, NoArgs, NoOpts) 114 t1 := time.Now() 115 116 dt := t1.Sub(t0) 117 fmt.Fprintln(fm.ports[1].File, dt) 118 119 return err 120 }