nasin/config/escape.go

98 lines
1.8 KiB
Go
Raw Normal View History

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
}