98 lines
1.8 KiB
Go
98 lines
1.8 KiB
Go
|
package config
|
||
|
|
||
|
import "fmt"
|
||
|
import "strings"
|
||
|
// import "unicode"
|
||
|
|
||
|
var escapeCodeToRune = map[rune] rune {
|
||
|
'\\': '\\',
|
||
|
'a': '\a',
|
||
|
'b': '\b',
|
||
|
't': '\t',
|
||
|
'n': '\n',
|
||
|
'v': '\v',
|
||
|
'f': '\f',
|
||
|
'r': '\r',
|
||
|
'"': '"',
|
||
|
}
|
||
|
|
||
|
var runeToEscapeCode = map[rune] rune { }
|
||
|
func init () {
|
||
|
for code, char := range escapeCodeToRune {
|
||
|
runeToEscapeCode[char] = code
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func escape (str string) string {
|
||
|
builder := strings.Builder { }
|
||
|
for _, char := range str {
|
||
|
code, escaped := runeToEscapeCode[char]
|
||
|
switch {
|
||
|
case escaped:
|
||
|
fmt.Fprintf(&builder, "\\%c", code)
|
||
|
// case !unicode.IsPrint(char):
|
||
|
// fmt.Fprintf(&builder, "\\%o", char)
|
||
|
default:
|
||
|
builder.WriteRune(char)
|
||
|
}
|
||
|
}
|
||
|
return builder.String()
|
||
|
}
|
||
|
|
||
|
func unescape (str string) (string, bool) {
|
||
|
runes := []rune(str)
|
||
|
builder := strings.Builder { }
|
||
|
|
||
|
end := func () bool {
|
||
|
return len(runes) < 1
|
||
|
}
|
||
|
next := func () {
|
||
|
if !end() { runes = runes[1:] }
|
||
|
}
|
||
|
|
||
|
for !end() {
|
||
|
if runes[0] == '\\' {
|
||
|
if end() { return "", false }
|
||
|
next()
|
||
|
char, isEscape := escapeCodeToRune[runes[0]]
|
||
|
switch {
|
||
|
case isEscape:
|
||
|
builder.WriteRune(char)
|
||
|
next()
|
||
|
// case isOctalDigit(runes[0]):
|
||
|
// char = 0
|
||
|
// for !end() && isOctalDigit(runes[0]) {
|
||
|
// char *= 8
|
||
|
// char += runes[0] - '0'
|
||
|
// next()
|
||
|
// }
|
||
|
// builder.WriteRune(char)
|
||
|
default:
|
||
|
return "", false
|
||
|
}
|
||
|
} else {
|
||
|
builder.WriteRune(runes[0])
|
||
|
next()
|
||
|
}
|
||
|
}
|
||
|
return builder.String(), true
|
||
|
}
|
||
|
|
||
|
func unquote (str string) (string, bool) {
|
||
|
if len(str) < 2 { return "", false }
|
||
|
if firstRune(str) != '"' { return "", false }
|
||
|
if str[len(str) - 1] != '"' { return "", false }
|
||
|
return str[1:len(str) - 1], true
|
||
|
}
|
||
|
|
||
|
func isOctalDigit (char rune) bool {
|
||
|
return char >= '0' && char <= '7'
|
||
|
}
|
||
|
|
||
|
func firstRune (str string) rune {
|
||
|
for _, char := range str {
|
||
|
return char
|
||
|
}
|
||
|
return 0
|
||
|
}
|