1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2025-01-20 19:47:12 +00:00

Shellwords: Simpler error and implementation

This commit is contained in:
diamondburned 2020-12-19 18:02:31 -08:00
parent 3e2814748f
commit e0f051b4c6
2 changed files with 25 additions and 42 deletions

View file

@ -1,48 +1,35 @@
package shellwords
import (
"fmt"
"strings"
)
// WordOffset is the offset from the position cursor to print on the error.
const WordOffset = 7
var escaper = strings.NewReplacer(
"`", "\\`",
"@", "\\@",
"__", "\\_\\_",
"\\", "\\\\",
)
type ErrParse struct {
// ErrMissingClose is returned when the parsed line is missing a closing quote.
type ErrMissingClose struct {
Position int
Words string // joined
}
func (e ErrParse) Error() string {
// Magic number 5.
var a = max(0, e.Position-WordOffset)
var b = min(len(e.Words), e.Position+WordOffset)
var word = e.Words[a:b]
var uidx = e.Position - a
func (e ErrMissingClose) Error() string {
// Underline 7 characters around.
var start = e.Position
errstr := strings.Builder{}
errstr.WriteString("Unexpected quote or escape")
errstr.WriteString("missing quote close")
// Do a bound check.
if uidx+1 > len(word) {
// Invalid.
errstr.WriteString(".")
return errstr.String()
if e.Words[start:] != "" {
errstr.WriteString(": ")
errstr.WriteString(escaper.Replace(e.Words[:start]))
errstr.WriteString("__")
errstr.WriteString(escaper.Replace(e.Words[start:]))
errstr.WriteString("__")
}
// Write the pre-underline part.
fmt.Fprintf(
&errstr, ": %s__%s__",
escaper.Replace(word[:uidx]),
escaper.Replace(string(word[uidx:])),
)
return errstr.String()
}
@ -117,7 +104,7 @@ func Parse(line string) ([]string, error) {
}
if escaped || singleQuoted || doubleQuoted {
return args, &ErrParse{
return args, ErrMissingClose{
Position: cursor + buf.Len(),
Words: strings.Join(args, " "),
}
@ -133,17 +120,3 @@ func isSpace(r rune) bool {
}
return false
}
func min(i, j int) int {
if i < j {
return i
}
return j
}
func max(i, j int) int {
if i < j {
return j
}
return i
}

View file

@ -14,7 +14,17 @@ type wordsTest struct {
func TestParse(t *testing.T) {
var tests = []wordsTest{
{
`this is a "test"`,
"",
nil,
false,
},
{
"'",
nil,
true,
},
{
`this is a "te""st"`,
[]string{"this", "is", "a", "test"},
false,
},