(c LexItem)
| 71 | var errorInvalidString = errors.New("invalid string") |
| 72 | |
| 73 | func stringValue(c LexItem) (string, error) { |
| 74 | v := c.Val |
| 75 | |
| 76 | if len(v) < 2 || v[0] != v[len(v)-1] { |
| 77 | return "", errorInvalidString |
| 78 | } |
| 79 | |
| 80 | d := v[0] |
| 81 | m := len(v) - 2 |
| 82 | |
| 83 | s := "" |
| 84 | i := 0 |
| 85 | for { |
| 86 | i++ |
| 87 | if i > m { |
| 88 | break |
| 89 | } |
| 90 | |
| 91 | if v[i] == '\\' { |
| 92 | if i+1 > m { |
| 93 | return "", errorInvalidString |
| 94 | } |
| 95 | |
| 96 | var x rune |
| 97 | |
| 98 | switch v[i+1] { |
| 99 | case '\\': // \\ A backslash (\) character |
| 100 | x = '\\' |
| 101 | case '0': // \0 An ASCII NUL (X'00') character |
| 102 | x = 0 // null byte |
| 103 | case '\'': // \' A single quote (') character |
| 104 | x = '\'' |
| 105 | case '"': // \" A double quote (") character |
| 106 | x = '"' |
| 107 | case 'b': // \b A backspace character |
| 108 | x = 'b' |
| 109 | case 'n': // \n A newline (linefeed) character |
| 110 | x = 'n' |
| 111 | case 'r': // \r A carriage return character |
| 112 | x = 'r' |
| 113 | case 't': // \t A tab character |
| 114 | x = 't' |
| 115 | case 'Z': // \Z ASCII 26 (Control+Z); see note following the table |
| 116 | x = 'Z' |
| 117 | case '%': // \% A % character; see note following the table |
| 118 | x = '%' |
| 119 | case '_': // \_ A _ character; see note following the table |
| 120 | x = '_' |
| 121 | default: |
| 122 | return "", errorInvalidString |
| 123 | } |
| 124 | |
| 125 | i++ |
| 126 | s += string(x) |
| 127 | continue |
| 128 | } |
| 129 | |
| 130 | if v[i] == d { |
no outgoing calls