##// END OF EJS Templates
templater: create string unescape helper (issue4798)...
Matt Mackall -
r26215:72aad184 default
parent child Browse files
Show More
@@ -39,6 +39,13 b' elements = {'
39 "end": (0, None, None, None, None),
39 "end": (0, None, None, None, None),
40 }
40 }
41
41
42 def _unescape(s):
43 try:
44 return s.decode("string_escape")
45 except ValueError as e:
46 # mangle Python's exception into our format
47 raise error.ParseError(str(e).lower())
48
42 def tokenize(program, start, end):
49 def tokenize(program, start, end):
43 pos = start
50 pos = start
44 while pos < end:
51 while pos < end:
@@ -105,11 +112,8 b' def tokenize(program, start, end):'
105 pos += 4 # skip over double escaped characters
112 pos += 4 # skip over double escaped characters
106 continue
113 continue
107 if program.startswith(quote, pos, end):
114 if program.startswith(quote, pos, end):
108 try:
115 # interpret as if it were a part of an outer string
109 # interpret as if it were a part of an outer string
116 data = _unescape(program[s:pos])
110 data = program[s:pos].decode('string-escape')
111 except ValueError: # unbalanced escapes
112 raise error.ParseError(_("syntax error"), s)
113 if token == 'template':
117 if token == 'template':
114 data = _parsetemplate(data, 0, len(data))[0]
118 data = _parsetemplate(data, 0, len(data))[0]
115 yield (token, data, s)
119 yield (token, data, s)
@@ -158,19 +162,18 b' def _parsetemplate(tmpl, start, stop, qu'
158 n = min((tmpl.find(c, pos, stop) for c in sepchars),
162 n = min((tmpl.find(c, pos, stop) for c in sepchars),
159 key=lambda n: (n < 0, n))
163 key=lambda n: (n < 0, n))
160 if n < 0:
164 if n < 0:
161 parsed.append(('string', tmpl[pos:stop].decode('string-escape')))
165 parsed.append(('string', _unescape(tmpl[pos:stop])))
162 pos = stop
166 pos = stop
163 break
167 break
164 c = tmpl[n]
168 c = tmpl[n]
165 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
169 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
166 if bs % 2 == 1:
170 if bs % 2 == 1:
167 # escaped (e.g. '\{', '\\\{', but not '\\{')
171 # escaped (e.g. '\{', '\\\{', but not '\\{')
168 parsed.append(('string',
172 parsed.append(('string', _unescape(tmpl[pos:n - 1]) + c))
169 tmpl[pos:n - 1].decode('string-escape') + c))
170 pos = n + 1
173 pos = n + 1
171 continue
174 continue
172 if n > pos:
175 if n > pos:
173 parsed.append(('string', tmpl[pos:n].decode('string-escape')))
176 parsed.append(('string', _unescape(tmpl[pos:n])))
174 if c == quote:
177 if c == quote:
175 return parsed, n + 1
178 return parsed, n + 1
176
179
@@ -2936,10 +2936,10 b' escaped single quotes and errors:'
2936 hg: parse error at 21: unterminated string
2936 hg: parse error at 21: unterminated string
2937 [255]
2937 [255]
2938 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2938 $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
2939 hg: parse error at 11: syntax error
2939 hg: parse error: trailing \ in string
2940 [255]
2940 [255]
2941 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2941 $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
2942 hg: parse error at 12: syntax error
2942 hg: parse error: trailing \ in string
2943 [255]
2943 [255]
2944
2944
2945 $ cd ..
2945 $ cd ..
@@ -3417,3 +3417,12 b' Test with non-strings like dates'
3417 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3417 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3418 1200000.00
3418 1200000.00
3419 1300000.00
3419 1300000.00
3420
3421 Test broken string escapes:
3422
3423 $ hg log -T "bogus\\" -R a
3424 hg: parse error: trailing \ in string
3425 [255]
3426 $ hg log -T "\\xy" -R a
3427 hg: parse error: invalid \x escape
3428 [255]
General Comments 0
You need to be logged in to leave comments. Login now