# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.
"""Safely evaluate Python string literals without using eval()."""

import re

simple_escapes = {
    'a': '\a',
    'b': '\b',
    'f': '\f',
    'n': '\n',
    'r': '\r',
    't': '\t',
    'v': '\v',
    "'": "'",
    '"': '"',
    '\\': '\\'
}


def escape(m):
  all, tail = m.group(0, 1)
  assert all.startswith('\\')
  esc = simple_escapes.get(tail)
  if esc is not None:
    return esc
  if tail.startswith('x'):
    hexes = tail[1:]
    if len(hexes) < 2:
      raise ValueError("invalid hex string escape ('\\%s')" % tail)
    try:
      i = int(hexes, 16)
    except ValueError:
      raise ValueError("invalid hex string escape ('\\%s')" % tail) from None
  else:
    try:
      i = int(tail, 8)
    except ValueError:
      raise ValueError("invalid octal string escape ('\\%s')" % tail) from None
  return chr(i)


def evalString(s):
  assert s.startswith("'") or s.startswith('"'), repr(s[:1])
  q = s[0]
  if s[:3] == q * 3:
    q = q * 3
  assert s.endswith(q), repr(s[-len(q):])
  assert len(s) >= 2 * len(q)
  s = s[len(q):-len(q)]
  return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s)


def test():
  for i in range(256):
    c = chr(i)
    s = repr(c)
    e = evalString(s)
    if e != c:
      print(i, c, s, e)


if __name__ == '__main__':
  test()
