Ejemplo n.º 1
0
// simpleCommand
func (p *Parser) simpleCommand() Node {
	tok := p.next()
	assignments := map[string]Arg{}
	args := []Arg{}
	startLine := tok.LineNo
	assignmentAllowed := true

	p.lexer.CheckAlias = true
	p.lexer.IgnoreNewlines = false
	p.lexer.CheckKeyword = false

OuterLoop:
	for {
		switch tok.Tok {
		case TWord:
			if assignmentAllowed && variables.IsAssignment(tok.Val) {
				parts := strings.SplitN(tok.Val, "=", 2)
				assignments[parts[0]] = Arg{Raw: parts[1], Subs: tok.Subs, Quoted: tok.Quoted}
				p.lexer.CheckAlias = false
			} else {
				assignmentAllowed = false
				args = append(args, Arg{Raw: tok.Val, Subs: tok.Subs, Quoted: tok.Quoted})
			}
		case TLeftParen:
			if len(args) == 1 && len(assignments) == 0 {
				p.expect(TRightParen)
				name := args[0]
				if !variables.IsGoodName(name.Raw) {
					panic("Bad function name: " + name.Raw)
				}
				p.lexer.CheckAlias = true
				p.lexer.IgnoreNewlines = true
				p.lexer.CheckKeyword = true
				n := NodeFunction{}
				n.Body = p.command()
				n.Name = name.Raw
				return n
			}
			fallthrough
		default:
			p.backup()
			break OuterLoop
		}
		tok = p.next()
	}

	n := NodeCommand{}
	n.Assign = assignments
	n.Args = args
	n.LineNo = startLine
	return n
}
Ejemplo n.º 2
0
// parseFor return a NodeFor which contains the body of the for loop, the
// variable to assign into and a list of things to assign.
//
// XXX: This does not follow the shell spec, which allows omitting the in
// and then defaults to using all the set positional variables. E.g $1, $2
func parseFor(p *Parser) Node {
	tok := p.next()
	if tok.Tok != TWord || tok.Quoted || !variables.IsGoodName(tok.Val) {
		p.log.Error(fmt.Sprintf("Bad for loop variable name", kisslog.Attrs{
			"name": tok.Val,
			"line": tok.LineNo,
		}))
	}

	n := NodeFor{Args: []Arg{}}
	n.LoopVar = tok.Val

	p.lexer.CheckAlias = true
	p.lexer.IgnoreNewlines = false
	p.lexer.CheckKeyword = true

	p.expect(TIn)
	for {
		tok = p.next()
		if tok.Tok != TWord {
			p.backup()
			p.expect(TNewLine, TSemicolon)
			break
		}
		n.Args = append(n.Args, Arg{Raw: tok.Val, Subs: tok.Subs, Quoted: tok.Quoted})
	}

	p.lexer.CheckAlias = true
	p.lexer.IgnoreNewlines = true
	p.lexer.CheckKeyword = true

	p.expect(TDo)
	n.Body = p.list(IgnoreNewlines)
	p.expect(TDone)

	return n
}