# 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)

    else:

        try:

            i = int(tail, 8)

        except ValueError:

            raise ValueError("invalid octal string escape ('\\%s')" % tail)

    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()

