[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