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