package shell import ( "io" "log" ) type Statement struct { BaseToken } func (s *Statement) Evaluate(state State, stdin io.Reader, stdout io.Writer, stderr io.Writer) uint8 { if len(s.Tokens()) == 0 { return 0 } var command string var arguments []string for _, token := range s.Tokens() { var values []string if expand, ok := token.(Expandable); ok { values = state.Expand(expand, stdin, stdout) } else if _, isWhitespace := token.(*Whitespace); isWhitespace { continue } else { logstr := "shell: Unexpected token: " + token.String() log.Println(logstr) stderr.Write([]byte(logstr)) return 2 } if command == "" { command = values[0] if len(values) > 1 { arguments = values[1:] } continue } arguments = append(arguments, values...) } return state.ExecuteCommand(command, arguments, stdin, stdout, stderr) } type StatementParameters struct{} func (p *StatementParameters) SubParsers() []Parser { return []Parser{ &BaseParser{ parameters: &QuoteParameters{}, }, &BaseParser{ parameters: &SingleQuoteParameters{}, }, &BaseParser{ parameters: &WordParameters{}, }, &BaseParser{ parameters: &DollarParameters{}, }, &BaseParser{ parameters: &PipeParameters{}, }, &BaseParser{ parameters: &SubshellParameters{}, }, &BaseParser{ parameters: &BlockParameters{}, }, &BaseParser{ parameters: &WhitespaceParameters{}, }, } } func (p *StatementParameters) Supports(charsBefore []rune, r rune) bool { return true } func (p *StatementParameters) MakeToken() Token { return &Statement{} } func (p *StatementParameters) ShouldLeave(charsBefore []rune, r rune) bool { if r == '\n' || r == ';' || r == ')' { return countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *StatementParameters) Leave(i *CharIterator) error { if i.Current() == '\n' || i.Current() == ')' { return i.Previous() } return nil }