This repository has been archived by the owner on Jan 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
quoting.go
114 lines (101 loc) · 2.02 KB
/
quoting.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package arff
import (
"strings"
"unicode/utf8"
)
const quoteRune = '\''
// Inspired by https://golang.org/src/strconv/quote.go
// Copyright 2009 The Go Authors. All rights reserved.
func quote(s string) string {
s = strings.TrimSpace(s)
if !stringNeedsQuotes(s) {
return s
}
buf := make([]rune, 0, 3*len(s)/2) // avoid reallocations
buf = append(buf, quoteRune)
for _, r := range s {
switch r {
case quoteRune, '\\':
buf = append(buf, '\\', r)
case '\a':
buf = append(buf, '\\', 'a')
case '\b':
buf = append(buf, '\\', 'b')
case '\f':
buf = append(buf, '\\', 'f')
case '\n':
buf = append(buf, '\\', 'n')
case '\r':
buf = append(buf, '\\', 'r')
case '\t':
buf = append(buf, '\\', 't')
case '\v':
buf = append(buf, '\\', 'v')
default:
buf = append(buf, r)
}
}
buf = append(buf, quoteRune)
return string(buf)
}
func unquoteAll(sl []string) []string {
for i, s := range sl {
sl[i] = unquote(s)
}
return sl
}
func unquote(s string) string {
s = strings.TrimSpace(s)
l := len(s)
if l < 2 || s[0] != quoteRune || s[l-1] != quoteRune {
return s
}
buf := make([]rune, 0, l-2)
for pos := 1; pos < l-1; {
r1, w1 := utf8.DecodeRuneInString(s[pos:])
pos += w1
switch r1 {
case '\\':
r2, w2 := utf8.DecodeRuneInString(s[pos:])
pos += w2
switch r2 {
case quoteRune, '\\':
buf = append(buf, r2)
case 'a':
buf = append(buf, '\a')
case 'b':
buf = append(buf, '\b')
case 'f':
buf = append(buf, '\f')
case 'n':
buf = append(buf, '\n')
case 'r':
buf = append(buf, '\r')
case 't':
buf = append(buf, '\t')
case 'v':
buf = append(buf, '\v')
default:
buf = append(buf, r1, r2)
}
default:
buf = append(buf, r1)
}
}
return strings.TrimSpace(string(buf))
}
func stringNeedsQuotes(s string) bool {
if s == "" {
return false
}
if s == "?" {
return true
}
for _, r := range s {
switch r {
case ' ', '"', '\'', '%', '{', '}', '\a', '\b', '\f', '\n', '\r', '\t', '\v':
return true
}
}
return false
}