@@ -39,7 +39,10 @@ def process(fullname):
3939 print "decoding" , res .GetResInfo (), "..."
4040 data = res .data
4141 aete = decode (data )
42+ # switch back (needed for dialogs in Python)
43+ UseResFile (cur )
4244 compileaete (aete , fullname )
45+ UseResFile (rf )
4346 finally :
4447 if rf <> cur :
4548 CloseResFile (rf )
@@ -237,27 +240,35 @@ def compilesuite(suite, major, minor, language, script, fname):
237240 fp .write ('import MacOS\n \n ' )
238241 fp .write ("_code = %s\n \n " % `code` )
239242
240- enum_names = []
241- for enum in enums :
242- name = compileenumeration (fp , enum )
243- enum_names .append (enum )
244-
245243 compileclassheader (fp , modname )
244+
245+ enumsneeded = {}
246246 if events :
247247 for event in events :
248- compileevent (fp , event )
248+ compileevent (fp , event , enumsneeded )
249249 else :
250250 fp .write ("\t pass\n \n " )
251+
252+ objc = ObjectCompiler (fp )
253+ for cls in classes :
254+ objc .compileclass (cls )
251255 for cls in classes :
252- compileclass ( fp , cls )
256+ objc . fillclasspropsandelems ( cls )
253257 for comp in comps :
254- compilecomparison (fp , comp )
258+ objc .compilecomparison (comp )
259+ for enum in enums :
260+ objc .compileenumeration (enum )
261+
262+ for enum in enumsneeded .keys ():
263+ objc .checkforenum (enum )
264+
265+ objc .dumpindex ()
255266
256267def compileclassheader (fp , name ):
257268 """Generate class boilerplate"""
258269 fp .write ("class %s:\n \n " % name )
259270
260- def compileevent (fp , event ):
271+ def compileevent (fp , event , enumsneeded ):
261272 """Generate code for a single event"""
262273 [name , desc , code , subcode , returns , accepts , arguments ] = event
263274 funcname = identify (name )
@@ -334,6 +345,7 @@ def compileevent(fp, event):
334345 if ename <> '****' :
335346 fp .write ("\t \t aetools.enumsubst(_arguments, %s, _Enum_%s)\n " %
336347 (`kname` , ename ))
348+ enumsneeded [ename ] = 1
337349 fp .write ("\n " )
338350 #
339351 # Do the transaction
@@ -365,37 +377,182 @@ def compileargument(arg):
365377 [name , keyword , what ] = arg
366378 print "# %s (%s)" % (name , `keyword` ), compiledata (what )
367379
368- def compileclass (fp , cls ):
369- [name , code , desc , properties , elements ] = cls
370- fp .write ("\n # Class %s (%s) -- %s\n " % (`name` , `code` , `desc` ))
371- for prop in properties :
372- compileproperty (fp , prop )
373- for elem in elements :
374- compileelement (fp , elem )
375-
376- def compileproperty (fp , prop ):
377- [name , code , what ] = prop
378- fp .write ("# property %s (%s) %s\n " % (`name` , `code` , compiledata (what )))
379-
380- def compileelement (fp , elem ):
381- [code , keyform ] = elem
382- fp .write ("# element %s as %s\n " % (`code` , keyform ))
383-
384- def compilecomparison (fp , comp ):
385- [name , code , comment ] = comp
386- fp .write ("# comparison %s (%s) -- %s\n " % (`name` , `code` , comment ))
387-
388- def compileenumeration (fp , enum ):
389- [code , items ] = enum
390- fp .write ("_Enum_%s = {\n " % identify (code ))
391- for item in items :
392- compileenumerator (fp , item )
393- fp .write ("}\n \n " )
394- return code
395-
396- def compileenumerator (fp , item ):
397- [name , code , desc ] = item
398- fp .write ("\t %s : %s,\t # %s\n " % (`identify(name)` , `code` , desc ))
380+ class ObjectCompiler :
381+ def __init__ (self , fp ):
382+ self .fp = fp
383+ self .propnames = {}
384+ self .classnames = {}
385+ self .propcodes = {}
386+ self .classcodes = {}
387+ self .compcodes = {}
388+ self .enumcodes = {}
389+ self .othersuites = []
390+
391+ def findcodename (self , type , code ):
392+ while 1 :
393+ if type == 'property' :
394+ if self .propcodes .has_key (code ):
395+ return self .propcodes [code ], self .propcodes [code ], None
396+ for s in self .othersuites :
397+ if s ._propdeclarations .has_key (code ):
398+ name = s ._propdeclarations [code ].__name__
399+ return name , '%s.%s' % (s .__name__ , name ), s .__name__
400+ if type == 'class' :
401+ if self .classcodes .has_key (code ):
402+ return self .classcodes [code ], self .classcodes [code ], None
403+ for s in self .othersuites :
404+ if s ._classdeclarations .has_key (code ):
405+ name = s ._classdeclarations [code ].__name__
406+ return name , '%s.%s' % (s .__name__ , name ), s .__name__
407+ if type == 'enum' :
408+ if self .enumcodes .has_key (code ):
409+ return self .enumcodes [code ], self .enumcodes [code ], None
410+ for s in self .othersuites :
411+ if s ._enumdeclarations .has_key (code ):
412+ name = '_Enum_' + identify (code )
413+ return name , '%s.%s' % (s .__name__ , name ), s .__name__
414+ if type == 'comparison' :
415+ if self .compcodes .has_key (code ):
416+ return self .compcodes [code ], self .compcodes [code ], None
417+ for s in self .othersuites :
418+ if s ._compdeclarations .has_key (code ):
419+ name = s ._compdeclarations [code ].__name__
420+ return name , '%s.%s' % (s .__name__ , name ), s .__name__
421+
422+ m = self .askdefinitionmodule (type , code )
423+ if not m : return None , None , None
424+ self .othersuites .append (m )
425+
426+ def askdefinitionmodule (self , type , code ):
427+ fss , ok = macfs .PromptGetFile ('Where is %s %s declared?' % (type , code ))
428+ if not ok : return
429+ path , file = os .path .split (fss .as_pathname ())
430+ modname = os .path .splitext (file )[0 ]
431+ if not path in sys .path :
432+ sys .path .insert (0 , path )
433+ m = __import__ (modname )
434+ self .fp .write ("import %s\n " % modname )
435+ return m
436+
437+ def compileclass (self , cls ):
438+ [name , code , desc , properties , elements ] = cls
439+ pname = identify (name )
440+ if self .classcodes .has_key (code ):
441+ # plural forms and such
442+ self .fp .write ("\n %s = %s\n " % (pname , self .classcodes [code ]))
443+ self .classnames [pname ] = code
444+ else :
445+ self .fp .write ('\n class %s(aetools.ComponentItem):\n ' % pname )
446+ self .fp .write ('\t """%s - %s"""\n ' % (name , desc ))
447+ self .fp .write ('\t want = %s\n ' % `code` )
448+ self .classnames [pname ] = code
449+ self .classcodes [code ] = pname
450+ for prop in properties :
451+ self .compileproperty (prop )
452+ for elem in elements :
453+ self .compileelement (elem )
454+
455+ def compileproperty (self , prop ):
456+ [name , code , what ] = prop
457+ if code == 'c@#!' :
458+ # Something silly with plurals. Skip it.
459+ return
460+ pname = identify (name )
461+ if self .propcodes .has_key (code ):
462+ self .fp .write ("# repeated property %s %s\n " % (pname , what [1 ]))
463+ else :
464+ self .fp .write ("class %s(aetools.NProperty):\n " % pname )
465+ self .fp .write ('\t """%s - %s"""\n ' % (name , what [1 ]))
466+ self .fp .write ("\t which = %s\n " % `code` )
467+ self .fp .write ("\t want = %s\n " % `what[0]` )
468+ self .propnames [pname ] = code
469+ self .propcodes [code ] = pname
470+
471+ def compileelement (self , elem ):
472+ [code , keyform ] = elem
473+ self .fp .write ("# element %s as %s\n " % (`code` , keyform ))
474+
475+ def fillclasspropsandelems (self , cls ):
476+ [name , code , desc , properties , elements ] = cls
477+ cname = identify (name )
478+ if self .classcodes [code ] != cname :
479+ # This is an other name (plural or so) for something else. Skip.
480+ return
481+ plist = []
482+ elist = []
483+ for prop in properties :
484+ [pname , pcode , what ] = prop
485+ if pcode == 'c@#!' :
486+ continue
487+ pname = identify (pname )
488+ plist .append (pname )
489+ for elem in elements :
490+ [ecode , keyform ] = elem
491+ if ecode == 'c@#!' :
492+ continue
493+ name , ename , module = self .findcodename ('class' , ecode )
494+ if not name :
495+ self .fp .write ("# XXXX %s element %s not found!!\n " % (cname , `ecode` ))
496+ else :
497+ elist .append (name , ename )
498+
499+ self .fp .write ("%s._propdict = {\n " % cname )
500+ for n in plist :
501+ self .fp .write ("\t '%s' : %s,\n " % (n , n ))
502+ self .fp .write ("}\n " )
503+ self .fp .write ("%s._elemdict = {\n " % cname )
504+ for n , fulln in elist :
505+ self .fp .write ("\t '%s' : %s,\n " % (n , fulln ))
506+ self .fp .write ("}\n " )
507+
508+ def compilecomparison (self , comp ):
509+ [name , code , comment ] = comp
510+ iname = identify (name )
511+ self .compcodes [code ] = iname
512+ self .fp .write ("class %s(aetools.NComparison):\n " % iname )
513+ self .fp .write ('\t """%s - %s"""\n ' % (name , comment ))
514+
515+ def compileenumeration (self , enum ):
516+ [code , items ] = enum
517+ name = "_Enum_%s" % identify (code )
518+ self .fp .write ("%s = {\n " % name )
519+ for item in items :
520+ self .compileenumerator (item )
521+ self .fp .write ("}\n \n " )
522+ self .enumcodes [code ] = name
523+ return code
524+
525+ def compileenumerator (self , item ):
526+ [name , code , desc ] = item
527+ self .fp .write ("\t %s : %s,\t # %s\n " % (`identify(name)` , `code` , desc ))
528+
529+ def checkforenum (self , enum ):
530+ """This enum code is used by an event. Make sure it's available"""
531+ name , fullname , module = self .findcodename ('enum' , enum )
532+ if not name :
533+ self .fp .write ("# XXXX enum %s not found!!\n " % (enum ))
534+ return
535+ if module :
536+ self .fp .write ("from %s import %s\n " % (module , name ))
537+
538+ def dumpindex (self ):
539+ self .fp .write ("\n #\n # Indices of types declared in this module\n #\n " )
540+ self .fp .write ("_classdeclarations = {\n " )
541+ for k in self .classcodes .keys ():
542+ self .fp .write ("\t %s : %s,\n " % (`k` , self .classcodes [k ]))
543+ self .fp .write ("}\n " )
544+ self .fp .write ("\n _propdeclarations = {\n " )
545+ for k in self .propcodes .keys ():
546+ self .fp .write ("\t %s : %s,\n " % (`k` , self .propcodes [k ]))
547+ self .fp .write ("}\n " )
548+ self .fp .write ("\n _compdeclarations = {\n " )
549+ for k in self .compcodes .keys ():
550+ self .fp .write ("\t %s : %s,\n " % (`k` , self .compcodes [k ]))
551+ self .fp .write ("}\n " )
552+ self .fp .write ("\n _enumdeclarations = {\n " )
553+ for k in self .enumcodes .keys ():
554+ self .fp .write ("\t %s : %s,\n " % (`k` , self .enumcodes [k ]))
555+ self .fp .write ("}\n " )
399556
400557def compiledata (data ):
401558 [type , description , flags ] = data
@@ -432,14 +589,17 @@ def compiledataflags(flags):
432589 return '[%s]' % string .join (bits )
433590
434591# XXXX Do we have a set of python keywords somewhere?
435- illegal_ids = [ "for" , "in" , "from" , "and" , "or" , "not" , "print" ]
592+ illegal_ids = [ "for" , "in" , "from" , "and" , "or" , "not" , "print" , "class" , "return" ,
593+ "def" ]
436594
437595def identify (str ):
438596 """Turn any string into an identifier:
439597 - replace space by _
440598 - replace other illegal chars by _xx_ (hex code)
441599 - prepend _ if the result is a python keyword
442600 """
601+ if not str :
602+ return "_empty_ae_name"
443603 rv = ''
444604 ok = string .letters + '_'
445605 ok2 = ok + string .digits
0 commit comments