package shell import ( "io" "strings" ) type QuoteParameters struct{} func (p *QuoteParameters) SubParsers() []Parser { return []Parser{ &BaseParser{ parameters: &DollarParameters{}, }, &BaseParser{ parameters: &BacktickParameters{}, }, &BaseParser{ parameters: &CharParserParameters{}, }, } } func (p *QuoteParameters) Enter(i *CharIterator) error { return i.Next() } func (p *QuoteParameters) Supports(charsBefore []rune, r rune) bool { if r == '"' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *QuoteParameters) ShouldLeave(charsBefore []rune, r rune) bool { if r == '"' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *QuoteParameters) MakeToken() Token { return &Quote{} } type Quote struct { BaseToken } func (q *Quote) Expand(state State, stdin io.Reader, stderr io.Writer) ([]string, uint8) { var retcode uint8 var str string for _, token := range q.Tokens() { if expand, ok := token.(Expandable); ok { var expansion []string expansion, retcode = expand.Expand(state, stdin, stderr) str += strings.Join(expansion, "") continue } str += token.String() } return []string{str}, retcode } type SingleQuoteParameters struct { QuoteParameters } type SingleQuote struct { BaseToken } func (p *SingleQuoteParameters) Supports(charsBefore []rune, r rune) bool { if r == '\'' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false } func (p *SingleQuoteParameters) ShouldLeave(charsBefore []rune, r rune) bool { if r == '\'' { return len(charsBefore) == 0 || countBackslashSuffixes(charsBefore)%2 == 0 } return false }