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 }