Last change
on this file since 67 was 67, checked in by Izuru Yakumo, 23 months ago |
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@…>
|
File size:
1.7 KB
|
Line | |
---|
1 | package syntax
|
---|
2 |
|
---|
3 | import (
|
---|
4 | "bytes"
|
---|
5 | "strconv"
|
---|
6 | "strings"
|
---|
7 | "unicode"
|
---|
8 | )
|
---|
9 |
|
---|
10 | func Escape(input string) string {
|
---|
11 | b := &bytes.Buffer{}
|
---|
12 | for _, r := range input {
|
---|
13 | escape(b, r, false)
|
---|
14 | }
|
---|
15 | return b.String()
|
---|
16 | }
|
---|
17 |
|
---|
18 | const meta = `\.+*?()|[]{}^$# `
|
---|
19 |
|
---|
20 | func escape(b *bytes.Buffer, r rune, force bool) {
|
---|
21 | if unicode.IsPrint(r) {
|
---|
22 | if strings.IndexRune(meta, r) >= 0 || force {
|
---|
23 | b.WriteRune('\\')
|
---|
24 | }
|
---|
25 | b.WriteRune(r)
|
---|
26 | return
|
---|
27 | }
|
---|
28 |
|
---|
29 | switch r {
|
---|
30 | case '\a':
|
---|
31 | b.WriteString(`\a`)
|
---|
32 | case '\f':
|
---|
33 | b.WriteString(`\f`)
|
---|
34 | case '\n':
|
---|
35 | b.WriteString(`\n`)
|
---|
36 | case '\r':
|
---|
37 | b.WriteString(`\r`)
|
---|
38 | case '\t':
|
---|
39 | b.WriteString(`\t`)
|
---|
40 | case '\v':
|
---|
41 | b.WriteString(`\v`)
|
---|
42 | default:
|
---|
43 | if r < 0x100 {
|
---|
44 | b.WriteString(`\x`)
|
---|
45 | s := strconv.FormatInt(int64(r), 16)
|
---|
46 | if len(s) == 1 {
|
---|
47 | b.WriteRune('0')
|
---|
48 | }
|
---|
49 | b.WriteString(s)
|
---|
50 | break
|
---|
51 | }
|
---|
52 | b.WriteString(`\u`)
|
---|
53 | b.WriteString(strconv.FormatInt(int64(r), 16))
|
---|
54 | }
|
---|
55 | }
|
---|
56 |
|
---|
57 | func Unescape(input string) (string, error) {
|
---|
58 | idx := strings.IndexRune(input, '\\')
|
---|
59 | // no slashes means no unescape needed
|
---|
60 | if idx == -1 {
|
---|
61 | return input, nil
|
---|
62 | }
|
---|
63 |
|
---|
64 | buf := bytes.NewBufferString(input[:idx])
|
---|
65 | // get the runes for the rest of the string -- we're going full parser scan on this
|
---|
66 |
|
---|
67 | p := parser{}
|
---|
68 | p.setPattern(input[idx+1:])
|
---|
69 | for {
|
---|
70 | if p.rightMost() {
|
---|
71 | return "", p.getErr(ErrIllegalEndEscape)
|
---|
72 | }
|
---|
73 | r, err := p.scanCharEscape()
|
---|
74 | if err != nil {
|
---|
75 | return "", err
|
---|
76 | }
|
---|
77 | buf.WriteRune(r)
|
---|
78 | // are we done?
|
---|
79 | if p.rightMost() {
|
---|
80 | return buf.String(), nil
|
---|
81 | }
|
---|
82 |
|
---|
83 | r = p.moveRightGetChar()
|
---|
84 | for r != '\\' {
|
---|
85 | buf.WriteRune(r)
|
---|
86 | if p.rightMost() {
|
---|
87 | // we're done, no more slashes
|
---|
88 | return buf.String(), nil
|
---|
89 | }
|
---|
90 | // keep scanning until we get another slash
|
---|
91 | r = p.moveRightGetChar()
|
---|
92 | }
|
---|
93 | }
|
---|
94 | }
|
---|
Note:
See
TracBrowser
for help on using the repository browser.