10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogensuitemodule - Generate an AE suite module from an aete/aeut resource
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
40a8c90248264a8b26970b4473770bcc3df8515fJosh GaoBased on aete.py.
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
60a8c90248264a8b26970b4473770bcc3df8515fJosh GaoReading and understanding this code is left as an exercise to the reader.
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom warnings import warnpy3k
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaowarnpy3k("In 3.x, the gensuitemodule module is removed.", stacklevel=2)
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport MacOS
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport EasyDialogs
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport string
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport types
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport StringIO
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport keyword
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport macresource
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport aetools
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport distutils.sysconfig
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport OSATerminology
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom Carbon.Res import *
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport Carbon.Folder
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport MacOS
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport getopt
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport plistlib
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_MAC_LIB_FOLDER=os.path.dirname(aetools.__file__)
310a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDEFAULT_STANDARD_PACKAGEFOLDER=os.path.join(_MAC_LIB_FOLDER, 'lib-scriptpackages')
320a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDEFAULT_USER_PACKAGEFOLDER=distutils.sysconfig.get_python_lib()
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef usage():
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sys.stderr.write("Usage: %s [opts] application-or-resource-file\n" % sys.argv[0])
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sys.stderr.write("""Options:
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--output pkgdir  Pathname of the output package (short: -o)
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--resource       Parse resource file in stead of launching application (-r)
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--base package   Use another base package in stead of default StdSuites (-b)
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--edit old=new   Edit suite names, use empty new to skip a suite (-e)
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--creator code   Set creator code for package (-c)
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--dump           Dump aete resource to stdout in stead of creating module (-d)
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao--verbose        Tell us what happens (-v)
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao""")
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sys.exit(1)
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef main():
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(sys.argv) > 1:
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        SHORTOPTS = "rb:o:e:c:dv"
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        LONGOPTS = ("resource", "base=", "output=", "edit=", "creator=", "dump", "verbose")
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            opts, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except getopt.GetoptError:
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            usage()
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        process_func = processfile
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basepkgname = 'StdSuites'
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        output = None
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        edit_modnames = []
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        creatorsignature = None
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dump = None
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        verbose = None
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for o, a in opts:
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-r', '--resource'):
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                process_func = processfile_fromresource
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-b', '--base'):
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                basepkgname = a
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-o', '--output'):
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                output = a
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-e', '--edit'):
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                split = a.split('=')
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if len(split) != 2:
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    usage()
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                edit_modnames.append(split)
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-c', '--creator'):
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if len(a) != 4:
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    sys.stderr.write("creator must be 4-char string\n")
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    sys.exit(1)
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                creatorsignature = a
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-d', '--dump'):
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                dump = sys.stdout
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if o in ('-v', '--verbose'):
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                verbose = sys.stderr
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if output and len(args) > 1:
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            sys.stderr.write("%s: cannot specify --output with multiple inputs\n" % sys.argv[0])
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            sys.exit(1)
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for filename in args:
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            process_func(filename, output=output, basepkgname=basepkgname,
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                edit_modnames=edit_modnames, creatorsignature=creatorsignature,
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                dump=dump, verbose=verbose)
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        main_interactive()
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef main_interactive(interact=0, basepkgname='StdSuites'):
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if interact:
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ask for save-filename for each module
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        edit_modnames = None
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Use default filenames for each module
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        edit_modnames = []
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    appsfolder = Carbon.Folder.FSFindFolder(-32765, 'apps', 0)
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    filename = EasyDialogs.AskFileForOpen(
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        message='Select scriptable application',
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dialogOptionFlags=0x1056,       # allow selection of .app bundles
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        defaultLocation=appsfolder)
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not filename:
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not is_scriptable(filename):
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if EasyDialogs.AskYesNoCancel(
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "Warning: application does not seem scriptable",
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                yes="Continue", default=2, no="") <= 0:
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        processfile(filename, edit_modnames=edit_modnames, basepkgname=basepkgname,
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        verbose=sys.stderr)
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except MacOS.Error, arg:
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print "Error getting terminology:", arg
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print "Retry, manually parsing resources"
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        processfile_fromresource(filename, edit_modnames=edit_modnames,
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basepkgname=basepkgname, verbose=sys.stderr)
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef is_scriptable(application):
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Return true if the application is scriptable"""
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if os.path.isdir(application):
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        plistfile = os.path.join(application, 'Contents', 'Info.plist')
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not os.path.exists(plistfile):
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return False
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        plist = plistlib.Plist.fromFile(plistfile)
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return plist.get('NSAppleScriptEnabled', False)
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # If it is a file test for an aete/aeut resource.
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    currf = CurResFile()
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        refno = macresource.open_pathname(application)
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except MacOS.Error:
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return False
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    UseResFile(refno)
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    n_terminology = Count1Resources('aete') + Count1Resources('aeut') + \
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Count1Resources('scsz') + Count1Resources('osiz')
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    CloseResFile(refno)
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    UseResFile(currf)
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return n_terminology > 0
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef processfile_fromresource(fullname, output=None, basepkgname=None,
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        edit_modnames=None, creatorsignature=None, dump=None, verbose=None):
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Process all resources in a single file"""
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not is_scriptable(fullname) and verbose:
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print >>verbose, "Warning: app does not seem scriptable: %s" % fullname
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    cur = CurResFile()
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if verbose:
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print >>verbose, "Processing", fullname
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    rf = macresource.open_pathname(fullname)
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        UseResFile(rf)
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resources = []
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(Count1Resources('aete')):
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            res = Get1IndResource('aete', 1+i)
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            resources.append(res)
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(Count1Resources('aeut')):
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            res = Get1IndResource('aeut', 1+i)
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            resources.append(res)
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if verbose:
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            print >>verbose, "\nLISTING aete+aeut RESOURCES IN", repr(fullname)
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        aetelist = []
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for res in resources:
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if verbose:
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print >>verbose, "decoding", res.GetResInfo(), "..."
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            data = res.data
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            aete = decode(data, verbose)
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            aetelist.append((aete, res.GetResInfo()))
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    finally:
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if rf != cur:
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            CloseResFile(rf)
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            UseResFile(cur)
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # switch back (needed for dialogs in Python)
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    UseResFile(cur)
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if dump:
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dumpaetelist(aetelist, dump)
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    compileaetelist(aetelist, fullname, output=output,
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basepkgname=basepkgname, edit_modnames=edit_modnames,
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        creatorsignature=creatorsignature, verbose=verbose)
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef processfile(fullname, output=None, basepkgname=None,
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        edit_modnames=None, creatorsignature=None, dump=None,
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        verbose=None):
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Ask an application for its terminology and process that"""
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not is_scriptable(fullname) and verbose:
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print >>verbose, "Warning: app does not seem scriptable: %s" % fullname
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if verbose:
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        print >>verbose, "\nASKING FOR aete DICTIONARY IN", repr(fullname)
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        aedescobj, launched = OSATerminology.GetAppTerminology(fullname)
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except MacOS.Error, arg:
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if arg[0] in (-1701, -192): # errAEDescNotFound, resNotFound
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if verbose:
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print >>verbose, "GetAppTerminology failed with errAEDescNotFound/resNotFound, trying manually"
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            aedata, sig = getappterminology(fullname, verbose=verbose)
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not creatorsignature:
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                creatorsignature = sig
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if launched:
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if verbose:
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print >>verbose, "Launched", fullname
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raw = aetools.unpack(aedescobj)
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not raw:
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if verbose:
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print >>verbose, 'Unpack returned empty value:', raw
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not raw[0].data:
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if verbose:
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print >>verbose, 'Unpack returned value without data:', raw
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        aedata = raw[0]
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    aete = decode(aedata.data, verbose)
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if dump:
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dumpaetelist([aete], dump)
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    compileaete(aete, None, fullname, output=output, basepkgname=basepkgname,
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        creatorsignature=creatorsignature, edit_modnames=edit_modnames,
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        verbose=verbose)
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getappterminology(fullname, verbose=None):
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Get application terminology by sending an AppleEvent"""
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # First check that we actually can send AppleEvents
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not MacOS.WMAvailable():
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise RuntimeError, "Cannot send AppleEvents, no access to window manager"
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Next, a workaround for a bug in MacOS 10.2: sending events will hang unless
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # you have created an event loop first.
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import Carbon.Evt
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Carbon.Evt.WaitNextEvent(0,0)
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if os.path.isdir(fullname):
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Now get the signature of the application, hoping it is a bundle
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pkginfo = os.path.join(fullname, 'Contents', 'PkgInfo')
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not os.path.exists(pkginfo):
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise RuntimeError, "No PkgInfo file found"
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tp_cr = open(pkginfo, 'rb').read()
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cr = tp_cr[4:8]
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Assume it is a file
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cr, tp = MacOS.GetCreatorAndType(fullname)
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Let's talk to it and ask for its AETE
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    talker = aetools.TalkTo(cr)
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        talker._start()
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except (MacOS.Error, aetools.Error), arg:
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if verbose:
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            print >>verbose, 'Warning: start() failed, continuing anyway:', arg
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    reply = talker.send("ascr", "gdte")
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #reply2 = talker.send("ascr", "gdut")
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Now pick the bits out of the return that we need.
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return reply[1]['----'], cr
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef compileaetelist(aetelist, fullname, output=None, basepkgname=None,
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            edit_modnames=None, creatorsignature=None, verbose=None):
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for aete, resinfo in aetelist:
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        compileaete(aete, resinfo, fullname, output=output,
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basepkgname=basepkgname, edit_modnames=edit_modnames,
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            creatorsignature=creatorsignature, verbose=verbose)
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef dumpaetelist(aetelist, output):
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import pprint
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    pprint.pprint(aetelist, output)
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef decode(data, verbose=None):
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Decode a resource into a python data structure"""
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    f = StringIO.StringIO(data)
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    aete = generic(getaete, f)
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    aete = simplify(aete)
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    processed = f.tell()
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unprocessed = len(f.read())
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    total = f.tell()
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if unprocessed and verbose:
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        verbose.write("%d processed + %d unprocessed = %d total\n" %
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (processed, unprocessed, total))
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return aete
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef simplify(item):
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Recursively replace singleton tuples by their constituent item"""
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type(item) is types.ListType:
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return map(simplify, item)
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    elif type(item) == types.TupleType and len(item) == 2:
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return simplify(item[1])
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return item
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Here follows the aete resource decoder.
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# It is presented bottom-up instead of top-down because there are  direct
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# references to the lower-level part-decoders from the high-level part-decoders.
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getbyte(f, *args):
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    c = f.read(1)
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not c:
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise EOFError, 'in getbyte' + str(args)
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return ord(c)
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getword(f, *args):
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    getalign(f)
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    s = f.read(2)
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(s) < 2:
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise EOFError, 'in getword' + str(args)
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return (ord(s[0])<<8) | ord(s[1])
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getlong(f, *args):
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    getalign(f)
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    s = f.read(4)
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(s) < 4:
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise EOFError, 'in getlong' + str(args)
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getostype(f, *args):
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    getalign(f)
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    s = f.read(4)
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(s) < 4:
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise EOFError, 'in getostype' + str(args)
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return s
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getpstr(f, *args):
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    c = f.read(1)
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(c) < 1:
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise EOFError, 'in getpstr[1]' + str(args)
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    nbytes = ord(c)
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if nbytes == 0: return ''
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    s = f.read(nbytes)
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(s) < nbytes:
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise EOFError, 'in getpstr[2]' + str(args)
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return s
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getalign(f):
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if f.tell() & 1:
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c = f.read(1)
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ##if c != '\0':
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ##  print align:', repr(c)
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getlist(f, description, getitem):
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    count = getword(f)
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    list = []
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for i in range(count):
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        list.append(generic(getitem, f))
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        getalign(f)
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return list
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef alt_generic(what, f, *args):
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    print "generic", repr(what), args
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    res = vageneric(what, f, args)
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    print '->', repr(res)
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return res
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef generic(what, f, *args):
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type(what) == types.FunctionType:
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return apply(what, (f,) + args)
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type(what) == types.ListType:
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        record = []
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for thing in what:
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            item = apply(generic, thing[:1] + (f,) + thing[1:])
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            record.append((thing[1], item))
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return record
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return "BAD GENERIC ARGS: %r" % (what,)
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetdata = [
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "type"),
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "description"),
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getword, "flags")
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetargument = [
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "name"),
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "keyword"),
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getdata, "what")
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetevent = [
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "name"),
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "description"),
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "suite code"),
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "event code"),
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getdata, "returns"),
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getdata, "accepts"),
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "optional arguments", getargument)
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetproperty = [
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "name"),
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "code"),
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getdata, "what")
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetelement = [
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "type"),
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "keyform", getostype)
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetclass = [
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "name"),
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "class code"),
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "description"),
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "properties", getproperty),
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "elements", getelement)
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetcomparison = [
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "operator name"),
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "operator ID"),
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "operator comment"),
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetenumerator = [
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "enumerator name"),
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "enumerator ID"),
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "enumerator comment")
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetenumeration = [
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "enumeration ID"),
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "enumerator", getenumerator)
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetsuite = [
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "suite name"),
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getpstr, "suite description"),
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getostype, "suite ID"),
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getword, "suite level"),
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getword, "suite version"),
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "events", getevent),
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "classes", getclass),
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "comparisons", getcomparison),
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "enumerations", getenumeration)
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetaete = [
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getword, "major/minor version in BCD"),
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getword, "language code"),
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getword, "script code"),
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (getlist, "suites", getsuite)
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ]
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef compileaete(aete, resinfo, fname, output=None, basepkgname=None,
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        edit_modnames=None, creatorsignature=None, verbose=None):
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Generate code for a full aete resource. fname passed for doc purposes"""
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    [version, language, script, suites] = aete
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    major, minor = divmod(version, 256)
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not creatorsignature:
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        creatorsignature, dummy = MacOS.GetCreatorAndType(fname)
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    packagename = identify(os.path.splitext(os.path.basename(fname))[0])
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if language:
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        packagename = packagename+'_lang%d'%language
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if script:
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        packagename = packagename+'_script%d'%script
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(packagename) > 27:
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        packagename = packagename[:27]
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if output:
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # XXXX Put this in site-packages if it isn't a full pathname?
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not os.path.exists(output):
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.mkdir(output)
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pathname = output
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pathname = EasyDialogs.AskFolder(message='Create and select package folder for %s'%packagename,
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            defaultLocation=DEFAULT_USER_PACKAGEFOLDER)
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        output = pathname
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not pathname:
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    packagename = os.path.split(os.path.normpath(pathname))[1]
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not basepkgname:
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basepkgname = EasyDialogs.AskFolder(message='Package folder for base suite (usually StdSuites)',
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            defaultLocation=DEFAULT_STANDARD_PACKAGEFOLDER)
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if basepkgname:
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dirname, basepkgname = os.path.split(os.path.normpath(basepkgname))
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if dirname and not dirname in sys.path:
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            sys.path.insert(0, dirname)
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basepackage = __import__(basepkgname)
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basepackage = None
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    suitelist = []
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    allprecompinfo = []
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    allsuites = []
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for suite in suites:
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        compiler = SuiteCompiler(suite, basepackage, output, edit_modnames, verbose)
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        code, modname, precompinfo = compiler.precompilesuite()
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not code:
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            continue
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        allprecompinfo = allprecompinfo + precompinfo
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        suiteinfo = suite, pathname, modname
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        suitelist.append((code, modname))
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        allsuites.append(compiler)
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for compiler in allsuites:
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        compiler.compilesuite(major, minor, language, script, fname, allprecompinfo)
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    initfilename = os.path.join(output, '__init__.py')
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp = open(initfilename, 'w')
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    MacOS.SetCreatorAndType(initfilename, 'Pyth', 'TEXT')
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write('"""\n')
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("Package generated from %s\n"%ascii(fname))
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if resinfo:
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("Resource %s resid %d %s\n"%(ascii(resinfo[1]), resinfo[0], ascii(resinfo[2])))
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write('"""\n')
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write('import aetools\n')
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write('Error = aetools.Error\n')
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    suitelist.sort()
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for code, modname in suitelist:
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("import %s\n" % modname)
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("\n\n_code_to_module = {\n")
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for code, modname in suitelist:
4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("    '%s' : %s,\n"%(ascii(code), modname))
4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("}\n\n")
5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("\n\n_code_to_fullname = {\n")
5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for code, modname in suitelist:
5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("    '%s' : ('%s.%s', '%s'),\n"%(ascii(code), packagename, modname, modname))
5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("}\n\n")
5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for code, modname in suitelist:
5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("from %s import *\n"%modname)
5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Generate property dicts and element dicts for all types declared in this module
5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("\ndef getbaseclasses(v):\n")
5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("    if not getattr(v, '_propdict', None):\n")
5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("        v._propdict = {}\n")
5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("        v._elemdict = {}\n")
5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("        for superclassname in getattr(v, '_superclassnames', []):\n")
5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("            superclass = eval(superclassname)\n")
5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("            getbaseclasses(superclass)\n")
5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("            v._propdict.update(getattr(superclass, '_propdict', {}))\n")
5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("            v._elemdict.update(getattr(superclass, '_elemdict', {}))\n")
5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("        v._propdict.update(getattr(v, '_privpropdict', {}))\n")
5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("        v._elemdict.update(getattr(v, '_privelemdict', {}))\n")
5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("\n")
5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.write("import StdSuites\n")
5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    allprecompinfo.sort()
5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if allprecompinfo:
5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("\n#\n# Set property and element dictionaries now that all classes have been defined\n#\n")
5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for codenamemapper in allprecompinfo:
5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for k, v in codenamemapper.getall('class'):
5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fp.write("getbaseclasses(%s)\n" % v)
5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Generate a code-to-name mapper for all of the types (classes) declared in this module
5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    application_class = None
5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if allprecompinfo:
5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("\n#\n# Indices of types declared in this module\n#\n")
5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("_classdeclarations = {\n")
5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for codenamemapper in allprecompinfo:
5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for k, v in codenamemapper.getall('class'):
5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fp.write("    %r : %s,\n" % (k, v))
5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if k == 'capp':
5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    application_class = v
5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("}\n")
5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if suitelist:
5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("\n\nclass %s(%s_Events"%(packagename, suitelist[0][1]))
5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code, modname in suitelist[1:]:
5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write(",\n        %s_Events"%modname)
5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write(",\n        aetools.TalkTo):\n")
5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("    _signature = %r\n\n"%(creatorsignature,))
5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("    _moduleName = '%s'\n\n"%packagename)
5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if application_class:
5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("    _elemdict = %s._elemdict\n" % application_class)
5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("    _propdict = %s._propdict\n" % application_class)
5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fp.close()
5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SuiteCompiler:
5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, suite, basepackage, output, edit_modnames, verbose):
5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.suite = suite
5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.basepackage = basepackage
5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.edit_modnames = edit_modnames
5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.output = output
5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.verbose = verbose
5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Set by precompilesuite
5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.pathname = None
5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.modname = None
5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Set by compilesuite
5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp = None
5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.basemodule = None
5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.enumsneeded = {}
5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def precompilesuite(self):
5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Parse a single suite without generating the output. This step is needed
5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        so we can resolve recursive references by suites to enums/comps/etc declared
5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        in other suites"""
5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, desc, code, level, version, events, classes, comps, enums] = self.suite
5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        modname = identify(name)
5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if len(modname) > 28:
5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            modname = modname[:27]
5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.edit_modnames is None:
5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.pathname = EasyDialogs.AskFileForSave(message='Python output file',
5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                savedFileName=modname+'.py')
5820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
5830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for old, new in self.edit_modnames:
5840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if old == modname:
5850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    modname = new
5860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if modname:
5870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.pathname = os.path.join(self.output, modname + '.py')
5880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
5890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.pathname = None
5900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not self.pathname:
5910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return None, None, None
5920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.modname = os.path.splitext(os.path.split(self.pathname)[1])[0]
5940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.basepackage and code in self.basepackage._code_to_module:
5960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We are an extension of a baseclass (usually an application extending
5970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Standard_Suite or so). Import everything from our base module
5980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemodule = self.basepackage._code_to_module[code]
5990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
6000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We are not an extension.
6010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemodule = None
6020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.enumsneeded = {}
6040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for event in events:
6050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.findenumsinevent(event)
6060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        objc = ObjectCompiler(None, self.modname, basemodule, interact=(self.edit_modnames is None),
6080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            verbose=self.verbose)
6090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for cls in classes:
6100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.compileclass(cls)
6110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for cls in classes:
6120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.fillclasspropsandelems(cls)
6130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for comp in comps:
6140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.compilecomparison(comp)
6150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for enum in enums:
6160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.compileenumeration(enum)
6170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for enum in self.enumsneeded.keys():
6190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.checkforenum(enum)
6200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        objc.dumpindex()
6220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        precompinfo = objc.getprecompinfo(self.modname)
6240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return code, self.modname, precompinfo
6260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compilesuite(self, major, minor, language, script, fname, precompinfo):
6280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Generate code for a single suite"""
6290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, desc, code, level, version, events, classes, comps, enums] = self.suite
6300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Sort various lists, so re-generated source is easier compared
6310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def class_sorter(k1, k2):
6320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            """Sort classes by code, and make sure main class sorts before synonyms"""
6330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # [name, code, desc, properties, elements] = cls
6340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if k1[1] < k2[1]: return -1
6350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if k1[1] > k2[1]: return 1
6360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not k2[3] or k2[3][0][1] == 'c@#!':
6370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # This is a synonym, the other one is better
6380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return -1
6390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not k1[3] or k1[3][0][1] == 'c@#!':
6400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # This is a synonym, the other one is better
6410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 1
6420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return 0
6430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        events.sort()
6450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        classes.sort(class_sorter)
6460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        comps.sort()
6470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        enums.sort()
6480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp = fp = open(self.pathname, 'w')
6500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        MacOS.SetCreatorAndType(self.pathname, 'Pyth', 'TEXT')
6510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc)))
6530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("Level %d, version %d\n\n" % (level, version))
6540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("Generated from %s\n"%ascii(fname))
6550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("AETE/AEUT resource version %d/%d, language %d, script %d\n" % \
6560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            (major, minor, language, script))
6570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write('"""\n\n')
6580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write('import aetools\n')
6600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write('import MacOS\n\n')
6610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("_code = %r\n\n"% (code,))
6620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.basepackage and code in self.basepackage._code_to_module:
6630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We are an extension of a baseclass (usually an application extending
6640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Standard_Suite or so). Import everything from our base module
6650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code][0])
6660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemodule = self.basepackage._code_to_module[code]
6670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif self.basepackage and code.lower() in self.basepackage._code_to_module:
6680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # This is needed by CodeWarrior and some others.
6690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code.lower()][0])
6700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemodule = self.basepackage._code_to_module[code.lower()]
6710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
6720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We are not an extension.
6730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemodule = None
6740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.basemodule = basemodule
6750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.compileclassheader()
6760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.enumsneeded = {}
6780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if events:
6790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for event in events:
6800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.compileevent(event)
6810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
6820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("    pass\n\n")
6830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        objc = ObjectCompiler(fp, self.modname, basemodule, precompinfo, interact=(self.edit_modnames is None),
6850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            verbose=self.verbose)
6860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for cls in classes:
6870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.compileclass(cls)
6880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for cls in classes:
6890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.fillclasspropsandelems(cls)
6900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for comp in comps:
6910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.compilecomparison(comp)
6920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for enum in enums:
6930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.compileenumeration(enum)
6940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for enum in self.enumsneeded.keys():
6960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            objc.checkforenum(enum)
6970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        objc.dumpindex()
6990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileclassheader(self):
7010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Generate class boilerplate"""
7020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        classname = '%s_Events'%self.modname
7030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.basemodule:
7040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            modshortname = string.split(self.basemodule.__name__, '.')[-1]
7050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            baseclassname = '%s_Events'%modshortname
7060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("class %s(%s):\n\n"%(classname, baseclassname))
7070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
7080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("class %s:\n\n"%classname)
7090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileevent(self, event):
7110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Generate code for a single event"""
7120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, desc, code, subcode, returns, accepts, arguments] = event
7130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp = self.fp
7140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        funcname = identify(name)
7150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # generate name->keyword map
7170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if arguments:
7190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("    _argmap_%s = {\n"%funcname)
7200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for a in arguments:
7210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fp.write("        %r : %r,\n"%(identify(a[0]), a[1]))
7220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("    }\n\n")
7230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Generate function header
7260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        has_arg = (not is_null(accepts))
7280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        opt_arg = (has_arg and is_optional(accepts))
7290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("    def %s(self, "%funcname)
7310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if has_arg:
7320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not opt_arg:
7330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fp.write("_object, ")       # Include direct object, if it has one
7340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
7350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fp.write("_object=None, ")  # Also include if it is optional
7360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
7370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("_no_object=None, ")   # For argument checking
7380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("_attributes={}, **_arguments):\n")    # include attribute dict and args
7390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Generate doc string (important, since it may be the only
7410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # available documentation, due to our name-remaping)
7420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write('        """%s: %s\n'%(ascii(name), ascii(desc)))
7440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if has_arg:
7450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        Required argument: %s\n"%getdatadoc(accepts))
7460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif opt_arg:
7470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        Optional argument: %s\n"%getdatadoc(accepts))
7480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for arg in arguments:
7490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        Keyword argument %s: %s\n"%(identify(arg[0]),
7500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    getdatadoc(arg[2])))
7510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        Keyword argument _attributes: AppleEvent attribute dictionary\n")
7520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not is_null(returns):
7530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        Returns: %s\n"%getdatadoc(returns))
7540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write('        """\n')
7550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Fiddle the args so everything ends up in 'arguments' dictionary
7570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        _code = %r\n"% (code,))
7590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        _subcode = %r\n\n"% (subcode,))
7600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Do keyword name substitution
7620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if arguments:
7640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        aetools.keysubst(_arguments, self._argmap_%s)\n"%funcname)
7650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
7660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        if _arguments: raise TypeError, 'No optional args expected'\n")
7670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Stuff required arg (if there is one) into arguments
7690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if has_arg:
7710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        _arguments['----'] = _object\n")
7720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif opt_arg:
7730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        if _object:\n")
7740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("            _arguments['----'] = _object\n")
7750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
7760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("        if _no_object is not None: raise TypeError, 'No direct arg expected'\n")
7770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("\n")
7780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Do enum-name substitution
7800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for a in arguments:
7820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if is_enum(a[2]):
7830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                kname = a[1]
7840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ename = a[2][0]
7850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if ename != '****':
7860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    fp.write("        aetools.enumsubst(_arguments, %r, _Enum_%s)\n" %
7870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        (kname, identify(ename)))
7880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.enumsneeded[ename] = 1
7890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("\n")
7900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Do the transaction
7920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        _reply, _arguments, _attributes = self.send(_code, _subcode,\n")
7940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("                _arguments, _attributes)\n")
7950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Error handling
7970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
7980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        if _arguments.get('errn', 0):\n")
7990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("            raise aetools.Error, aetools.decodeerror(_arguments)\n")
8000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        # XXXX Optionally decode result\n")
8010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
8020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Decode result
8030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
8040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("        if '----' in _arguments:\n")
8050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if is_enum(returns):
8060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fp.write("            # XXXX Should do enum remapping here...\n")
8070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("            return _arguments['----']\n")
8080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fp.write("\n")
8090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def findenumsinevent(self, event):
8110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Find all enums for a single event"""
8120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, desc, code, subcode, returns, accepts, arguments] = event
8130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for a in arguments:
8140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if is_enum(a[2]):
8150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ename = a[2][0]
8160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if ename != '****':
8170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.enumsneeded[ename] = 1
8180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
8200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This class stores the code<->name translations for a single module. It is used
8210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# to keep the information while we're compiling the module, but we also keep these objects
8220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# around so if one suite refers to, say, an enum in another suite we know where to
8230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# find it. Finally, if we really can't find a code, the user can add modules by
8240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# hand.
8250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
8260a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass CodeNameMapper:
8270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, interact=1, verbose=None):
8290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.code2name = {
8300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "property" : {},
8310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "class" : {},
8320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "enum" : {},
8330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "comparison" : {},
8340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        }
8350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name2code =  {
8360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "property" : {},
8370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "class" : {},
8380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "enum" : {},
8390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "comparison" : {},
8400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        }
8410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.modulename = None
8420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.star_imported = 0
8430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.can_interact = interact
8440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.verbose = verbose
8450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def addnamecode(self, type, name, code):
8470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name2code[type][name] = code
8480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if code not in self.code2name[type]:
8490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.code2name[type][code] = name
8500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def hasname(self, name):
8520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dict in self.name2code.values():
8530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if name in dict:
8540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return True
8550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return False
8560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def hascode(self, type, code):
8580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return code in self.code2name[type]
8590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def findcodename(self, type, code):
8610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not self.hascode(type, code):
8620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return None, None, None
8630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name = self.code2name[type][code]
8640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.modulename and not self.star_imported:
8650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            qualname = '%s.%s'%(self.modulename, name)
8660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
8670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            qualname = name
8680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return name, qualname, self.modulename
8690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def getall(self, type):
8710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.code2name[type].items()
8720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def addmodule(self, module, name, star_imported):
8740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.modulename = name
8750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.star_imported = star_imported
8760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code, name in module._propdeclarations.items():
8770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.addnamecode('property', name, code)
8780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code, name in module._classdeclarations.items():
8790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.addnamecode('class', name, code)
8800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code in module._enumdeclarations.keys():
8810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.addnamecode('enum', '_Enum_'+identify(code), code)
8820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for code, name in module._compdeclarations.items():
8830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.addnamecode('comparison', name, code)
8840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def prepareforexport(self, name=None):
8860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not self.modulename:
8870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.modulename = name
8880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self
8890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8900a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass ObjectCompiler:
8910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, fp, modname, basesuite, othernamemappers=None, interact=1,
8920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            verbose=None):
8930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp = fp
8940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.verbose = verbose
8950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.basesuite = basesuite
8960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.can_interact = interact
8970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.modulename = modname
8980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.namemappers = [CodeNameMapper(self.can_interact, self.verbose)]
8990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if othernamemappers:
9000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.othernamemappers = othernamemappers[:]
9010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
9020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.othernamemappers = []
9030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if basesuite:
9040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemapper = CodeNameMapper(self.can_interact, self.verbose)
9050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            basemapper.addmodule(basesuite, '', 1)
9060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.namemappers.append(basemapper)
9070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def getprecompinfo(self, modname):
9090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        list = []
9100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for mapper in self.namemappers:
9110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            emapper = mapper.prepareforexport(modname)
9120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if emapper:
9130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                list.append(emapper)
9140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return list
9150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def findcodename(self, type, code):
9170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        while 1:
9180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # First try: check whether we already know about this code.
9190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for mapper in self.namemappers:
9200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if mapper.hascode(type, code):
9210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return mapper.findcodename(type, code)
9220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Second try: maybe one of the other modules knows about it.
9230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for mapper in self.othernamemappers:
9240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if mapper.hascode(type, code):
9250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.othernamemappers.remove(mapper)
9260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.namemappers.append(mapper)
9270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if self.fp:
9280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        self.fp.write("import %s\n"%mapper.modulename)
9290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    break
9300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
9310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # If all this has failed we ask the user for a guess on where it could
9320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # be and retry.
9330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if self.fp:
9340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    m = self.askdefinitionmodule(type, code)
9350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
9360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    m = None
9370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if not m: return None, None, None
9380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                mapper = CodeNameMapper(self.can_interact, self.verbose)
9390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                mapper.addmodule(m, m.__name__, 0)
9400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.namemappers.append(mapper)
9410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def hasname(self, name):
9430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for mapper in self.othernamemappers:
9440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if mapper.hasname(name) and mapper.modulename != self.modulename:
9450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if self.verbose:
9460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    print >>self.verbose, "Duplicate Python identifier:", name, self.modulename, mapper.modulename
9470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return True
9480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return False
9490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def askdefinitionmodule(self, type, code):
9510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not self.can_interact:
9520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.verbose:
9530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                print >>self.verbose, "** No definition for %s '%s' found" % (type, code)
9540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return None
9550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        path = EasyDialogs.AskFileForSave(message='Where is %s %s declared?'%(type, code))
9560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not path: return
9570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        path, file = os.path.split(path)
9580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        modname = os.path.splitext(file)[0]
9590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not path in sys.path:
9600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            sys.path.insert(0, path)
9610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        m = __import__(modname)
9620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("import %s\n"%modname)
9630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return m
9640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileclass(self, cls):
9660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, code, desc, properties, elements] = cls
9670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pname = identify(name)
9680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.namemappers[0].hascode('class', code):
9690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # plural forms and such
9700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            othername, dummy, dummy = self.namemappers[0].findcodename('class', code)
9710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp:
9720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("\n%s = %s\n"%(pname, othername))
9730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
9740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp:
9750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write('\nclass %s(aetools.ComponentItem):\n' % pname)
9760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(desc)))
9770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write('    want = %r\n' % (code,))
9780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.namemappers[0].addnamecode('class', pname, code)
9790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        is_application_class = (code == 'capp')
9800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        properties.sort()
9810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for prop in properties:
9820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.compileproperty(prop, is_application_class)
9830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elements.sort()
9840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for elem in elements:
9850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.compileelement(elem)
9860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileproperty(self, prop, is_application_class=False):
9880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, code, what] = prop
9890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if code == 'c@#!':
9900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Something silly with plurals. Skip it.
9910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
9920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pname = identify(name)
9930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.namemappers[0].hascode('property', code):
9940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # plural forms and such
9950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            othername, dummy, dummy = self.namemappers[0].findcodename('property', code)
9960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if pname == othername:
9970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return
9980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp:
9990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("\n_Prop_%s = _Prop_%s\n"%(pname, othername))
10000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
10010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp:
10020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("class _Prop_%s(aetools.NProperty):\n" % pname)
10030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(what[1])))
10040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("    which = %r\n" % (code,))
10050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("    want = %r\n" % (what[0],))
10060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.namemappers[0].addnamecode('property', pname, code)
10070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if is_application_class and self.fp:
10080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("%s = _Prop_%s()\n" % (pname, pname))
10090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileelement(self, elem):
10110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [code, keyform] = elem
10120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.fp:
10130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("#        element %r as %s\n" % (code, keyform))
10140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def fillclasspropsandelems(self, cls):
10160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, code, desc, properties, elements] = cls
10170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cname = identify(name)
10180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.namemappers[0].hascode('class', code) and \
10190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.namemappers[0].findcodename('class', code)[0] != cname:
10200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # This is an other name (plural or so) for something else. Skip.
10210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp and (elements or len(properties) > 1 or (len(properties) == 1 and
10220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                properties[0][1] != 'c@#!')):
10230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if self.verbose:
10240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    print >>self.verbose, '** Skip multiple %s of %s (code %r)' % (cname, self.namemappers[0].findcodename('class', code)[0], code)
10250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise RuntimeError, "About to skip non-empty class"
10260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
10270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        plist = []
10280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elist = []
10290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        superclasses = []
10300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for prop in properties:
10310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            [pname, pcode, what] = prop
10320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if pcode == "c@#^":
10330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                superclasses.append(what)
10340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if pcode == 'c@#!':
10350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                continue
10360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pname = identify(pname)
10370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            plist.append(pname)
10380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        superclassnames = []
10400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for superclass in superclasses:
10410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            superId, superDesc, dummy = superclass
10420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            superclassname, fullyqualifiedname, module = self.findcodename("class", superId)
10430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # I don't think this is correct:
10440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if superclassname == cname:
10450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass # superclassnames.append(fullyqualifiedname)
10460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
10470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                superclassnames.append(superclassname)
10480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.fp:
10500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("%s._superclassnames = %r\n"%(cname, superclassnames))
10510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for elem in elements:
10530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            [ecode, keyform] = elem
10540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if ecode == 'c@#!':
10550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                continue
10560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            name, ename, module = self.findcodename('class', ecode)
10570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not name:
10580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if self.fp:
10590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.fp.write("# XXXX %s element %r not found!!\n"%(cname, ecode))
10600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
10610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                elist.append((name, ename))
10620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        plist.sort()
10640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elist.sort()
10650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.fp:
10670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("%s._privpropdict = {\n"%cname)
10680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for n in plist:
10690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("    '%s' : _Prop_%s,\n"%(n, n))
10700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("}\n")
10710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("%s._privelemdict = {\n"%cname)
10720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for n, fulln in elist:
10730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("    '%s' : %s,\n"%(n, fulln))
10740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("}\n")
10750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compilecomparison(self, comp):
10770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, code, comment] = comp
10780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        iname = identify(name)
10790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.namemappers[0].addnamecode('comparison', iname, code)
10800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.fp:
10810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("class %s(aetools.NComparison):\n" % iname)
10820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(comment)))
10830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileenumeration(self, enum):
10850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [code, items] = enum
10860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name = "_Enum_%s" % identify(code)
10870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.fp:
10880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("%s = {\n" % name)
10890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for item in items:
10900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.compileenumerator(item)
10910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("}\n\n")
10920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.namemappers[0].addnamecode('enum', name, code)
10930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return code
10940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def compileenumerator(self, item):
10960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        [name, code, desc] = item
10970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("    %r : %r,\t# %s\n" % (identify(name), code, ascii(desc)))
10980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def checkforenum(self, enum):
11000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """This enum code is used by an event. Make sure it's available"""
11010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name, fullname, module = self.findcodename('enum', enum)
11020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not name:
11030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp:
11040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("_Enum_%s = None # XXXX enum %s not found!!\n"%(identify(enum), ascii(enum)))
11050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
11060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if module:
11070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.fp:
11080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fp.write("from %s import %s\n"%(module, name))
11090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def dumpindex(self):
11110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not self.fp:
11120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
11130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("\n#\n# Indices of types declared in this module\n#\n")
11140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("_classdeclarations = {\n")
11160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        classlist = self.namemappers[0].getall('class')
11170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        classlist.sort()
11180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for k, v in classlist:
11190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("    %r : %s,\n" % (k, v))
11200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("}\n")
11210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("\n_propdeclarations = {\n")
11230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        proplist = self.namemappers[0].getall('property')
11240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        proplist.sort()
11250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for k, v in proplist:
11260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("    %r : _Prop_%s,\n" % (k, v))
11270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("}\n")
11280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("\n_compdeclarations = {\n")
11300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        complist = self.namemappers[0].getall('comparison')
11310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        complist.sort()
11320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for k, v in complist:
11330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("    %r : %s,\n" % (k, v))
11340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("}\n")
11350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("\n_enumdeclarations = {\n")
11370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        enumlist = self.namemappers[0].getall('enum')
11380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        enumlist.sort()
11390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for k, v in enumlist:
11400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fp.write("    %r : %s,\n" % (k, v))
11410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fp.write("}\n")
11420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef compiledata(data):
11440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    [type, description, flags] = data
11450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return "%r -- %r %s" % (type, description, compiledataflags(flags))
11460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11470a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef is_null(data):
11480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return data[0] == 'null'
11490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11500a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef is_optional(data):
11510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return (data[2] & 0x8000)
11520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef is_enum(data):
11540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return (data[2] & 0x2000)
11550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11560a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getdatadoc(data):
11570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    [type, descr, flags] = data
11580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if descr:
11590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return ascii(descr)
11600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type == '****':
11610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return 'anything'
11620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type == 'obj ':
11630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return 'an AE object reference'
11640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return "undocumented, typecode %r"%(type,)
11650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodataflagdict = {15: "optional", 14: "list", 13: "enum", 12: "mutable"}
11670a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef compiledataflags(flags):
11680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    bits = []
11690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for i in range(16):
11700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if flags & (1<<i):
11710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if i in dataflagdict.keys():
11720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                bits.append(dataflagdict[i])
11730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
11740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                bits.append(repr(i))
11750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return '[%s]' % string.join(bits)
11760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11770a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef ascii(str):
11780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Return a string with all non-ascii characters hex-encoded"""
11790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type(str) != type(''):
11800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return map(ascii, str)
11810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    rv = ''
11820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for c in str:
11830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if c in ('\t', '\n', '\r') or ' ' <= c < chr(0x7f):
11840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + c
11850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
11860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + '\\' + 'x%02.2x' % ord(c)
11870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return rv
11880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11890a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef identify(str):
11900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Turn any string into an identifier:
11910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    - replace space by _
11920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    - replace other illegal chars by _xx_ (hex code)
11930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    - append _ if the result is a python keyword
11940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
11950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not str:
11960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return "empty_ae_name_"
11970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    rv = ''
11980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ok = string.ascii_letters + '_'
11990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ok2 = ok + string.digits
12000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for c in str:
12010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if c in ok:
12020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + c
12030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif c == ' ':
12040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + '_'
12050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
12060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + '_%02.2x_'%ord(c)
12070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ok = ok2
12080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if keyword.iskeyword(rv):
12090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = rv + '_'
12100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return rv
12110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Call the main program
12130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
12150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    main()
12160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sys.exit(1)
1217