From 5542bde1ac7888e09cbefa1766290fec84a1c9c1 Mon Sep 17 00:00:00 2001 From: Alem Rakovic Date: Tue, 4 Apr 2023 21:03:52 +0200 Subject: [PATCH] Add the ability to exclude specific separators from the parsing algorithm --- README.md | 5 +++++ shellwords.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/README.md b/README.md index bdd5319..741469d 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,11 @@ args, err := p.Parse("./foo `echo $SHELL`") // args should be ["./foo", "/bin/bash"] ``` +```go +p := shellwords.NewParser() +p.SetExcludeSeparators('\t',';') +``` + # Thanks This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine). diff --git a/shellwords.go b/shellwords.go index 376e9e5..bd62789 100644 --- a/shellwords.go +++ b/shellwords.go @@ -99,6 +99,7 @@ type Parser struct { ParseBacktick bool Position int Dir string + excludedSep []rune // If ParseEnv is true, use this for getenv. // If nil, use os.Getenv. @@ -111,6 +112,7 @@ func NewParser() *Parser { ParseBacktick: ParseBacktick, Position: 0, Dir: "", + excludedSep: []rune{}, } } @@ -122,6 +124,27 @@ const ( argQuoted ) +// isExcluded checks if separator should be ignored +func (p *Parser) isExcluded(r rune) bool { + for _, v := range p.excludedSep { + if v == r { + return true + } + } + return false +} + +// SetExcludeSeparators indictes the parser to ignore provided separators when parsing +// example: parser.SetExcludeSeparators(';','\t') +func (p *Parser) SetExcludeSeparators(r ...rune) { + p.excludedSep = r +} + +// ExcludedSeparators returns excluded separators +func (p *Parser) ExcludedSeparators() []rune { + return p.excludedSep +} + func (p *Parser) Parse(line string) ([]string, error) { args := []string{} buf := "" @@ -157,6 +180,15 @@ loop: continue } + if p.isExcluded(r) { + got = argSingle + buf += string(r) + if backQuote || dollarQuote { + backtick += string(r) + } + continue + } + if isSpace(r) { if singleQuoted || doubleQuoted || backQuote || dollarQuote { buf += string(r)