update deps

This commit is contained in:
Andrey Nering
2017-06-24 16:00:10 -03:00
parent f8a5825083
commit 7e06ba1728
18 changed files with 289 additions and 204 deletions

View File

@@ -1,14 +1,21 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
The MIT License (MIT)
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Copyright (c) 2013 TOML authors
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -775,7 +775,7 @@ func lexDatetime(lx *lexer) stateFn {
return lexDatetime
}
switch r {
case '-', 'T', ':', '.', 'Z':
case '-', 'T', ':', '.', 'Z', '+':
return lexDatetime
}

View File

@@ -17,7 +17,7 @@ func isBuiltin(name string) bool {
switch name {
case "true", ":", "false", "exit", "set", "shift", "unset",
"echo", "printf", "break", "continue", "pwd", "cd",
"wait", "builtin", "trap", "type", "source", "command",
"wait", "builtin", "trap", "type", "source", ".", "command",
"pushd", "popd", "umask", "alias", "unalias", "fg", "bg",
"getopts", "eval", "test", "[":
return true
@@ -45,7 +45,12 @@ func (r *Runner) builtinCode(pos syntax.Pos, name string, args []string) int {
r.lastExit()
return r.exit
case "set":
r.args = args
rest, err := r.FromArgs(args...)
if err != nil {
r.errf("set: %v", err)
return 2
}
r.Params = rest
case "shift":
n := 1
switch len(args) {
@@ -60,17 +65,18 @@ func (r *Runner) builtinCode(pos syntax.Pos, name string, args []string) int {
r.errf("usage: shift [n]\n")
return 2
}
if len(r.args) < n {
n = len(r.args)
if n >= len(r.Params) {
r.Params = nil
} else {
r.Params = r.Params[n:]
}
r.args = r.args[n:]
case "unset":
for _, arg := range args {
r.delVar(arg)
}
case "echo":
newline := true
opts:
echoOpts:
for len(args) > 0 {
switch args[0] {
case "-n":
@@ -80,7 +86,7 @@ func (r *Runner) builtinCode(pos syntax.Pos, name string, args []string) int {
// exactly what is the difference in
// what we write?
default:
break opts
break echoOpts
}
args = args[1:]
}
@@ -206,6 +212,27 @@ func (r *Runner) builtinCode(pos syntax.Pos, name string, args []string) int {
r2.File = file
r2.Run()
return r2.exit
case "source", ".":
if len(args) < 1 {
r.runErr(pos, "source: need filename")
}
f, err := os.Open(args[0])
if err != nil {
r.errf("eval: %v\n", err)
return 1
}
defer f.Close()
p := syntax.NewParser()
file, err := p.Parse(f, args[0])
if err != nil {
r.errf("eval: %v\n", err)
return 1
}
r2 := *r
r2.Params = args[1:]
r2.File = file
r2.Run()
return r2.exit
case "[":
if len(args) == 0 || args[len(args)-1] != "]" {
r.runErr(pos, "[: missing matching ]")
@@ -223,7 +250,7 @@ func (r *Runner) builtinCode(pos syntax.Pos, name string, args []string) int {
p.next()
expr := p.classicTest("[", false)
return oneIf(r.bashTest(expr) == "")
case "trap", "source", "command", "pushd", "popd",
case "trap", "command", "pushd", "popd",
"umask", "alias", "unalias", "fg", "bg", "getopts":
r.runErr(pos, "unhandled builtin: %s", name)
}

View File

@@ -44,6 +44,11 @@ type Runner struct {
// process's current directory.
Dir string
// Params are the current parameters, e.g. from running a shell
// file or calling a function. Accessible via the $@/$* family
// of vars.
Params []string
// Separate maps, note that bash allows a name to be both a var
// and a func simultaneously
vars map[string]varValue
@@ -52,9 +57,6 @@ type Runner struct {
// like vars, but local to a cmd i.e. "foo=bar prog args..."
cmdVars map[string]varValue
// Current arguments, if executing a function
args []string
// >0 to break or continue out of N enclosing loops
breakEnclosing, contnEnclosing int
@@ -71,6 +73,8 @@ type Runner struct {
// Context can be used to cancel the interpreter before it finishes
Context context.Context
stopOnCmdErr bool // set -e
}
// varValue can hold a string, an indexed array ([]string) or an
@@ -184,6 +188,33 @@ func (r *Runner) setFunc(name string, body *syntax.Stmt) {
r.funcs[name] = body
}
// FromArgs populates the shell options and returns the remaining
// arguments. For example, running FromArgs("-e", "--", "foo") will set
// the "-e" option and return []string{"foo"}.
//
// This is similar to what the interpreter's "set" builtin does.
func (r *Runner) FromArgs(args ...string) ([]string, error) {
opts:
for len(args) > 0 {
opt := args[0]
if opt == "" || (opt[0] != '-' && opt[0] != '+') {
break
}
enable := opt[0] == '-'
switch opt[1:] {
case "-":
args = args[1:]
break opts
case "e":
r.stopOnCmdErr = enable
default:
return nil, fmt.Errorf("invalid option: %q", opt)
}
args = args[1:]
}
return args, nil
}
// Run starts the interpreter and returns any error.
func (r *Runner) Run() error {
if r.Context == nil {
@@ -531,6 +562,9 @@ func (r *Runner) cmd(cm syntax.Command) {
default:
r.runErr(cm.Pos(), "unhandled command node: %T", x)
}
if r.exit != 0 && r.stopOnCmdErr {
r.lastExit()
}
}
func (r *Runner) stmts(stmts []*syntax.Stmt) {
@@ -581,7 +615,11 @@ func (r *Runner) redir(rd *syntax.Redirect) (io.Closer, error) {
case syntax.RdrOut, syntax.RdrAll:
mode = os.O_RDWR | os.O_CREATE | os.O_TRUNC
}
f, err := os.OpenFile(arg, mode, 0644)
path := arg
if !filepath.IsAbs(path) {
path = filepath.Join(r.Dir, path)
}
f, err := os.OpenFile(path, mode, 0644)
if err != nil {
// TODO: print to stderr?
return nil, err
@@ -719,10 +757,10 @@ func (r *Runner) wordFields(wps []syntax.WordPart, quoted bool) [][]fieldPart {
func (r *Runner) call(pos syntax.Pos, name string, args []string) {
if body := r.funcs[name]; body != nil {
// stack them to support nested func calls
oldArgs := r.args
r.args = args
oldParams := r.Params
r.Params = args
r.stmt(body)
r.args = oldArgs
r.Params = oldParams
return
}
if isBuiltin(name) {

View File

@@ -17,7 +17,7 @@ func (r *Runner) quotedElems(pe *syntax.ParamExp) []string {
return nil
}
if pe.Param.Value == "@" {
return r.args
return r.Params
}
w, _ := pe.Index.(*syntax.Word)
if w == nil || len(w.Parts) != 1 {
@@ -41,15 +41,15 @@ func (r *Runner) paramExp(pe *syntax.ParamExp) string {
set := false
switch name {
case "#":
val = strconv.Itoa(len(r.args))
val = strconv.Itoa(len(r.Params))
case "*", "@":
val = strings.Join(r.args, " ")
val = strings.Join(r.Params, " ")
case "?":
val = strconv.Itoa(r.exit)
default:
if n, err := strconv.Atoi(name); err == nil {
if i := n - 1; i < len(r.args) {
val, set = r.args[i], true
if i := n - 1; i < len(r.Params) {
val, set = r.Params[i], true
}
} else {
val, set = r.lookupVar(name)