#!/usr/bin/python
"""fixapplepython23 - Fix Apple-installed Python 2.3 (on Mac OS X 10.3)

Python 2.3 (and 2.3.X for X<5) have the problem that building an extension
for a framework installation may accidentally pick up the framework
of a newer Python, in stead of the one that was used to build the extension.

This script modifies the Makefile (in .../lib/python2.3/config) to use
the newer method of linking extensions with "-undefined dynamic_lookup"
which fixes this problem.

The script will first check all prerequisites, and return a zero exit
status also when nothing needs to be fixed.
"""
import sys
import os
import gestalt

MAKEFILE='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/Makefile'
CHANGES=((
    'LDSHARED=\t$(CC) $(LDFLAGS) -bundle -framework $(PYTHONFRAMEWORK)\n',
    'LDSHARED=\t$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup\n'
    ),(
    'BLDSHARED=\t$(CC) $(LDFLAGS) -bundle -framework $(PYTHONFRAMEWORK)\n',
    'BLDSHARED=\t$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup\n'
    ),(
    'CC=\t\tgcc\n',
    'CC=\t\t/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-gcc\n'
    ),(
    'CXX=\t\tc++\n',
    'CXX=\t\t/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-g++\n'
))

GCC_SCRIPT='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-gcc'
GXX_SCRIPT='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-g++'
SCRIPT="""#!/bin/sh
export MACOSX_DEPLOYMENT_TARGET=10.3
exec %s "${@}"
"""

def findline(lines, start):
    """return line starting with given string or -1"""
    for i in range(len(lines)):
        if lines[i][:len(start)] == start:
            return i
    return -1

def fix(makefile, do_apply):
    """Fix the Makefile, if required."""
    fixed = False
    lines = open(makefile).readlines()

    for old, new in CHANGES:
        i = findline(lines, new)
        if i >= 0:
            # Already fixed
            continue
        i = findline(lines, old)
        if i < 0:
            print 'fixapplepython23: Python installation not fixed (appears broken)'
            print 'fixapplepython23: missing line:', old
            return 2
        lines[i] = new
        fixed = True

    if fixed:
        if do_apply:
            print 'fixapplepython23: Fix to Apple-installed Python 2.3 applied'
            os.rename(makefile, makefile + '~')
            open(makefile, 'w').writelines(lines)
            return 0
        else:
            print 'fixapplepython23: Fix to Apple-installed Python 2.3 should be applied'
            return 1
    else:
        print 'fixapplepython23: No fix needed, appears to have been applied before'
        return 0

def makescript(filename, compiler):
    """Create a wrapper script for a compiler"""
    dirname = os.path.split(filename)[0]
    if not os.access(dirname, os.X_OK):
        os.mkdir(dirname, 0755)
    fp = open(filename, 'w')
    fp.write(SCRIPT % compiler)
    fp.close()
    os.chmod(filename, 0755)
    print 'fixapplepython23: Created', filename

def main():
    # Check for -n option
    if len(sys.argv) > 1 and sys.argv[1] == '-n':
        do_apply = False
    else:
        do_apply = True
    # First check OS version
    if sys.byteorder == 'little':
        # All intel macs are fine
        print "fixapplypython23: no fix is needed on MacOSX on Intel"
        sys.exit(0)

    if gestalt.gestalt('sysv') < 0x1030:
        print 'fixapplepython23: no fix needed on MacOSX < 10.3'
        sys.exit(0)

    if gestalt.gestalt('sysv') >= 0x1040:
        print 'fixapplepython23: no fix needed on MacOSX >= 10.4'
        sys.exit(0)

    # Test that a framework Python is indeed installed
    if not os.path.exists(MAKEFILE):
        print 'fixapplepython23: Python framework does not appear to be installed (?), nothing fixed'
        sys.exit(0)
    # Check that we can actually write the file
    if do_apply and not os.access(MAKEFILE, os.W_OK):
        print 'fixapplepython23: No write permission, please run with "sudo"'
        sys.exit(2)
    # Create the shell scripts
    if do_apply:
        if not os.access(GCC_SCRIPT, os.X_OK):
            makescript(GCC_SCRIPT, "gcc")
        if not os.access(GXX_SCRIPT, os.X_OK):
            makescript(GXX_SCRIPT, "g++")
    #  Finally fix the makefile
    rv = fix(MAKEFILE, do_apply)
    #sys.exit(rv)
    sys.exit(0)

if __name__ == '__main__':
    main()
