# Part of the A-A-P recipe executive: Load the re module with tricks

# Copyright (C) 2002-2003 Stichting NLnet Labs
# Permission to copy and use this file is specified in the file COPYING.
# If this file is missing you can find it here: http://www.a-a-p.org/COPYING


# The reason "pre" is used, instead of the default "re" module (which uses
# "sre"), is that compiling a regexp with the "sre" module is about twenty
# times slower than using the old "pre" module.  We don't use Unicode yet, thus
# we might as well use the old module until this problem has been solved.  The
# "pre" module is the "re" module of Python 1.5.

# If already done return quickly.
import __builtin__
if not __builtin__.__dict__.has_key("re"):

    import sys

    if sys.version[0] == '2' and sys.version[2] == "3":
        # In Python 2.3 importing "pre" generates a warning, we use our own copy of
        # the module with the warning removed.
        exec "import aapre as re"

    elif sys.version[0] == '2' and sys.version[2] in "012":
        exec "import pre as re"

        # Check if the bug in pre.py of Python 2.2.1 is present.  It was
        # distributed with Red Hat 8.0, thus it happens frequently enough to
        # require this check.
        try:
            msg = re.sub("(a)", "\\1", "a")
        except TypeError:

            # Corrected version of RegexObject.subn() from Python 2.2.1.
            def aapsubn(self, repl, source, count=0):
                """subn(repl, string[, count=0]) -> tuple

                Perform the same operation as sub(), but return a tuple
                (new_string, number_of_subs_made).

                """
                if count < 0:
                    raise re.error, "negative substitution count"
                if count == 0:
                    count = sys.maxint
                n = 0           # Number of matches
                pos = 0         # Where to start searching
                lastmatch = -1  # End of last match
                results = []    # Substrings making up the result
                end = len(source)

                if type(repl) is type(''):
                    # See if repl contains group references (if it does,
                    # pcre_expand will attempt to call _Dummy.group, which
                    # results in a TypeError)
                    try:
                        repl = re.pcre_expand(re._Dummy, repl)
                    except (re.error, TypeError):
                        m = re.MatchObject(self, source, 0, end, [])
                        repl = lambda m, repl=repl, expand=re.pcre_expand: expand(m, repl)
                    else:
                        m = None
                else:
                    m = re.MatchObject(self, source, 0, end, [])

                match = self.code.match
                append = results.append
                while n < count and pos <= end:
                    regs = match(source, pos, end, 0)
                    if not regs:
                        break
                    self._num_regs = len(regs)
                    i, j = regs[0]
                    if i == j == lastmatch:
                        # Empty match adjacent to previous match
                        pos = pos + 1
                        append(source[lastmatch:pos])
                        continue
                    if pos < i:
                        append(source[pos:i])
                    if m:
                        m.pos = pos
                        m.regs = regs
                        append(repl(m))
                    else:
                        append(repl)
                    pos = lastmatch = j
                    if i == j:
                        # Last match was empty; don't try here again
                        pos = pos + 1
                        append(source[lastmatch:pos])
                    n = n + 1
                append(source[pos:])
                return (''.join(results), n)

            # Replace the subn() method of the RegexObject class.
            re.RegexObject.subn = aapsubn

    else:
        # Python version before 2.0 or later than 2.3: use regular re module.
        import re

    __builtin__.__dict__['re'] = re

# vim: set sw=4 et sts=4 tw=79 fo+=l:
