-
Notifications
You must be signed in to change notification settings - Fork 0
/
escapeparser.go
73 lines (57 loc) · 1.19 KB
/
escapeparser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package escaper
import (
"unicode/utf8"
)
func Parse(str string) []string {
const quote = "\""
const empty = ""
const space = " "
const slash = "\\"
acc := empty
var split []string
inQuotes := false
completeToken := func() {
if acc != empty {
split = append(split, acc)
acc = empty
}
}
addToToken := func(curr string) {
acc = acc + curr
}
for i, w := 0, 0; i < len(str); {
curr, width := runeAt(str[i:])
if i + width < len(str) {
next, nextWidth := runeAt(str[i+width:])
// an escaped quotation inside a quotation block
if inQuotes && curr == slash && next == quote {
addToToken(curr + next)
// add both escaped values, skip to next
i = i + width + nextWidth
continue
}
}
if curr == quote {
if inQuotes {
completeToken()
}
inQuotes = !inQuotes
} else if inQuotes {
addToToken(curr)
} else if curr != space && !inQuotes {
addToToken(curr)
} else if curr == space && acc != empty {
completeToken()
}
w = width
i += w
}
// any remaining text
completeToken()
return split
}
func runeAt(str string) (string, int) {
r, width := utf8.DecodeRuneInString(str)
runeStr := string(r)
return runeStr, width
}