| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | gensuitemodule - Generate an AE suite module from an aete/aeut resource | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-17 22:11:45 +00:00
										 |  |  | Based on aete.py. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Reading and understanding this code is left as an exercise to the reader. | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-12 21:42:13 +00:00
										 |  |  | from warnings import warnpy3k | 
					
						
							|  |  |  | warnpy3k("In 3.x, the gensuitemodule module is removed.") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | import MacOS | 
					
						
							| 
									
										
										
										
											2003-01-26 20:35:47 +00:00
										 |  |  | import EasyDialogs | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | import os | 
					
						
							|  |  |  | import string | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import types | 
					
						
							|  |  |  | import StringIO | 
					
						
							| 
									
										
										
										
											2002-01-24 22:44:07 +00:00
										 |  |  | import keyword | 
					
						
							| 
									
										
										
										
											2002-03-30 23:43:04 +00:00
										 |  |  | import macresource | 
					
						
							| 
									
										
										
										
											2003-03-06 23:04:38 +00:00
										 |  |  | import aetools | 
					
						
							|  |  |  | import distutils.sysconfig | 
					
						
							|  |  |  | import OSATerminology | 
					
						
							| 
									
										
										
										
											2001-08-25 12:15:04 +00:00
										 |  |  | from Carbon.Res import * | 
					
						
							| 
									
										
										
										
											2003-03-29 22:54:00 +00:00
										 |  |  | import Carbon.Folder | 
					
						
							| 
									
										
										
										
											2003-03-06 23:04:38 +00:00
										 |  |  | import MacOS | 
					
						
							| 
									
										
										
										
											2003-03-21 16:07:39 +00:00
										 |  |  | import getopt | 
					
						
							| 
									
										
										
										
											2003-03-29 22:54:00 +00:00
										 |  |  | import plistlib | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-06 23:04:38 +00:00
										 |  |  | _MAC_LIB_FOLDER=os.path.dirname(aetools.__file__) | 
					
						
							|  |  |  | DEFAULT_STANDARD_PACKAGEFOLDER=os.path.join(_MAC_LIB_FOLDER, 'lib-scriptpackages') | 
					
						
							|  |  |  | DEFAULT_USER_PACKAGEFOLDER=distutils.sysconfig.get_python_lib() | 
					
						
							| 
									
										
										
										
											2002-03-30 23:43:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-21 16:07:39 +00:00
										 |  |  | def usage(): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     sys.stderr.write("Usage: %s [opts] application-or-resource-file\n" % sys.argv[0]) | 
					
						
							|  |  |  |     sys.stderr.write("""Options:
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | --output pkgdir  Pathname of the output package (short: -o) | 
					
						
							| 
									
										
										
										
											2003-03-21 16:07:39 +00:00
										 |  |  | --resource       Parse resource file in stead of launching application (-r) | 
					
						
							|  |  |  | --base package   Use another base package in stead of default StdSuites (-b) | 
					
						
							|  |  |  | --edit old=new   Edit suite names, use empty new to skip a suite (-e) | 
					
						
							| 
									
										
										
										
											2003-03-21 16:28:09 +00:00
										 |  |  | --creator code   Set creator code for package (-c) | 
					
						
							| 
									
										
										
										
											2003-04-01 13:32:17 +00:00
										 |  |  | --dump           Dump aete resource to stdout in stead of creating module (-d) | 
					
						
							|  |  |  | --verbose        Tell us what happens (-v) | 
					
						
							| 
									
										
										
										
											2003-03-21 16:07:39 +00:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     sys.exit(1) | 
					
						
							| 
									
										
										
										
											2003-03-21 16:07:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | def main(): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     if len(sys.argv) > 1: | 
					
						
							|  |  |  |         SHORTOPTS = "rb:o:e:c:dv" | 
					
						
							|  |  |  |         LONGOPTS = ("resource", "base=", "output=", "edit=", "creator=", "dump", "verbose") | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             opts, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS) | 
					
						
							|  |  |  |         except getopt.GetoptError: | 
					
						
							|  |  |  |             usage() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         process_func = processfile | 
					
						
							|  |  |  |         basepkgname = 'StdSuites' | 
					
						
							|  |  |  |         output = None | 
					
						
							|  |  |  |         edit_modnames = [] | 
					
						
							|  |  |  |         creatorsignature = None | 
					
						
							|  |  |  |         dump = None | 
					
						
							|  |  |  |         verbose = None | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         for o, a in opts: | 
					
						
							|  |  |  |             if o in ('-r', '--resource'): | 
					
						
							|  |  |  |                 process_func = processfile_fromresource | 
					
						
							|  |  |  |             if o in ('-b', '--base'): | 
					
						
							|  |  |  |                 basepkgname = a | 
					
						
							|  |  |  |             if o in ('-o', '--output'): | 
					
						
							|  |  |  |                 output = a | 
					
						
							|  |  |  |             if o in ('-e', '--edit'): | 
					
						
							|  |  |  |                 split = a.split('=') | 
					
						
							|  |  |  |                 if len(split) != 2: | 
					
						
							|  |  |  |                     usage() | 
					
						
							|  |  |  |                 edit_modnames.append(split) | 
					
						
							|  |  |  |             if o in ('-c', '--creator'): | 
					
						
							|  |  |  |                 if len(a) != 4: | 
					
						
							|  |  |  |                     sys.stderr.write("creator must be 4-char string\n") | 
					
						
							|  |  |  |                     sys.exit(1) | 
					
						
							|  |  |  |                 creatorsignature = a | 
					
						
							|  |  |  |             if o in ('-d', '--dump'): | 
					
						
							|  |  |  |                 dump = sys.stdout | 
					
						
							|  |  |  |             if o in ('-v', '--verbose'): | 
					
						
							|  |  |  |                 verbose = sys.stderr | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         if output and len(args) > 1: | 
					
						
							|  |  |  |             sys.stderr.write("%s: cannot specify --output with multiple inputs\n" % sys.argv[0]) | 
					
						
							|  |  |  |             sys.exit(1) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         for filename in args: | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |             process_func(filename, output=output, basepkgname=basepkgname, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |                 edit_modnames=edit_modnames, creatorsignature=creatorsignature, | 
					
						
							|  |  |  |                 dump=dump, verbose=verbose) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         main_interactive() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-29 22:54:00 +00:00
										 |  |  | def main_interactive(interact=0, basepkgname='StdSuites'): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     if interact: | 
					
						
							|  |  |  |         # Ask for save-filename for each module | 
					
						
							|  |  |  |         edit_modnames = None | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # Use default filenames for each module | 
					
						
							|  |  |  |         edit_modnames = [] | 
					
						
							|  |  |  |     appsfolder = Carbon.Folder.FSFindFolder(-32765, 'apps', 0) | 
					
						
							|  |  |  |     filename = EasyDialogs.AskFileForOpen( | 
					
						
							|  |  |  |         message='Select scriptable application', | 
					
						
							|  |  |  |         dialogOptionFlags=0x1056,       # allow selection of .app bundles | 
					
						
							|  |  |  |         defaultLocation=appsfolder) | 
					
						
							|  |  |  |     if not filename: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if not is_scriptable(filename): | 
					
						
							|  |  |  |         if EasyDialogs.AskYesNoCancel( | 
					
						
							|  |  |  |                 "Warning: application does not seem scriptable", | 
					
						
							|  |  |  |                 yes="Continue", default=2, no="") <= 0: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         processfile(filename, edit_modnames=edit_modnames, basepkgname=basepkgname, | 
					
						
							|  |  |  |         verbose=sys.stderr) | 
					
						
							|  |  |  |     except MacOS.Error, arg: | 
					
						
							|  |  |  |         print "Error getting terminology:", arg | 
					
						
							|  |  |  |         print "Retry, manually parsing resources" | 
					
						
							|  |  |  |         processfile_fromresource(filename, edit_modnames=edit_modnames, | 
					
						
							|  |  |  |             basepkgname=basepkgname, verbose=sys.stderr) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-29 22:54:00 +00:00
										 |  |  | def is_scriptable(application): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """Return true if the application is scriptable""" | 
					
						
							|  |  |  |     if os.path.isdir(application): | 
					
						
							|  |  |  |         plistfile = os.path.join(application, 'Contents', 'Info.plist') | 
					
						
							|  |  |  |         if not os.path.exists(plistfile): | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         plist = plistlib.Plist.fromFile(plistfile) | 
					
						
							|  |  |  |         return plist.get('NSAppleScriptEnabled', False) | 
					
						
							|  |  |  |     # If it is a file test for an aete/aeut resource. | 
					
						
							|  |  |  |     currf = CurResFile() | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         refno = macresource.open_pathname(application) | 
					
						
							|  |  |  |     except MacOS.Error: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     UseResFile(refno) | 
					
						
							|  |  |  |     n_terminology = Count1Resources('aete') + Count1Resources('aeut') + \ | 
					
						
							|  |  |  |         Count1Resources('scsz') + Count1Resources('osiz') | 
					
						
							|  |  |  |     CloseResFile(refno) | 
					
						
							|  |  |  |     UseResFile(currf) | 
					
						
							|  |  |  |     return n_terminology > 0 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | def processfile_fromresource(fullname, output=None, basepkgname=None, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         edit_modnames=None, creatorsignature=None, dump=None, verbose=None): | 
					
						
							|  |  |  |     """Process all resources in a single file""" | 
					
						
							|  |  |  |     if not is_scriptable(fullname) and verbose: | 
					
						
							|  |  |  |         print >>verbose, "Warning: app does not seem scriptable: %s" % fullname | 
					
						
							|  |  |  |     cur = CurResFile() | 
					
						
							|  |  |  |     if verbose: | 
					
						
							|  |  |  |         print >>verbose, "Processing", fullname | 
					
						
							|  |  |  |     rf = macresource.open_pathname(fullname) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         UseResFile(rf) | 
					
						
							|  |  |  |         resources = [] | 
					
						
							|  |  |  |         for i in range(Count1Resources('aete')): | 
					
						
							|  |  |  |             res = Get1IndResource('aete', 1+i) | 
					
						
							|  |  |  |             resources.append(res) | 
					
						
							|  |  |  |         for i in range(Count1Resources('aeut')): | 
					
						
							|  |  |  |             res = Get1IndResource('aeut', 1+i) | 
					
						
							|  |  |  |             resources.append(res) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |         if verbose: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             print >>verbose, "\nLISTING aete+aeut RESOURCES IN", repr(fullname) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         aetelist = [] | 
					
						
							|  |  |  |         for res in resources: | 
					
						
							|  |  |  |             if verbose: | 
					
						
							|  |  |  |                 print >>verbose, "decoding", res.GetResInfo(), "..." | 
					
						
							|  |  |  |             data = res.data | 
					
						
							|  |  |  |             aete = decode(data, verbose) | 
					
						
							|  |  |  |             aetelist.append((aete, res.GetResInfo())) | 
					
						
							|  |  |  |     finally: | 
					
						
							|  |  |  |         if rf <> cur: | 
					
						
							|  |  |  |             CloseResFile(rf) | 
					
						
							|  |  |  |             UseResFile(cur) | 
					
						
							|  |  |  |     # switch back (needed for dialogs in Python) | 
					
						
							|  |  |  |     UseResFile(cur) | 
					
						
							|  |  |  |     if dump: | 
					
						
							|  |  |  |         dumpaetelist(aetelist, dump) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |     compileaetelist(aetelist, fullname, output=output, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         basepkgname=basepkgname, edit_modnames=edit_modnames, | 
					
						
							|  |  |  |         creatorsignature=creatorsignature, verbose=verbose) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | def processfile(fullname, output=None, basepkgname=None, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         edit_modnames=None, creatorsignature=None, dump=None, | 
					
						
							|  |  |  |         verbose=None): | 
					
						
							|  |  |  |     """Ask an application for its terminology and process that""" | 
					
						
							|  |  |  |     if not is_scriptable(fullname) and verbose: | 
					
						
							|  |  |  |         print >>verbose, "Warning: app does not seem scriptable: %s" % fullname | 
					
						
							|  |  |  |     if verbose: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |         print >>verbose, "\nASKING FOR aete DICTIONARY IN", repr(fullname) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     try: | 
					
						
							|  |  |  |         aedescobj, launched = OSATerminology.GetAppTerminology(fullname) | 
					
						
							|  |  |  |     except MacOS.Error, arg: | 
					
						
							|  |  |  |         if arg[0] in (-1701, -192): # errAEDescNotFound, resNotFound | 
					
						
							|  |  |  |             if verbose: | 
					
						
							|  |  |  |                 print >>verbose, "GetAppTerminology failed with errAEDescNotFound/resNotFound, trying manually" | 
					
						
							|  |  |  |             aedata, sig = getappterminology(fullname, verbose=verbose) | 
					
						
							|  |  |  |             if not creatorsignature: | 
					
						
							|  |  |  |                 creatorsignature = sig | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         if launched: | 
					
						
							|  |  |  |             if verbose: | 
					
						
							|  |  |  |                 print >>verbose, "Launched", fullname | 
					
						
							|  |  |  |         raw = aetools.unpack(aedescobj) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |         if not raw: | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |             if verbose: | 
					
						
							|  |  |  |                 print >>verbose, 'Unpack returned empty value:', raw | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         if not raw[0].data: | 
					
						
							|  |  |  |             if verbose: | 
					
						
							|  |  |  |                 print >>verbose, 'Unpack returned value without data:', raw | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         aedata = raw[0] | 
					
						
							|  |  |  |     aete = decode(aedata.data, verbose) | 
					
						
							|  |  |  |     if dump: | 
					
						
							|  |  |  |         dumpaetelist([aete], dump) | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     compileaete(aete, None, fullname, output=output, basepkgname=basepkgname, | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |         creatorsignature=creatorsignature, edit_modnames=edit_modnames, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         verbose=verbose) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-01 13:32:17 +00:00
										 |  |  | def getappterminology(fullname, verbose=None): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """Get application terminology by sending an AppleEvent""" | 
					
						
							|  |  |  |     # First check that we actually can send AppleEvents | 
					
						
							|  |  |  |     if not MacOS.WMAvailable(): | 
					
						
							|  |  |  |         raise RuntimeError, "Cannot send AppleEvents, no access to window manager" | 
					
						
							|  |  |  |     # Next, a workaround for a bug in MacOS 10.2: sending events will hang unless | 
					
						
							|  |  |  |     # you have created an event loop first. | 
					
						
							|  |  |  |     import Carbon.Evt | 
					
						
							|  |  |  |     Carbon.Evt.WaitNextEvent(0,0) | 
					
						
							|  |  |  |     if os.path.isdir(fullname): | 
					
						
							|  |  |  |         # Now get the signature of the application, hoping it is a bundle | 
					
						
							|  |  |  |         pkginfo = os.path.join(fullname, 'Contents', 'PkgInfo') | 
					
						
							|  |  |  |         if not os.path.exists(pkginfo): | 
					
						
							|  |  |  |             raise RuntimeError, "No PkgInfo file found" | 
					
						
							|  |  |  |         tp_cr = open(pkginfo, 'rb').read() | 
					
						
							|  |  |  |         cr = tp_cr[4:8] | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # Assume it is a file | 
					
						
							|  |  |  |         cr, tp = MacOS.GetCreatorAndType(fullname) | 
					
						
							|  |  |  |     # Let's talk to it and ask for its AETE | 
					
						
							|  |  |  |     talker = aetools.TalkTo(cr) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         talker._start() | 
					
						
							|  |  |  |     except (MacOS.Error, aetools.Error), arg: | 
					
						
							|  |  |  |         if verbose: | 
					
						
							|  |  |  |             print >>verbose, 'Warning: start() failed, continuing anyway:', arg | 
					
						
							|  |  |  |     reply = talker.send("ascr", "gdte") | 
					
						
							|  |  |  |     #reply2 = talker.send("ascr", "gdut") | 
					
						
							|  |  |  |     # Now pick the bits out of the return that we need. | 
					
						
							|  |  |  |     return reply[1]['----'], cr | 
					
						
							| 
									
										
										
										
											2003-03-06 23:04:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def compileaetelist(aetelist, fullname, output=None, basepkgname=None, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |             edit_modnames=None, creatorsignature=None, verbose=None): | 
					
						
							|  |  |  |     for aete, resinfo in aetelist: | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |         compileaete(aete, resinfo, fullname, output=output, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |             basepkgname=basepkgname, edit_modnames=edit_modnames, | 
					
						
							|  |  |  |             creatorsignature=creatorsignature, verbose=verbose) | 
					
						
							| 
									
										
										
										
											2003-04-01 13:32:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def dumpaetelist(aetelist, output): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     import pprint | 
					
						
							|  |  |  |     pprint.pprint(aetelist, output) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-01 13:32:17 +00:00
										 |  |  | def decode(data, verbose=None): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """Decode a resource into a python data structure""" | 
					
						
							|  |  |  |     f = StringIO.StringIO(data) | 
					
						
							|  |  |  |     aete = generic(getaete, f) | 
					
						
							|  |  |  |     aete = simplify(aete) | 
					
						
							|  |  |  |     processed = f.tell() | 
					
						
							|  |  |  |     unprocessed = len(f.read()) | 
					
						
							|  |  |  |     total = f.tell() | 
					
						
							|  |  |  |     if unprocessed and verbose: | 
					
						
							|  |  |  |         verbose.write("%d processed + %d unprocessed = %d total\n" % | 
					
						
							|  |  |  |                          (processed, unprocessed, total)) | 
					
						
							|  |  |  |     return aete | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def simplify(item): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """Recursively replace singleton tuples by their constituent item""" | 
					
						
							|  |  |  |     if type(item) is types.ListType: | 
					
						
							|  |  |  |         return map(simplify, item) | 
					
						
							|  |  |  |     elif type(item) == types.TupleType and len(item) == 2: | 
					
						
							|  |  |  |         return simplify(item[1]) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return item | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Here follows the aete resource decoder. | 
					
						
							|  |  |  | # It is presented bottom-up instead of top-down because there are  direct | 
					
						
							|  |  |  | # references to the lower-level part-decoders from the high-level part-decoders. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def getbyte(f, *args): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     c = f.read(1) | 
					
						
							|  |  |  |     if not c: | 
					
						
							|  |  |  |         raise EOFError, 'in getbyte' + str(args) | 
					
						
							|  |  |  |     return ord(c) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getword(f, *args): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     getalign(f) | 
					
						
							|  |  |  |     s = f.read(2) | 
					
						
							|  |  |  |     if len(s) < 2: | 
					
						
							|  |  |  |         raise EOFError, 'in getword' + str(args) | 
					
						
							|  |  |  |     return (ord(s[0])<<8) | ord(s[1]) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getlong(f, *args): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     getalign(f) | 
					
						
							|  |  |  |     s = f.read(4) | 
					
						
							|  |  |  |     if len(s) < 4: | 
					
						
							|  |  |  |         raise EOFError, 'in getlong' + str(args) | 
					
						
							|  |  |  |     return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getostype(f, *args): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     getalign(f) | 
					
						
							|  |  |  |     s = f.read(4) | 
					
						
							|  |  |  |     if len(s) < 4: | 
					
						
							|  |  |  |         raise EOFError, 'in getostype' + str(args) | 
					
						
							|  |  |  |     return s | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getpstr(f, *args): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     c = f.read(1) | 
					
						
							|  |  |  |     if len(c) < 1: | 
					
						
							|  |  |  |         raise EOFError, 'in getpstr[1]' + str(args) | 
					
						
							|  |  |  |     nbytes = ord(c) | 
					
						
							|  |  |  |     if nbytes == 0: return '' | 
					
						
							|  |  |  |     s = f.read(nbytes) | 
					
						
							|  |  |  |     if len(s) < nbytes: | 
					
						
							|  |  |  |         raise EOFError, 'in getpstr[2]' + str(args) | 
					
						
							|  |  |  |     return s | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getalign(f): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     if f.tell() & 1: | 
					
						
							|  |  |  |         c = f.read(1) | 
					
						
							|  |  |  |         ##if c <> '\0': | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |         ##  print align:', repr(c) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def getlist(f, description, getitem): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     count = getword(f) | 
					
						
							|  |  |  |     list = [] | 
					
						
							|  |  |  |     for i in range(count): | 
					
						
							|  |  |  |         list.append(generic(getitem, f)) | 
					
						
							|  |  |  |         getalign(f) | 
					
						
							|  |  |  |     return list | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def alt_generic(what, f, *args): | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |     print "generic", repr(what), args | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     res = vageneric(what, f, args) | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |     print '->', repr(res) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     return res | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def generic(what, f, *args): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     if type(what) == types.FunctionType: | 
					
						
							|  |  |  |         return apply(what, (f,) + args) | 
					
						
							|  |  |  |     if type(what) == types.ListType: | 
					
						
							|  |  |  |         record = [] | 
					
						
							|  |  |  |         for thing in what: | 
					
						
							|  |  |  |             item = apply(generic, thing[:1] + (f,) + thing[1:]) | 
					
						
							|  |  |  |             record.append((thing[1], item)) | 
					
						
							|  |  |  |         return record | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |     return "BAD GENERIC ARGS: %r" % (what,) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | getdata = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getostype, "type"), | 
					
						
							|  |  |  |     (getpstr, "description"), | 
					
						
							|  |  |  |     (getword, "flags") | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getargument = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "name"), | 
					
						
							|  |  |  |     (getostype, "keyword"), | 
					
						
							|  |  |  |     (getdata, "what") | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getevent = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "name"), | 
					
						
							|  |  |  |     (getpstr, "description"), | 
					
						
							|  |  |  |     (getostype, "suite code"), | 
					
						
							|  |  |  |     (getostype, "event code"), | 
					
						
							|  |  |  |     (getdata, "returns"), | 
					
						
							|  |  |  |     (getdata, "accepts"), | 
					
						
							|  |  |  |     (getlist, "optional arguments", getargument) | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getproperty = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "name"), | 
					
						
							|  |  |  |     (getostype, "code"), | 
					
						
							|  |  |  |     (getdata, "what") | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getelement = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getostype, "type"), | 
					
						
							|  |  |  |     (getlist, "keyform", getostype) | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getclass = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "name"), | 
					
						
							|  |  |  |     (getostype, "class code"), | 
					
						
							|  |  |  |     (getpstr, "description"), | 
					
						
							|  |  |  |     (getlist, "properties", getproperty), | 
					
						
							|  |  |  |     (getlist, "elements", getelement) | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getcomparison = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "operator name"), | 
					
						
							|  |  |  |     (getostype, "operator ID"), | 
					
						
							|  |  |  |     (getpstr, "operator comment"), | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getenumerator = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "enumerator name"), | 
					
						
							|  |  |  |     (getostype, "enumerator ID"), | 
					
						
							|  |  |  |     (getpstr, "enumerator comment") | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getenumeration = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getostype, "enumeration ID"), | 
					
						
							|  |  |  |     (getlist, "enumerator", getenumerator) | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getsuite = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getpstr, "suite name"), | 
					
						
							|  |  |  |     (getpstr, "suite description"), | 
					
						
							|  |  |  |     (getostype, "suite ID"), | 
					
						
							|  |  |  |     (getword, "suite level"), | 
					
						
							|  |  |  |     (getword, "suite version"), | 
					
						
							|  |  |  |     (getlist, "events", getevent), | 
					
						
							|  |  |  |     (getlist, "classes", getclass), | 
					
						
							|  |  |  |     (getlist, "comparisons", getcomparison), | 
					
						
							|  |  |  |     (getlist, "enumerations", getenumeration) | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | getaete = [ | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     (getword, "major/minor version in BCD"), | 
					
						
							|  |  |  |     (getword, "language code"), | 
					
						
							|  |  |  |     (getword, "script code"), | 
					
						
							|  |  |  |     (getlist, "suites", getsuite) | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | def compileaete(aete, resinfo, fname, output=None, basepkgname=None, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         edit_modnames=None, creatorsignature=None, verbose=None): | 
					
						
							|  |  |  |     """Generate code for a full aete resource. fname passed for doc purposes""" | 
					
						
							|  |  |  |     [version, language, script, suites] = aete | 
					
						
							|  |  |  |     major, minor = divmod(version, 256) | 
					
						
							|  |  |  |     if not creatorsignature: | 
					
						
							|  |  |  |         creatorsignature, dummy = MacOS.GetCreatorAndType(fname) | 
					
						
							|  |  |  |     packagename = identify(os.path.splitext(os.path.basename(fname))[0]) | 
					
						
							|  |  |  |     if language: | 
					
						
							|  |  |  |         packagename = packagename+'_lang%d'%language | 
					
						
							|  |  |  |     if script: | 
					
						
							|  |  |  |         packagename = packagename+'_script%d'%script | 
					
						
							|  |  |  |     if len(packagename) > 27: | 
					
						
							|  |  |  |         packagename = packagename[:27] | 
					
						
							|  |  |  |     if output: | 
					
						
							|  |  |  |         # XXXX Put this in site-packages if it isn't a full pathname? | 
					
						
							|  |  |  |         if not os.path.exists(output): | 
					
						
							|  |  |  |             os.mkdir(output) | 
					
						
							|  |  |  |         pathname = output | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         pathname = EasyDialogs.AskFolder(message='Create and select package folder for %s'%packagename, | 
					
						
							|  |  |  |             defaultLocation=DEFAULT_USER_PACKAGEFOLDER) | 
					
						
							|  |  |  |         output = pathname | 
					
						
							|  |  |  |     if not pathname: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     packagename = os.path.split(os.path.normpath(pathname))[1] | 
					
						
							|  |  |  |     if not basepkgname: | 
					
						
							|  |  |  |         basepkgname = EasyDialogs.AskFolder(message='Package folder for base suite (usually StdSuites)', | 
					
						
							|  |  |  |             defaultLocation=DEFAULT_STANDARD_PACKAGEFOLDER) | 
					
						
							|  |  |  |     if basepkgname: | 
					
						
							|  |  |  |         dirname, basepkgname = os.path.split(os.path.normpath(basepkgname)) | 
					
						
							|  |  |  |         if dirname and not dirname in sys.path: | 
					
						
							|  |  |  |             sys.path.insert(0, dirname) | 
					
						
							|  |  |  |         basepackage = __import__(basepkgname) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         basepackage = None | 
					
						
							|  |  |  |     suitelist = [] | 
					
						
							|  |  |  |     allprecompinfo = [] | 
					
						
							|  |  |  |     allsuites = [] | 
					
						
							|  |  |  |     for suite in suites: | 
					
						
							|  |  |  |         compiler = SuiteCompiler(suite, basepackage, output, edit_modnames, verbose) | 
					
						
							|  |  |  |         code, modname, precompinfo = compiler.precompilesuite() | 
					
						
							|  |  |  |         if not code: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         allprecompinfo = allprecompinfo + precompinfo | 
					
						
							|  |  |  |         suiteinfo = suite, pathname, modname | 
					
						
							|  |  |  |         suitelist.append((code, modname)) | 
					
						
							|  |  |  |         allsuites.append(compiler) | 
					
						
							|  |  |  |     for compiler in allsuites: | 
					
						
							|  |  |  |         compiler.compilesuite(major, minor, language, script, fname, allprecompinfo) | 
					
						
							|  |  |  |     initfilename = os.path.join(output, '__init__.py') | 
					
						
							|  |  |  |     fp = open(initfilename, 'w') | 
					
						
							|  |  |  |     MacOS.SetCreatorAndType(initfilename, 'Pyth', 'TEXT') | 
					
						
							|  |  |  |     fp.write('"""\n') | 
					
						
							|  |  |  |     fp.write("Package generated from %s\n"%ascii(fname)) | 
					
						
							|  |  |  |     if resinfo: | 
					
						
							|  |  |  |         fp.write("Resource %s resid %d %s\n"%(ascii(resinfo[1]), resinfo[0], ascii(resinfo[2]))) | 
					
						
							|  |  |  |     fp.write('"""\n') | 
					
						
							|  |  |  |     fp.write('import aetools\n') | 
					
						
							|  |  |  |     fp.write('Error = aetools.Error\n') | 
					
						
							|  |  |  |     suitelist.sort() | 
					
						
							|  |  |  |     for code, modname in suitelist: | 
					
						
							|  |  |  |         fp.write("import %s\n" % modname) | 
					
						
							|  |  |  |     fp.write("\n\n_code_to_module = {\n") | 
					
						
							|  |  |  |     for code, modname in suitelist: | 
					
						
							|  |  |  |         fp.write("    '%s' : %s,\n"%(ascii(code), modname)) | 
					
						
							|  |  |  |     fp.write("}\n\n") | 
					
						
							|  |  |  |     fp.write("\n\n_code_to_fullname = {\n") | 
					
						
							|  |  |  |     for code, modname in suitelist: | 
					
						
							|  |  |  |         fp.write("    '%s' : ('%s.%s', '%s'),\n"%(ascii(code), packagename, modname, modname)) | 
					
						
							|  |  |  |     fp.write("}\n\n") | 
					
						
							|  |  |  |     for code, modname in suitelist: | 
					
						
							|  |  |  |         fp.write("from %s import *\n"%modname) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     # Generate property dicts and element dicts for all types declared in this module | 
					
						
							|  |  |  |     fp.write("\ndef getbaseclasses(v):\n") | 
					
						
							|  |  |  |     fp.write("    if not getattr(v, '_propdict', None):\n") | 
					
						
							|  |  |  |     fp.write("        v._propdict = {}\n") | 
					
						
							|  |  |  |     fp.write("        v._elemdict = {}\n") | 
					
						
							|  |  |  |     fp.write("        for superclassname in getattr(v, '_superclassnames', []):\n") | 
					
						
							|  |  |  |     fp.write("            superclass = eval(superclassname)\n") | 
					
						
							|  |  |  |     fp.write("            getbaseclasses(superclass)\n") | 
					
						
							|  |  |  |     fp.write("            v._propdict.update(getattr(superclass, '_propdict', {}))\n") | 
					
						
							|  |  |  |     fp.write("            v._elemdict.update(getattr(superclass, '_elemdict', {}))\n") | 
					
						
							|  |  |  |     fp.write("        v._propdict.update(getattr(v, '_privpropdict', {}))\n") | 
					
						
							|  |  |  |     fp.write("        v._elemdict.update(getattr(v, '_privelemdict', {}))\n") | 
					
						
							|  |  |  |     fp.write("\n") | 
					
						
							|  |  |  |     fp.write("import StdSuites\n") | 
					
						
							|  |  |  |     allprecompinfo.sort() | 
					
						
							|  |  |  |     if allprecompinfo: | 
					
						
							|  |  |  |         fp.write("\n#\n# Set property and element dictionaries now that all classes have been defined\n#\n") | 
					
						
							|  |  |  |         for codenamemapper in allprecompinfo: | 
					
						
							|  |  |  |             for k, v in codenamemapper.getall('class'): | 
					
						
							|  |  |  |                 fp.write("getbaseclasses(%s)\n" % v) | 
					
						
							| 
									
										
										
										
											2002-08-07 14:49:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     # Generate a code-to-name mapper for all of the types (classes) declared in this module | 
					
						
							| 
									
										
										
										
											2003-06-13 14:27:35 +00:00
										 |  |  |     application_class = None | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     if allprecompinfo: | 
					
						
							|  |  |  |         fp.write("\n#\n# Indices of types declared in this module\n#\n") | 
					
						
							|  |  |  |         fp.write("_classdeclarations = {\n") | 
					
						
							|  |  |  |         for codenamemapper in allprecompinfo: | 
					
						
							|  |  |  |             for k, v in codenamemapper.getall('class'): | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                 fp.write("    %r : %s,\n" % (k, v)) | 
					
						
							| 
									
										
										
										
											2003-06-18 14:17:34 +00:00
										 |  |  |                 if k == 'capp': | 
					
						
							|  |  |  |                     application_class = v | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         fp.write("}\n") | 
					
						
							| 
									
										
										
										
											2002-08-07 14:49:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     if suitelist: | 
					
						
							|  |  |  |         fp.write("\n\nclass %s(%s_Events"%(packagename, suitelist[0][1])) | 
					
						
							|  |  |  |         for code, modname in suitelist[1:]: | 
					
						
							|  |  |  |             fp.write(",\n        %s_Events"%modname) | 
					
						
							|  |  |  |         fp.write(",\n        aetools.TalkTo):\n") | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |         fp.write("    _signature = %r\n\n"%(creatorsignature,)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         fp.write("    _moduleName = '%s'\n\n"%packagename) | 
					
						
							| 
									
										
										
										
											2003-06-13 14:27:35 +00:00
										 |  |  |         if application_class: | 
					
						
							|  |  |  |             fp.write("    _elemdict = %s._elemdict\n" % application_class) | 
					
						
							|  |  |  |             fp.write("    _propdict = %s._propdict\n" % application_class) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     fp.close() | 
					
						
							| 
									
										
										
										
											2000-08-20 19:30:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-01 14:25:49 +00:00
										 |  |  | class SuiteCompiler: | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def __init__(self, suite, basepackage, output, edit_modnames, verbose): | 
					
						
							|  |  |  |         self.suite = suite | 
					
						
							|  |  |  |         self.basepackage = basepackage | 
					
						
							|  |  |  |         self.edit_modnames = edit_modnames | 
					
						
							|  |  |  |         self.output = output | 
					
						
							|  |  |  |         self.verbose = verbose | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         # Set by precompilesuite | 
					
						
							|  |  |  |         self.pathname = None | 
					
						
							|  |  |  |         self.modname = None | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         # Set by compilesuite | 
					
						
							|  |  |  |         self.fp = None | 
					
						
							|  |  |  |         self.basemodule = None | 
					
						
							|  |  |  |         self.enumsneeded = {} | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def precompilesuite(self): | 
					
						
							|  |  |  |         """Parse a single suite without generating the output. This step is needed
 | 
					
						
							|  |  |  |         so we can resolve recursive references by suites to enums/comps/etc declared | 
					
						
							|  |  |  |         in other suites"""
 | 
					
						
							|  |  |  |         [name, desc, code, level, version, events, classes, comps, enums] = self.suite | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         modname = identify(name) | 
					
						
							|  |  |  |         if len(modname) > 28: | 
					
						
							|  |  |  |             modname = modname[:27] | 
					
						
							|  |  |  |         if self.edit_modnames is None: | 
					
						
							|  |  |  |             self.pathname = EasyDialogs.AskFileForSave(message='Python output file', | 
					
						
							|  |  |  |                 savedFileName=modname+'.py') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             for old, new in self.edit_modnames: | 
					
						
							|  |  |  |                 if old == modname: | 
					
						
							|  |  |  |                     modname = new | 
					
						
							|  |  |  |             if modname: | 
					
						
							|  |  |  |                 self.pathname = os.path.join(self.output, modname + '.py') | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.pathname = None | 
					
						
							|  |  |  |         if not self.pathname: | 
					
						
							|  |  |  |             return None, None, None | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.modname = os.path.splitext(os.path.split(self.pathname)[1])[0] | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         if self.basepackage and self.basepackage._code_to_module.has_key(code): | 
					
						
							|  |  |  |             # We are an extension of a baseclass (usually an application extending | 
					
						
							|  |  |  |             # Standard_Suite or so). Import everything from our base module | 
					
						
							|  |  |  |             basemodule = self.basepackage._code_to_module[code] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # We are not an extension. | 
					
						
							|  |  |  |             basemodule = None | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.enumsneeded = {} | 
					
						
							|  |  |  |         for event in events: | 
					
						
							|  |  |  |             self.findenumsinevent(event) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         objc = ObjectCompiler(None, self.modname, basemodule, interact=(self.edit_modnames is None), | 
					
						
							|  |  |  |             verbose=self.verbose) | 
					
						
							|  |  |  |         for cls in classes: | 
					
						
							|  |  |  |             objc.compileclass(cls) | 
					
						
							|  |  |  |         for cls in classes: | 
					
						
							|  |  |  |             objc.fillclasspropsandelems(cls) | 
					
						
							|  |  |  |         for comp in comps: | 
					
						
							|  |  |  |             objc.compilecomparison(comp) | 
					
						
							|  |  |  |         for enum in enums: | 
					
						
							|  |  |  |             objc.compileenumeration(enum) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         for enum in self.enumsneeded.keys(): | 
					
						
							|  |  |  |             objc.checkforenum(enum) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         objc.dumpindex() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         precompinfo = objc.getprecompinfo(self.modname) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         return code, self.modname, precompinfo | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compilesuite(self, major, minor, language, script, fname, precompinfo): | 
					
						
							|  |  |  |         """Generate code for a single suite""" | 
					
						
							|  |  |  |         [name, desc, code, level, version, events, classes, comps, enums] = self.suite | 
					
						
							|  |  |  |         # Sort various lists, so re-generated source is easier compared | 
					
						
							|  |  |  |         def class_sorter(k1, k2): | 
					
						
							|  |  |  |             """Sort classes by code, and make sure main class sorts before synonyms""" | 
					
						
							|  |  |  |             # [name, code, desc, properties, elements] = cls | 
					
						
							|  |  |  |             if k1[1] < k2[1]: return -1 | 
					
						
							|  |  |  |             if k1[1] > k2[1]: return 1 | 
					
						
							|  |  |  |             if not k2[3] or k2[3][0][1] == 'c@#!': | 
					
						
							|  |  |  |                 # This is a synonym, the other one is better | 
					
						
							|  |  |  |                 return -1 | 
					
						
							|  |  |  |             if not k1[3] or k1[3][0][1] == 'c@#!': | 
					
						
							|  |  |  |                 # This is a synonym, the other one is better | 
					
						
							|  |  |  |                 return 1 | 
					
						
							|  |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         events.sort() | 
					
						
							|  |  |  |         classes.sort(class_sorter) | 
					
						
							|  |  |  |         comps.sort() | 
					
						
							|  |  |  |         enums.sort() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.fp = fp = open(self.pathname, 'w') | 
					
						
							|  |  |  |         MacOS.SetCreatorAndType(self.pathname, 'Pyth', 'TEXT') | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc))) | 
					
						
							|  |  |  |         fp.write("Level %d, version %d\n\n" % (level, version)) | 
					
						
							|  |  |  |         fp.write("Generated from %s\n"%ascii(fname)) | 
					
						
							|  |  |  |         fp.write("AETE/AEUT resource version %d/%d, language %d, script %d\n" % \ | 
					
						
							|  |  |  |             (major, minor, language, script)) | 
					
						
							|  |  |  |         fp.write('"""\n\n') | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         fp.write('import aetools\n') | 
					
						
							|  |  |  |         fp.write('import MacOS\n\n') | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |         fp.write("_code = %r\n\n"% (code,)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         if self.basepackage and self.basepackage._code_to_module.has_key(code): | 
					
						
							|  |  |  |             # We are an extension of a baseclass (usually an application extending | 
					
						
							|  |  |  |             # Standard_Suite or so). Import everything from our base module | 
					
						
							|  |  |  |             fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code][0]) | 
					
						
							|  |  |  |             basemodule = self.basepackage._code_to_module[code] | 
					
						
							|  |  |  |         elif self.basepackage and self.basepackage._code_to_module.has_key(code.lower()): | 
					
						
							|  |  |  |             # This is needed by CodeWarrior and some others. | 
					
						
							|  |  |  |             fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code.lower()][0]) | 
					
						
							|  |  |  |             basemodule = self.basepackage._code_to_module[code.lower()] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # We are not an extension. | 
					
						
							|  |  |  |             basemodule = None | 
					
						
							|  |  |  |         self.basemodule = basemodule | 
					
						
							|  |  |  |         self.compileclassheader() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.enumsneeded = {} | 
					
						
							|  |  |  |         if events: | 
					
						
							|  |  |  |             for event in events: | 
					
						
							|  |  |  |                 self.compileevent(event) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             fp.write("    pass\n\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         objc = ObjectCompiler(fp, self.modname, basemodule, precompinfo, interact=(self.edit_modnames is None), | 
					
						
							|  |  |  |             verbose=self.verbose) | 
					
						
							|  |  |  |         for cls in classes: | 
					
						
							|  |  |  |             objc.compileclass(cls) | 
					
						
							|  |  |  |         for cls in classes: | 
					
						
							|  |  |  |             objc.fillclasspropsandelems(cls) | 
					
						
							|  |  |  |         for comp in comps: | 
					
						
							|  |  |  |             objc.compilecomparison(comp) | 
					
						
							|  |  |  |         for enum in enums: | 
					
						
							|  |  |  |             objc.compileenumeration(enum) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         for enum in self.enumsneeded.keys(): | 
					
						
							|  |  |  |             objc.checkforenum(enum) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         objc.dumpindex() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compileclassheader(self): | 
					
						
							|  |  |  |         """Generate class boilerplate""" | 
					
						
							|  |  |  |         classname = '%s_Events'%self.modname | 
					
						
							|  |  |  |         if self.basemodule: | 
					
						
							|  |  |  |             modshortname = string.split(self.basemodule.__name__, '.')[-1] | 
					
						
							|  |  |  |             baseclassname = '%s_Events'%modshortname | 
					
						
							|  |  |  |             self.fp.write("class %s(%s):\n\n"%(classname, baseclassname)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fp.write("class %s:\n\n"%classname) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compileevent(self, event): | 
					
						
							|  |  |  |         """Generate code for a single event""" | 
					
						
							|  |  |  |         [name, desc, code, subcode, returns, accepts, arguments] = event | 
					
						
							|  |  |  |         fp = self.fp | 
					
						
							|  |  |  |         funcname = identify(name) | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # generate name->keyword map | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         if arguments: | 
					
						
							|  |  |  |             fp.write("    _argmap_%s = {\n"%funcname) | 
					
						
							|  |  |  |             for a in arguments: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                 fp.write("        %r : %r,\n"%(identify(a[0]), a[1])) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |             fp.write("    }\n\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         # | 
					
						
							|  |  |  |         # Generate function header | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         has_arg = (not is_null(accepts)) | 
					
						
							|  |  |  |         opt_arg = (has_arg and is_optional(accepts)) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         fp.write("    def %s(self, "%funcname) | 
					
						
							|  |  |  |         if has_arg: | 
					
						
							|  |  |  |             if not opt_arg: | 
					
						
							|  |  |  |                 fp.write("_object, ")       # Include direct object, if it has one | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 fp.write("_object=None, ")  # Also include if it is optional | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             fp.write("_no_object=None, ")   # For argument checking | 
					
						
							|  |  |  |         fp.write("_attributes={}, **_arguments):\n")    # include attribute dict and args | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Generate doc string (important, since it may be the only | 
					
						
							|  |  |  |         # available documentation, due to our name-remaping) | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         fp.write('        """%s: %s\n'%(ascii(name), ascii(desc))) | 
					
						
							|  |  |  |         if has_arg: | 
					
						
							|  |  |  |             fp.write("        Required argument: %s\n"%getdatadoc(accepts)) | 
					
						
							|  |  |  |         elif opt_arg: | 
					
						
							|  |  |  |             fp.write("        Optional argument: %s\n"%getdatadoc(accepts)) | 
					
						
							|  |  |  |         for arg in arguments: | 
					
						
							|  |  |  |             fp.write("        Keyword argument %s: %s\n"%(identify(arg[0]), | 
					
						
							|  |  |  |                     getdatadoc(arg[2]))) | 
					
						
							|  |  |  |         fp.write("        Keyword argument _attributes: AppleEvent attribute dictionary\n") | 
					
						
							|  |  |  |         if not is_null(returns): | 
					
						
							|  |  |  |             fp.write("        Returns: %s\n"%getdatadoc(returns)) | 
					
						
							|  |  |  |         fp.write('        """\n') | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Fiddle the args so everything ends up in 'arguments' dictionary | 
					
						
							|  |  |  |         # | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |         fp.write("        _code = %r\n"% (code,)) | 
					
						
							|  |  |  |         fp.write("        _subcode = %r\n\n"% (subcode,)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         # | 
					
						
							|  |  |  |         # Do keyword name substitution | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         if arguments: | 
					
						
							|  |  |  |             fp.write("        aetools.keysubst(_arguments, self._argmap_%s)\n"%funcname) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             fp.write("        if _arguments: raise TypeError, 'No optional args expected'\n") | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Stuff required arg (if there is one) into arguments | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         if has_arg: | 
					
						
							|  |  |  |             fp.write("        _arguments['----'] = _object\n") | 
					
						
							|  |  |  |         elif opt_arg: | 
					
						
							|  |  |  |             fp.write("        if _object:\n") | 
					
						
							|  |  |  |             fp.write("            _arguments['----'] = _object\n") | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2008-03-29 15:24:25 +00:00
										 |  |  |             fp.write("        if _no_object is not None: raise TypeError, 'No direct arg expected'\n") | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         fp.write("\n") | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Do enum-name substitution | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         for a in arguments: | 
					
						
							|  |  |  |             if is_enum(a[2]): | 
					
						
							|  |  |  |                 kname = a[1] | 
					
						
							|  |  |  |                 ename = a[2][0] | 
					
						
							|  |  |  |                 if ename <> '****': | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                     fp.write("        aetools.enumsubst(_arguments, %r, _Enum_%s)\n" % | 
					
						
							|  |  |  |                         (kname, identify(ename))) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |                     self.enumsneeded[ename] = 1 | 
					
						
							|  |  |  |         fp.write("\n") | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Do the transaction | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         fp.write("        _reply, _arguments, _attributes = self.send(_code, _subcode,\n") | 
					
						
							|  |  |  |         fp.write("                _arguments, _attributes)\n") | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Error handling | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         fp.write("        if _arguments.get('errn', 0):\n") | 
					
						
							|  |  |  |         fp.write("            raise aetools.Error, aetools.decodeerror(_arguments)\n") | 
					
						
							|  |  |  |         fp.write("        # XXXX Optionally decode result\n") | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # Decode result | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         fp.write("        if _arguments.has_key('----'):\n") | 
					
						
							|  |  |  |         if is_enum(returns): | 
					
						
							|  |  |  |             fp.write("            # XXXX Should do enum remapping here...\n") | 
					
						
							|  |  |  |         fp.write("            return _arguments['----']\n") | 
					
						
							|  |  |  |         fp.write("\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def findenumsinevent(self, event): | 
					
						
							|  |  |  |         """Find all enums for a single event""" | 
					
						
							|  |  |  |         [name, desc, code, subcode, returns, accepts, arguments] = event | 
					
						
							|  |  |  |         for a in arguments: | 
					
						
							|  |  |  |             if is_enum(a[2]): | 
					
						
							|  |  |  |                 ename = a[2][0] | 
					
						
							|  |  |  |                 if ename <> '****': | 
					
						
							|  |  |  |                     self.enumsneeded[ename] = 1 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-20 19:30:56 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # This class stores the code<->name translations for a single module. It is used | 
					
						
							|  |  |  | # to keep the information while we're compiling the module, but we also keep these objects | 
					
						
							|  |  |  | # around so if one suite refers to, say, an enum in another suite we know where to | 
					
						
							|  |  |  | # find it. Finally, if we really can't find a code, the user can add modules by | 
					
						
							|  |  |  | # hand. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | class CodeNameMapper: | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def __init__(self, interact=1, verbose=None): | 
					
						
							|  |  |  |         self.code2name = { | 
					
						
							|  |  |  |             "property" : {}, | 
					
						
							|  |  |  |             "class" : {}, | 
					
						
							|  |  |  |             "enum" : {}, | 
					
						
							|  |  |  |             "comparison" : {}, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         self.name2code =  { | 
					
						
							|  |  |  |             "property" : {}, | 
					
						
							|  |  |  |             "class" : {}, | 
					
						
							|  |  |  |             "enum" : {}, | 
					
						
							|  |  |  |             "comparison" : {}, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         self.modulename = None | 
					
						
							|  |  |  |         self.star_imported = 0 | 
					
						
							|  |  |  |         self.can_interact = interact | 
					
						
							|  |  |  |         self.verbose = verbose | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def addnamecode(self, type, name, code): | 
					
						
							|  |  |  |         self.name2code[type][name] = code | 
					
						
							|  |  |  |         if not self.code2name[type].has_key(code): | 
					
						
							|  |  |  |             self.code2name[type][code] = name | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def hasname(self, name): | 
					
						
							|  |  |  |         for dict in self.name2code.values(): | 
					
						
							|  |  |  |             if dict.has_key(name): | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def hascode(self, type, code): | 
					
						
							|  |  |  |         return self.code2name[type].has_key(code) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def findcodename(self, type, code): | 
					
						
							|  |  |  |         if not self.hascode(type, code): | 
					
						
							|  |  |  |             return None, None, None | 
					
						
							|  |  |  |         name = self.code2name[type][code] | 
					
						
							|  |  |  |         if self.modulename and not self.star_imported: | 
					
						
							|  |  |  |             qualname = '%s.%s'%(self.modulename, name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             qualname = name | 
					
						
							|  |  |  |         return name, qualname, self.modulename | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def getall(self, type): | 
					
						
							|  |  |  |         return self.code2name[type].items() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def addmodule(self, module, name, star_imported): | 
					
						
							|  |  |  |         self.modulename = name | 
					
						
							|  |  |  |         self.star_imported = star_imported | 
					
						
							|  |  |  |         for code, name in module._propdeclarations.items(): | 
					
						
							|  |  |  |             self.addnamecode('property', name, code) | 
					
						
							|  |  |  |         for code, name in module._classdeclarations.items(): | 
					
						
							|  |  |  |             self.addnamecode('class', name, code) | 
					
						
							|  |  |  |         for code in module._enumdeclarations.keys(): | 
					
						
							|  |  |  |             self.addnamecode('enum', '_Enum_'+identify(code), code) | 
					
						
							|  |  |  |         for code, name in module._compdeclarations.items(): | 
					
						
							|  |  |  |             self.addnamecode('comparison', name, code) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def prepareforexport(self, name=None): | 
					
						
							|  |  |  |         if not self.modulename: | 
					
						
							|  |  |  |             self.modulename = name | 
					
						
							|  |  |  |         return self | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-08 14:49:02 +00:00
										 |  |  | class ObjectCompiler: | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  |     def __init__(self, fp, modname, basesuite, othernamemappers=None, interact=1, | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |             verbose=None): | 
					
						
							|  |  |  |         self.fp = fp | 
					
						
							|  |  |  |         self.verbose = verbose | 
					
						
							|  |  |  |         self.basesuite = basesuite | 
					
						
							|  |  |  |         self.can_interact = interact | 
					
						
							|  |  |  |         self.modulename = modname | 
					
						
							|  |  |  |         self.namemappers = [CodeNameMapper(self.can_interact, self.verbose)] | 
					
						
							|  |  |  |         if othernamemappers: | 
					
						
							|  |  |  |             self.othernamemappers = othernamemappers[:] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.othernamemappers = [] | 
					
						
							|  |  |  |         if basesuite: | 
					
						
							|  |  |  |             basemapper = CodeNameMapper(self.can_interact, self.verbose) | 
					
						
							|  |  |  |             basemapper.addmodule(basesuite, '', 1) | 
					
						
							|  |  |  |             self.namemappers.append(basemapper) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def getprecompinfo(self, modname): | 
					
						
							|  |  |  |         list = [] | 
					
						
							|  |  |  |         for mapper in self.namemappers: | 
					
						
							|  |  |  |             emapper = mapper.prepareforexport(modname) | 
					
						
							|  |  |  |             if emapper: | 
					
						
							|  |  |  |                 list.append(emapper) | 
					
						
							|  |  |  |         return list | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def findcodename(self, type, code): | 
					
						
							|  |  |  |         while 1: | 
					
						
							|  |  |  |             # First try: check whether we already know about this code. | 
					
						
							|  |  |  |             for mapper in self.namemappers: | 
					
						
							|  |  |  |                 if mapper.hascode(type, code): | 
					
						
							|  |  |  |                     return mapper.findcodename(type, code) | 
					
						
							|  |  |  |             # Second try: maybe one of the other modules knows about it. | 
					
						
							|  |  |  |             for mapper in self.othernamemappers: | 
					
						
							|  |  |  |                 if mapper.hascode(type, code): | 
					
						
							|  |  |  |                     self.othernamemappers.remove(mapper) | 
					
						
							|  |  |  |                     self.namemappers.append(mapper) | 
					
						
							|  |  |  |                     if self.fp: | 
					
						
							|  |  |  |                         self.fp.write("import %s\n"%mapper.modulename) | 
					
						
							|  |  |  |                     break | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 # If all this has failed we ask the user for a guess on where it could | 
					
						
							|  |  |  |                 # be and retry. | 
					
						
							|  |  |  |                 if self.fp: | 
					
						
							|  |  |  |                     m = self.askdefinitionmodule(type, code) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     m = None | 
					
						
							|  |  |  |                 if not m: return None, None, None | 
					
						
							|  |  |  |                 mapper = CodeNameMapper(self.can_interact, self.verbose) | 
					
						
							|  |  |  |                 mapper.addmodule(m, m.__name__, 0) | 
					
						
							|  |  |  |                 self.namemappers.append(mapper) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def hasname(self, name): | 
					
						
							|  |  |  |         for mapper in self.othernamemappers: | 
					
						
							|  |  |  |             if mapper.hasname(name) and mapper.modulename != self.modulename: | 
					
						
							|  |  |  |                 if self.verbose: | 
					
						
							|  |  |  |                     print >>self.verbose, "Duplicate Python identifier:", name, self.modulename, mapper.modulename | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def askdefinitionmodule(self, type, code): | 
					
						
							|  |  |  |         if not self.can_interact: | 
					
						
							|  |  |  |             if self.verbose: | 
					
						
							|  |  |  |                 print >>self.verbose, "** No definition for %s '%s' found" % (type, code) | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         path = EasyDialogs.AskFileForSave(message='Where is %s %s declared?'%(type, code)) | 
					
						
							|  |  |  |         if not path: return | 
					
						
							|  |  |  |         path, file = os.path.split(path) | 
					
						
							|  |  |  |         modname = os.path.splitext(file)[0] | 
					
						
							|  |  |  |         if not path in sys.path: | 
					
						
							|  |  |  |             sys.path.insert(0, path) | 
					
						
							|  |  |  |         m = __import__(modname) | 
					
						
							|  |  |  |         self.fp.write("import %s\n"%modname) | 
					
						
							|  |  |  |         return m | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compileclass(self, cls): | 
					
						
							|  |  |  |         [name, code, desc, properties, elements] = cls | 
					
						
							|  |  |  |         pname = identify(name) | 
					
						
							|  |  |  |         if self.namemappers[0].hascode('class', code): | 
					
						
							|  |  |  |             # plural forms and such | 
					
						
							|  |  |  |             othername, dummy, dummy = self.namemappers[0].findcodename('class', code) | 
					
						
							|  |  |  |             if self.fp: | 
					
						
							|  |  |  |                 self.fp.write("\n%s = %s\n"%(pname, othername)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if self.fp: | 
					
						
							|  |  |  |                 self.fp.write('\nclass %s(aetools.ComponentItem):\n' % pname) | 
					
						
							|  |  |  |                 self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(desc))) | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                 self.fp.write('    want = %r\n' % (code,)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.namemappers[0].addnamecode('class', pname, code) | 
					
						
							| 
									
										
										
										
											2003-06-13 14:27:35 +00:00
										 |  |  |         is_application_class = (code == 'capp') | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         properties.sort() | 
					
						
							|  |  |  |         for prop in properties: | 
					
						
							| 
									
										
										
										
											2003-06-13 14:27:35 +00:00
										 |  |  |             self.compileproperty(prop, is_application_class) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         elements.sort() | 
					
						
							|  |  |  |         for elem in elements: | 
					
						
							|  |  |  |             self.compileelement(elem) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-13 14:27:35 +00:00
										 |  |  |     def compileproperty(self, prop, is_application_class=False): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         [name, code, what] = prop | 
					
						
							|  |  |  |         if code == 'c@#!': | 
					
						
							|  |  |  |             # Something silly with plurals. Skip it. | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         pname = identify(name) | 
					
						
							|  |  |  |         if self.namemappers[0].hascode('property', code): | 
					
						
							|  |  |  |             # plural forms and such | 
					
						
							|  |  |  |             othername, dummy, dummy = self.namemappers[0].findcodename('property', code) | 
					
						
							|  |  |  |             if pname == othername: | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             if self.fp: | 
					
						
							|  |  |  |                 self.fp.write("\n_Prop_%s = _Prop_%s\n"%(pname, othername)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if self.fp: | 
					
						
							|  |  |  |                 self.fp.write("class _Prop_%s(aetools.NProperty):\n" % pname) | 
					
						
							|  |  |  |                 self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(what[1]))) | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                 self.fp.write("    which = %r\n" % (code,)) | 
					
						
							|  |  |  |                 self.fp.write("    want = %r\n" % (what[0],)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.namemappers[0].addnamecode('property', pname, code) | 
					
						
							| 
									
										
										
										
											2003-06-13 14:27:35 +00:00
										 |  |  |         if is_application_class and self.fp: | 
					
						
							|  |  |  |             self.fp.write("%s = _Prop_%s()\n" % (pname, pname)) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compileelement(self, elem): | 
					
						
							|  |  |  |         [code, keyform] = elem | 
					
						
							|  |  |  |         if self.fp: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             self.fp.write("#        element %r as %s\n" % (code, keyform)) | 
					
						
							| 
									
										
										
										
											1997-08-08 14:49:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def fillclasspropsandelems(self, cls): | 
					
						
							|  |  |  |         [name, code, desc, properties, elements] = cls | 
					
						
							|  |  |  |         cname = identify(name) | 
					
						
							|  |  |  |         if self.namemappers[0].hascode('class', code) and \ | 
					
						
							|  |  |  |                 self.namemappers[0].findcodename('class', code)[0] != cname: | 
					
						
							|  |  |  |             # This is an other name (plural or so) for something else. Skip. | 
					
						
							|  |  |  |             if self.fp and (elements or len(properties) > 1 or (len(properties) == 1 and | 
					
						
							|  |  |  |                 properties[0][1] != 'c@#!')): | 
					
						
							|  |  |  |                 if self.verbose: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                     print >>self.verbose, '** Skip multiple %s of %s (code %r)' % (cname, self.namemappers[0].findcodename('class', code)[0], code) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |                 raise RuntimeError, "About to skip non-empty class" | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         plist = [] | 
					
						
							|  |  |  |         elist = [] | 
					
						
							|  |  |  |         superclasses = [] | 
					
						
							|  |  |  |         for prop in properties: | 
					
						
							|  |  |  |             [pname, pcode, what] = prop | 
					
						
							|  |  |  |             if pcode == "c@#^": | 
					
						
							|  |  |  |                 superclasses.append(what) | 
					
						
							|  |  |  |             if pcode == 'c@#!': | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             pname = identify(pname) | 
					
						
							|  |  |  |             plist.append(pname) | 
					
						
							| 
									
										
										
										
											2002-08-07 14:49:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         superclassnames = [] | 
					
						
							|  |  |  |         for superclass in superclasses: | 
					
						
							|  |  |  |             superId, superDesc, dummy = superclass | 
					
						
							|  |  |  |             superclassname, fullyqualifiedname, module = self.findcodename("class", superId) | 
					
						
							|  |  |  |             # I don't think this is correct: | 
					
						
							|  |  |  |             if superclassname == cname: | 
					
						
							|  |  |  |                 pass # superclassnames.append(fullyqualifiedname) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 superclassnames.append(superclassname) | 
					
						
							| 
									
										
										
										
											2002-08-07 14:49:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         if self.fp: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             self.fp.write("%s._superclassnames = %r\n"%(cname, superclassnames)) | 
					
						
							| 
									
										
										
										
											2002-08-07 14:49:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         for elem in elements: | 
					
						
							|  |  |  |             [ecode, keyform] = elem | 
					
						
							|  |  |  |             if ecode == 'c@#!': | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             name, ename, module = self.findcodename('class', ecode) | 
					
						
							|  |  |  |             if not name: | 
					
						
							|  |  |  |                 if self.fp: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                     self.fp.write("# XXXX %s element %r not found!!\n"%(cname, ecode)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 elist.append((name, ename)) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         plist.sort() | 
					
						
							|  |  |  |         elist.sort() | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         if self.fp: | 
					
						
							|  |  |  |             self.fp.write("%s._privpropdict = {\n"%cname) | 
					
						
							|  |  |  |             for n in plist: | 
					
						
							|  |  |  |                 self.fp.write("    '%s' : _Prop_%s,\n"%(n, n)) | 
					
						
							|  |  |  |             self.fp.write("}\n") | 
					
						
							|  |  |  |             self.fp.write("%s._privelemdict = {\n"%cname) | 
					
						
							|  |  |  |             for n, fulln in elist: | 
					
						
							|  |  |  |                 self.fp.write("    '%s' : %s,\n"%(n, fulln)) | 
					
						
							|  |  |  |             self.fp.write("}\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compilecomparison(self, comp): | 
					
						
							|  |  |  |         [name, code, comment] = comp | 
					
						
							|  |  |  |         iname = identify(name) | 
					
						
							|  |  |  |         self.namemappers[0].addnamecode('comparison', iname, code) | 
					
						
							|  |  |  |         if self.fp: | 
					
						
							|  |  |  |             self.fp.write("class %s(aetools.NComparison):\n" % iname) | 
					
						
							|  |  |  |             self.fp.write('    """%s - %s """\n' % (ascii(name), ascii(comment))) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compileenumeration(self, enum): | 
					
						
							|  |  |  |         [code, items] = enum | 
					
						
							|  |  |  |         name = "_Enum_%s" % identify(code) | 
					
						
							|  |  |  |         if self.fp: | 
					
						
							|  |  |  |             self.fp.write("%s = {\n" % name) | 
					
						
							|  |  |  |             for item in items: | 
					
						
							|  |  |  |                 self.compileenumerator(item) | 
					
						
							|  |  |  |             self.fp.write("}\n\n") | 
					
						
							|  |  |  |         self.namemappers[0].addnamecode('enum', name, code) | 
					
						
							|  |  |  |         return code | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def compileenumerator(self, item): | 
					
						
							|  |  |  |         [name, code, desc] = item | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |         self.fp.write("    %r : %r,\t# %s\n" % (identify(name), code, ascii(desc))) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def checkforenum(self, enum): | 
					
						
							|  |  |  |         """This enum code is used by an event. Make sure it's available""" | 
					
						
							|  |  |  |         name, fullname, module = self.findcodename('enum', enum) | 
					
						
							|  |  |  |         if not name: | 
					
						
							|  |  |  |             if self.fp: | 
					
						
							|  |  |  |                 self.fp.write("_Enum_%s = None # XXXX enum %s not found!!\n"%(identify(enum), ascii(enum))) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         if module: | 
					
						
							|  |  |  |             if self.fp: | 
					
						
							|  |  |  |                 self.fp.write("from %s import %s\n"%(module, name)) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     def dumpindex(self): | 
					
						
							|  |  |  |         if not self.fp: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         self.fp.write("\n#\n# Indices of types declared in this module\n#\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.fp.write("_classdeclarations = {\n") | 
					
						
							|  |  |  |         classlist = self.namemappers[0].getall('class') | 
					
						
							|  |  |  |         classlist.sort() | 
					
						
							|  |  |  |         for k, v in classlist: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             self.fp.write("    %r : %s,\n" % (k, v)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |         self.fp.write("}\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-12 22:27:11 +00:00
										 |  |  |         self.fp.write("\n_propdeclarations = {\n") | 
					
						
							|  |  |  |         proplist = self.namemappers[0].getall('property') | 
					
						
							|  |  |  |         proplist.sort() | 
					
						
							|  |  |  |         for k, v in proplist: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             self.fp.write("    %r : _Prop_%s,\n" % (k, v)) | 
					
						
							| 
									
										
										
										
											2003-04-12 22:27:11 +00:00
										 |  |  |         self.fp.write("}\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-12 22:27:11 +00:00
										 |  |  |         self.fp.write("\n_compdeclarations = {\n") | 
					
						
							|  |  |  |         complist = self.namemappers[0].getall('comparison') | 
					
						
							|  |  |  |         complist.sort() | 
					
						
							|  |  |  |         for k, v in complist: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             self.fp.write("    %r : %s,\n" % (k, v)) | 
					
						
							| 
									
										
										
										
											2003-04-12 22:27:11 +00:00
										 |  |  |         self.fp.write("}\n") | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-12 22:27:11 +00:00
										 |  |  |         self.fp.write("\n_enumdeclarations = {\n") | 
					
						
							|  |  |  |         enumlist = self.namemappers[0].getall('enum') | 
					
						
							|  |  |  |         enumlist.sort() | 
					
						
							|  |  |  |         for k, v in enumlist: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |             self.fp.write("    %r : %s,\n" % (k, v)) | 
					
						
							| 
									
										
										
										
											2003-04-12 22:27:11 +00:00
										 |  |  |         self.fp.write("}\n") | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def compiledata(data): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     [type, description, flags] = data | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |     return "%r -- %r %s" % (type, description, compiledataflags(flags)) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | def is_null(data): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     return data[0] == 'null' | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | def is_optional(data): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     return (data[2] & 0x8000) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | def is_enum(data): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     return (data[2] & 0x2000) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | def getdatadoc(data): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     [type, descr, flags] = data | 
					
						
							|  |  |  |     if descr: | 
					
						
							|  |  |  |         return ascii(descr) | 
					
						
							|  |  |  |     if type == '****': | 
					
						
							|  |  |  |         return 'anything' | 
					
						
							|  |  |  |     if type == 'obj ': | 
					
						
							|  |  |  |         return 'an AE object reference' | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |     return "undocumented, typecode %r"%(type,) | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | dataflagdict = {15: "optional", 14: "list", 13: "enum", 12: "mutable"} | 
					
						
							|  |  |  | def compiledataflags(flags): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     bits = [] | 
					
						
							|  |  |  |     for i in range(16): | 
					
						
							|  |  |  |         if flags & (1<<i): | 
					
						
							|  |  |  |             if i in dataflagdict.keys(): | 
					
						
							|  |  |  |                 bits.append(dataflagdict[i]) | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2004-02-12 17:35:32 +00:00
										 |  |  |                 bits.append(repr(i)) | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     return '[%s]' % string.join(bits) | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-08-07 14:49:00 +00:00
										 |  |  | def ascii(str): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """Return a string with all non-ascii characters hex-encoded""" | 
					
						
							|  |  |  |     if type(str) != type(''): | 
					
						
							|  |  |  |         return map(ascii, str) | 
					
						
							|  |  |  |     rv = '' | 
					
						
							|  |  |  |     for c in str: | 
					
						
							|  |  |  |         if c in ('\t', '\n', '\r') or ' ' <= c < chr(0x7f): | 
					
						
							|  |  |  |             rv = rv + c | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             rv = rv + '\\' + 'x%02.2x' % ord(c) | 
					
						
							|  |  |  |     return rv | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | def identify(str): | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """Turn any string into an identifier:
 | 
					
						
							|  |  |  |     - replace space by _ | 
					
						
							|  |  |  |     - replace other illegal chars by _xx_ (hex code) | 
					
						
							| 
									
										
										
										
											2003-04-16 13:10:53 +00:00
										 |  |  |     - append _ if the result is a python keyword | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     if not str: | 
					
						
							|  |  |  |         return "empty_ae_name_" | 
					
						
							|  |  |  |     rv = '' | 
					
						
							|  |  |  |     ok = string.ascii_letters + '_' | 
					
						
							|  |  |  |     ok2 = ok + string.digits | 
					
						
							|  |  |  |     for c in str: | 
					
						
							|  |  |  |         if c in ok: | 
					
						
							|  |  |  |             rv = rv + c | 
					
						
							|  |  |  |         elif c == ' ': | 
					
						
							|  |  |  |             rv = rv + '_' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             rv = rv + '_%02.2x_'%ord(c) | 
					
						
							|  |  |  |         ok = ok2 | 
					
						
							|  |  |  |     if keyword.iskeyword(rv): | 
					
						
							|  |  |  |         rv = rv + '_' | 
					
						
							|  |  |  |     return rv | 
					
						
							| 
									
										
										
										
											1995-07-17 11:43:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Call the main program | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							| 
									
										
										
										
											2003-04-09 13:25:43 +00:00
										 |  |  |     main() | 
					
						
							|  |  |  |     sys.exit(1) |