@@ -86,6 +86,113 @@ print_joined(io, strings) = print_joined(io, strings, "")
86
86
87
87
join (args... ) = sprint (print_joined, args... )
88
88
89
+ # # string escaping & unescaping ##
90
+
91
+ escape_nul (s:: AbstractString , i:: Int ) =
92
+ ! done (s,i) && ' 0' <= next (s,i)[1 ] <= ' 7' ? " \\ x00" : " \\ 0"
93
+
94
+ function print_escaped (io, s:: AbstractString , esc:: AbstractString )
95
+ i = start (s)
96
+ while ! done (s,i)
97
+ c, j = next (s,i)
98
+ c == ' \0 ' ? print (io, escape_nul (s,j)) :
99
+ c == ' \e ' ? print (io, " \\ e" ) :
100
+ c == ' \\ ' ? print (io, " \\\\ " ) :
101
+ c in esc ? print (io, ' \\ ' , c) :
102
+ ' \a ' <= c <= ' \r ' ? print (io, ' \\ ' , " abtnvfr" [Int (c)- 6 ]) :
103
+ isprint (c) ? print (io, c) :
104
+ c <= ' \x 7f' ? print (io, " \\ x" , hex (c, 2 )) :
105
+ c <= ' \u ffff' ? print (io, " \\ u" , hex (c, need_full_hex (s,j) ? 4 : 2 )) :
106
+ print (io, " \\ U" , hex (c, need_full_hex (s,j) ? 8 : 4 ))
107
+ i = j
108
+ end
109
+ end
110
+
111
+ escape_string (s:: AbstractString ) = sprint (endof (s), print_escaped, s, " \" " )
112
+ function print_quoted (io, s:: AbstractString )
113
+ print (io, ' "' )
114
+ print_escaped (io, s, " \"\$ " ) # "# work around syntax highlighting problem
115
+ print (io, ' "' )
116
+ end
117
+
118
+ # bare minimum unescaping function unescapes only given characters
119
+
120
+ function print_unescaped_chars (io, s:: AbstractString , esc:: AbstractString )
121
+ if ! (' \\ ' in esc)
122
+ esc = string (" \\ " , esc)
123
+ end
124
+ i = start (s)
125
+ while ! done (s,i)
126
+ c, i = next (s,i)
127
+ if c == ' \\ ' && ! done (s,i) && s[i] in esc
128
+ c, i = next (s,i)
129
+ end
130
+ print (io, c)
131
+ end
132
+ end
133
+
134
+ unescape_chars (s:: AbstractString , esc:: AbstractString ) =
135
+ sprint (endof (s), print_unescaped_chars, s, esc)
136
+
137
+ # general unescaping of traditional C and Unicode escape sequences
138
+
139
+ function print_unescaped (io, s:: AbstractString )
140
+ i = start (s)
141
+ while ! done (s,i)
142
+ c, i = next (s,i)
143
+ if ! done (s,i) && c == ' \\ '
144
+ c, i = next (s,i)
145
+ if c == ' x' || c == ' u' || c == ' U'
146
+ n = k = 0
147
+ m = c == ' x' ? 2 :
148
+ c == ' u' ? 4 : 8
149
+ while (k+= 1 ) <= m && ! done (s,i)
150
+ c, j = next (s,i)
151
+ n = ' 0' <= c <= ' 9' ? n<< 4 + c- ' 0' :
152
+ ' a' <= c <= ' f' ? n<< 4 + c- ' a' + 10 :
153
+ ' A' <= c <= ' F' ? n<< 4 + c- ' A' + 10 : break
154
+ i = j
155
+ end
156
+ if k == 1
157
+ throw (ArgumentError (" \\ x used with no following hex digits in $(repr (s)) " ))
158
+ end
159
+ if m == 2 # \x escape sequence
160
+ write (io, UInt8 (n))
161
+ else
162
+ print (io, Char (n))
163
+ end
164
+ elseif ' 0' <= c <= ' 7'
165
+ k = 1
166
+ n = c- ' 0'
167
+ while (k+= 1 ) <= 3 && ! done (s,i)
168
+ c, j = next (s,i)
169
+ n = (' 0' <= c <= ' 7' ) ? n<< 3 + c- ' 0' : break
170
+ i = j
171
+ end
172
+ if n > 255
173
+ throw (ArgumentError (" octal escape sequence out of range" ))
174
+ end
175
+ write (io, UInt8 (n))
176
+ else
177
+ print (io, c == ' a' ? ' \a ' :
178
+ c == ' b' ? ' \b ' :
179
+ c == ' t' ? ' \t ' :
180
+ c == ' n' ? ' \n ' :
181
+ c == ' v' ? ' \v ' :
182
+ c == ' f' ? ' \f ' :
183
+ c == ' r' ? ' \r ' :
184
+ c == ' e' ? ' \e ' : c)
185
+ end
186
+ else
187
+ print (io, c)
188
+ end
189
+ end
190
+ end
191
+
192
+ unescape_string (s:: AbstractString ) = sprint (endof (s), print_unescaped, s)
193
+
194
+ macro b_str (s); :($ (unescape_string (s)). data); end
195
+
89
196
# # Count indentation, unindent ##
90
197
91
198
function blank_width (c:: Char )
0 commit comments