summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Mac/scripts/gensuitemodule.py142
1 files changed, 120 insertions, 22 deletions
diff --git a/Mac/scripts/gensuitemodule.py b/Mac/scripts/gensuitemodule.py
index 25595df..85cbe0d 100644
--- a/Mac/scripts/gensuitemodule.py
+++ b/Mac/scripts/gensuitemodule.py
@@ -1,7 +1,9 @@
"""
gensuitemodule - Generate an AE suite module from an aete/aeut resource
-Based on aete.py
+Based on aete.py.
+
+Reading and understanding this code is left as an exercise to the reader.
"""
import MacOS
@@ -18,9 +20,9 @@ def main():
fss, ok = macfs.PromptGetFile('Select file with aeut/aete resource:')
if not ok:
sys.exit(0)
- process(fss.as_pathname())
+ processfile(fss.as_pathname())
-def process(fullname):
+def processfile(fullname):
"""Process all resources in a single file"""
cur = CurResFile()
print fullname
@@ -35,19 +37,24 @@ def process(fullname):
res = Get1IndResource('aeut', 1+i)
resources.append(res)
print "\nLISTING aete+aeut RESOURCES IN", `fullname`
+ aetelist = []
for res in resources:
print "decoding", res.GetResInfo(), "..."
data = res.data
aete = decode(data)
- # switch back (needed for dialogs in Python)
- UseResFile(cur)
- compileaete(aete, fullname)
- UseResFile(rf)
+ aetelist.append((aete, res.GetResInfo()))
finally:
if rf <> cur:
CloseResFile(rf)
UseResFile(cur)
+ # switch back (needed for dialogs in Python)
+ UseResFile(cur)
+ compileaetelist(aetelist, fullname)
+def compileaetelist(aetelist, fullname):
+ for aete, resinfo in aetelist:
+ compileaete(aete, resinfo, fullname)
+
def decode(data):
"""Decode a resource into a python data structure"""
f = StringIO.StringIO(data)
@@ -211,21 +218,81 @@ getaete = [
(getlist, "suites", getsuite)
]
-def compileaete(aete, fname):
+def compileaete(aete, resinfo, fname):
"""Generate code for a full aete resource. fname passed for doc purposes"""
[version, language, script, suites] = aete
major, minor = divmod(version, 256)
+ fss = macfs.FSSpec(fname)
+ creatorsignature, dummy = fss.GetCreatorType()
+ packagename = identify(os.path.basename(fname))
+ if language:
+ packagename = packagename+'_lang%d'%language
+ if script:
+ packagename = packagename+'_script%d'%script
+ if len(packagename) > 27:
+ packagename = packagename[:27]
+ macfs.SetFolder(os.path.join(sys.prefix, ':Mac:Lib:lib-scriptpackages'))
+ fss, ok = macfs.GetDirectory('Package folder for %s'%packagename)
+ if not ok:
+ return
+ pathname = fss.as_pathname()
+ packagename = os.path.split(os.path.normpath(pathname))[1]
+ fss, ok = macfs.GetDirectory('Package folder for base suite (usually StdSuites)')
+ if ok:
+ dirname, basepkgname = os.path.split(os.path.normpath(fss.as_pathname()))
+ if not dirname in sys.path:
+ sys.path.insert(0, dirname)
+ basepackage = __import__(basepkgname)
+ else:
+ basepackage = None
+ macfs.SetFolder(pathname)
+ suitelist = []
for suite in suites:
- compilesuite(suite, major, minor, language, script, fname)
-
-def compilesuite(suite, major, minor, language, script, fname):
+ code, modname = compilesuite(suite, major, minor, language, script, fname, basepackage)
+ if modname:
+ suitelist.append((code, modname))
+ fss, ok = macfs.StandardPutFile('Package module', '__init__.py')
+ if not ok:
+ return
+ fp = open(fss.as_pathname(), 'w')
+ fss.SetCreatorType('Pyth', 'TEXT')
+ fp.write('"""\n')
+ fp.write("Package generated from %s\n"%fname)
+ fp.write("Resource %s resid %d %s\n"%(resinfo[1], resinfo[0], resinfo[2]))
+ fp.write('"""\n')
+ fp.write('import aetools\n')
+ 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("\t'%s' : %s,\n"%(code, modname))
+ fp.write("}\n\n")
+ fp.write("\n\n_code_to_fullname = {\n")
+ for code, modname in suitelist:
+ fp.write("\t'%s' : '%s.%s',\n"%(code, packagename, modname))
+ fp.write("}\n\n")
+ for code, modname in suitelist:
+ fp.write("from %s import *\n"%modname)
+ if suitelist:
+ fp.write("\n\nclass %s(%s_Events"%(packagename, suitelist[0][1]))
+ for code, modname in suitelist[1:]:
+ fp.write(",\n\t%s_Events"%modname)
+ fp.write(",\n\taetools.TalkTo):\n")
+ fp.write("\t_signature = '%s'\n\n"%creatorsignature)
+ fp.close()
+
+def compilesuite(suite, major, minor, language, script, fname, basepackage=None):
"""Generate code for a single suite"""
[name, desc, code, level, version, events, classes, comps, enums] = suite
modname = identify(name)
+ if len(modname) > 28:
+ modname = modname[:27]
fss, ok = macfs.StandardPutFile('Python output file', modname+'.py')
if not ok:
- return
+ return None, None
+ pathname = fss.as_pathname()
+ modname = os.path.splitext(os.path.split(pathname)[1])[0]
fp = open(fss.as_pathname(), 'w')
fss.SetCreatorType('Pyth', 'TEXT')
@@ -239,8 +306,15 @@ def compilesuite(suite, major, minor, language, script, fname):
fp.write('import aetools\n')
fp.write('import MacOS\n\n')
fp.write("_code = %s\n\n"% `code`)
-
- compileclassheader(fp, modname)
+ if basepackage and 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'%basepackage._code_to_fullname[code])
+ basemodule = basepackage._code_to_module[code]
+ else:
+ # We are not an extension.
+ basemodule = None
+ compileclassheader(fp, modname, basemodule)
enumsneeded = {}
if events:
@@ -249,7 +323,7 @@ def compilesuite(suite, major, minor, language, script, fname):
else:
fp.write("\tpass\n\n")
- objc = ObjectCompiler(fp)
+ objc = ObjectCompiler(fp, basemodule)
for cls in classes:
objc.compileclass(cls)
for cls in classes:
@@ -263,10 +337,16 @@ def compilesuite(suite, major, minor, language, script, fname):
objc.checkforenum(enum)
objc.dumpindex()
+
+ return code, modname
-def compileclassheader(fp, name):
+def compileclassheader(fp, name, module=None):
"""Generate class boilerplate"""
- fp.write("class %s:\n\n"%name)
+ classname = '%s_Events'%name
+ if module and hasattr(module, classname):
+ fp.write("class %s(%s):\n\n"%(classname, classname))
+ else:
+ fp.write("class %s:\n\n"%classname)
def compileevent(fp, event, enumsneeded):
"""Generate code for a single event"""
@@ -378,7 +458,7 @@ def compileargument(arg):
print "# %s (%s)" % (name, `keyword`), compiledata(what)
class ObjectCompiler:
- def __init__(self, fp):
+ def __init__(self, fp, basesuite=None):
self.fp = fp
self.propnames = {}
self.classnames = {}
@@ -387,12 +467,20 @@ class ObjectCompiler:
self.compcodes = {}
self.enumcodes = {}
self.othersuites = []
+ self.basesuite = basesuite
def findcodename(self, type, code):
while 1:
if type == 'property':
+ # First we check whether we ourselves have defined it
if self.propcodes.has_key(code):
return self.propcodes[code], self.propcodes[code], None
+ # Next we check whether our base suite module has defined it
+ if self.basesuite and self.basesuite._propdeclarations.has_key(code):
+ name = self.basesuite._propdeclarations[code].__name__
+ return name, name, None
+ # Finally we test whether one of the other suites we know about has defined
+ # it.
for s in self.othersuites:
if s._propdeclarations.has_key(code):
name = s._propdeclarations[code].__name__
@@ -400,6 +488,9 @@ class ObjectCompiler:
if type == 'class':
if self.classcodes.has_key(code):
return self.classcodes[code], self.classcodes[code], None
+ if self.basesuite and self.basesuite._classdeclarations.has_key(code):
+ name = self.basesuite._classdeclarations[code].__name__
+ return name, name, None
for s in self.othersuites:
if s._classdeclarations.has_key(code):
name = s._classdeclarations[code].__name__
@@ -407,6 +498,9 @@ class ObjectCompiler:
if type == 'enum':
if self.enumcodes.has_key(code):
return self.enumcodes[code], self.enumcodes[code], None
+ if self.basesuite and self.basesuite._enumdeclarations.has_key(code):
+ name = '_Enum_' + identify(code)
+ return name, name, None
for s in self.othersuites:
if s._enumdeclarations.has_key(code):
name = '_Enum_' + identify(code)
@@ -414,11 +508,15 @@ class ObjectCompiler:
if type == 'comparison':
if self.compcodes.has_key(code):
return self.compcodes[code], self.compcodes[code], None
+ if self.basesuite and self.basesuite._compdeclarations.has_key(code):
+ name = self.basesuite._compdeclarations[code].__name__
+ return name, name, None
for s in self.othersuites:
if s._compdeclarations.has_key(code):
name = s._compdeclarations[code].__name__
return name, '%s.%s' % (s.__name__, name), s.__name__
-
+ # If all this has failed we ask the user for a guess on where it could
+ # be and retry.
m = self.askdefinitionmodule(type, code)
if not m: return None, None, None
self.othersuites.append(m)
@@ -443,7 +541,7 @@ class ObjectCompiler:
self.classnames[pname] = code
else:
self.fp.write('\nclass %s(aetools.ComponentItem):\n' % pname)
- self.fp.write('\t"""%s - %s"""\n' % (name, desc))
+ self.fp.write('\t"""%s - %s """\n' % (name, desc))
self.fp.write('\twant = %s\n' % `code`)
self.classnames[pname] = code
self.classcodes[code] = pname
@@ -462,7 +560,7 @@ class ObjectCompiler:
self.fp.write("# repeated property %s %s\n"%(pname, what[1]))
else:
self.fp.write("class %s(aetools.NProperty):\n" % pname)
- self.fp.write('\t"""%s - %s"""\n' % (name, what[1]))
+ self.fp.write('\t"""%s - %s """\n' % (name, what[1]))
self.fp.write("\twhich = %s\n" % `code`)
self.fp.write("\twant = %s\n" % `what[0]`)
self.propnames[pname] = code
@@ -510,7 +608,7 @@ class ObjectCompiler:
iname = identify(name)
self.compcodes[code] = iname
self.fp.write("class %s(aetools.NComparison):\n" % iname)
- self.fp.write('\t"""%s - %s"""\n' % (name, comment))
+ self.fp.write('\t"""%s - %s """\n' % (name, comment))
def compileenumeration(self, enum):
[code, items] = enum