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  }