98 lines
1.7 KiB
Go
98 lines
1.7 KiB
Go
package util
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func InterpretString(in string) (string, error) {
|
|
in = in[1 : len(in)-1]
|
|
sb := strings.Builder{}
|
|
s := []rune(in)
|
|
for i := 0; i < len(s); {
|
|
r := s[i]
|
|
if r == '\\' {
|
|
if i == len(s)-1 {
|
|
return "", errors.New("illegal escape character")
|
|
}
|
|
switch s[i+1] {
|
|
case 'a':
|
|
sb.WriteRune('\a')
|
|
i += 2
|
|
break
|
|
case 'b':
|
|
sb.WriteRune('\b')
|
|
i += 2
|
|
break
|
|
case 'f':
|
|
sb.WriteRune('\f')
|
|
i += 2
|
|
break
|
|
case 'n':
|
|
sb.WriteRune('\n')
|
|
i += 2
|
|
break
|
|
case 'r':
|
|
sb.WriteRune('\r')
|
|
i += 2
|
|
break
|
|
case 't':
|
|
sb.WriteRune('\t')
|
|
i += 2
|
|
break
|
|
case 'v':
|
|
sb.WriteRune('\v')
|
|
i += 2
|
|
break
|
|
case '\\':
|
|
sb.WriteRune('\\')
|
|
i += 2
|
|
break
|
|
case '"':
|
|
sb.WriteRune('"')
|
|
i += 2
|
|
break
|
|
case 'u':
|
|
sub := s[i+2 : i+6]
|
|
n, err := strconv.ParseInt(string(sub), 16, 64)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
sb.WriteRune(rune(n))
|
|
i += 6
|
|
case 'U':
|
|
sub := s[i+2 : i+10]
|
|
n, err := strconv.ParseInt(string(sub), 16, 64)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
sb.WriteRune(rune(n))
|
|
i += 10
|
|
case '0', '1', '2', '3', '4', '5', '6', '7':
|
|
sub := s[i+1 : i+4]
|
|
n, err := strconv.ParseInt(string(sub), 8, 64)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
sb.WriteRune(rune(n))
|
|
i += 4
|
|
case 'x':
|
|
sub := s[i+2 : i+4]
|
|
n, err := strconv.ParseInt(string(sub), 16, 64)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
sb.WriteRune(rune(n))
|
|
i += 4
|
|
default:
|
|
return "", errors.New("could not parse escape character")
|
|
}
|
|
} else {
|
|
sb.WriteRune(r)
|
|
i++
|
|
}
|
|
}
|
|
return sb.String(), nil
|
|
}
|