[PATCH] templater: create string unescape helper (issue4798)
Augie Fackler
raf at durin42.com
Thu Sep 10 08:27:50 CDT 2015
On Wed, Sep 09, 2015 at 02:53:17PM -0700, Matt Mackall wrote:
> # HG changeset patch
> # User Matt Mackall <mpm at selenic.com>
> # Date 1441835025 25200
> # Wed Sep 09 14:43:45 2015 -0700
> # Node ID 84cd9c88ebcb57506ee919438b218e1d5f171600
> # Parent ab1c6e4efda47281b14a4f5a46cc0d4a114fff7d
> templater: create string unescape helper (issue4798)
Queued, thanks.
>
> This gives us a unified place to do error-handling of string-escaping
> syntax errors
>
> diff -r ab1c6e4efda4 -r 84cd9c88ebcb mercurial/templater.py
> --- a/mercurial/templater.py Wed Sep 09 09:07:27 2015 -0700
> +++ b/mercurial/templater.py Wed Sep 09 14:43:45 2015 -0700
> @@ -39,6 +39,13 @@
> "end": (0, None, None, None, None),
> }
>
> +def _unescape(s):
> + try:
> + return s.decode("string_escape")
> + except ValueError as e:
> + # mangle Python's exception into our format
> + raise error.ParseError(str(e).lower())
> +
> def tokenize(program, start, end):
> pos = start
> while pos < end:
> @@ -105,11 +112,8 @@
> pos += 4 # skip over double escaped characters
> continue
> if program.startswith(quote, pos, end):
> - try:
> - # interpret as if it were a part of an outer string
> - data = program[s:pos].decode('string-escape')
> - except ValueError: # unbalanced escapes
> - raise error.ParseError(_("syntax error"), s)
> + # interpret as if it were a part of an outer string
> + data = _unescape(program[s:pos])
> if token == 'template':
> data = _parsetemplate(data, 0, len(data))[0]
> yield (token, data, s)
> @@ -158,19 +162,18 @@
> n = min((tmpl.find(c, pos, stop) for c in sepchars),
> key=lambda n: (n < 0, n))
> if n < 0:
> - parsed.append(('string', tmpl[pos:stop].decode('string-escape')))
> + parsed.append(('string', _unescape(tmpl[pos:stop])))
> pos = stop
> break
> c = tmpl[n]
> bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
> if bs % 2 == 1:
> # escaped (e.g. '\{', '\\\{', but not '\\{')
> - parsed.append(('string',
> - tmpl[pos:n - 1].decode('string-escape') + c))
> + parsed.append(('string', _unescape(tmpl[pos:n - 1]) + c))
> pos = n + 1
> continue
> if n > pos:
> - parsed.append(('string', tmpl[pos:n].decode('string-escape')))
> + parsed.append(('string', _unescape(tmpl[pos:n])))
> if c == quote:
> return parsed, n + 1
>
> diff -r ab1c6e4efda4 -r 84cd9c88ebcb tests/test-command-template.t
> --- a/tests/test-command-template.t Wed Sep 09 09:07:27 2015 -0700
> +++ b/tests/test-command-template.t Wed Sep 09 14:43:45 2015 -0700
> @@ -2936,10 +2936,10 @@
> hg: parse error at 21: unterminated string
> [255]
> $ hg log -r 2 -T '{if(rev, \"\\"")}\n'
> - hg: parse error at 11: syntax error
> + hg: parse error: trailing \ in string
> [255]
> $ hg log -r 2 -T '{if(rev, r\"\\"")}\n'
> - hg: parse error at 12: syntax error
> + hg: parse error: trailing \ in string
> [255]
>
> $ cd ..
> @@ -3417,3 +3417,12 @@
> $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
> 1200000.00
> 1300000.00
> +
> +Test broken string escapes:
> +
> + $ hg log -T "bogus\\" -R a
> + hg: parse error: trailing \ in string
> + [255]
> + $ hg log -T "\\xy" -R a
> + hg: parse error: invalid \x escape
> + [255]
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list