| BGEN -- An Experiment: Automatic Generation of Extension Modules |
| ================================================================ |
| |
| This directory contains BGEN -- a package that helps in generating |
| complete source code for Python extension module. It currently also |
| contains a set of examples that were generated with BGEN. These |
| examples are mostly interfaces to a number of important managers in |
| the Macintosh toolbox. |
| |
| |
| Overview of Subdirectories |
| -------------------------- |
| |
| Main subdirectories: |
| |
| bgen the code generator package |
| |
| Example subdirectories: |
| |
| ae AppleEvents |
| ctl Controls |
| dlg Dialogs |
| evt Events |
| menu Menus |
| list Lists |
| qd QuickDraw |
| res Resources |
| snd Sound |
| win Windows |
| |
| |
| Contents of Subdirectories |
| -------------------------- |
| |
| The contents of each example subdirectory is similar (<Foobar> is |
| for instance AppleEvents, while <foo> is ae): |
| |
| <foo>scan.py Scan the <Foobar>.h header, generating <foo>gen.py |
| <foo>gen.py Output of <foo>scan.py, input for <foo>support.py |
| <foo>edit.py Manually written complement of <foo>gen.py, sometimes |
| <foo>support.py Generate <Foo>module.c from <foo>gen.py and <foo>edit.py |
| <Foo>module.c The interface module, ready to be compiled |
| <Foobar>.py Symbolic constants extracted from <Foobar.h> |
| |
| |
| Tests and Examples |
| ------------------ |
| |
| Other files in these subdirectories are usually examples using the |
| extension. If there's a file t<foo>.py, it usually is a really |
| boring test program. |
| |
| Some test programs contain pathnames that should be edited before |
| trying them. |
| |
| Some of the less boring tests and examples: |
| |
| At the top level: |
| |
| test.py Application mainloop, uses most Mac extensions |
| |
| In ae: |
| |
| aetools.py Conversions between AE and Python data type |
| echo.py Dummy AE server, echoes all data back |
| tell.py Primitive AE client |
| aete.py Decode 'aete' and 'aeut' resources (incomplete) |
| gensuitemodule.py |
| Read aete/aeut resources and turn them into python |
| modules. The *_Suite.py modules have been generated |
| with this. |
| AEservertest.py A simple AE server, similar to echo but different. |
| |
| |
| In res: |
| |
| listres.py List *all* resources in current and in all res files |
| copyres.py Copy a resource file |
| mkerrstrres.py Read "errors.txt" and create a set of "Estr" resources |
| |
| In snd: |
| |
| playaiff.py Play an AIFF file |
| morse.py Turn text into Morse code |
| audiodev.py The standard audiodev.py extended with Mac support |
| Audio_mac.py The Mac support for audiodev.py |
| |
| |
| Creating new Macintosh interfaces |
| --------------------------------- |
| |
| These instructions were written up by Jack while he was building the |
| interface to Lists.h, the macintosh list manager. they may or may not |
| have a more global scope than exactly that. |
| |
| First, start by copying ...scan.py and ...support.py from another, |
| preferrably similar type. I started with evt, but that was a mistake |
| since evt has no "own" object. Ctl or Dlg would probably have been a |
| better idea. |
| |
| Now, the first thing to do is to comment out the blacklisted types and |
| functions and the transformation rules for arguments, we'll fill those |
| in lateron. Also, change the various definitions at the top, so that |
| the right include file is parsed, and the .py files are generated with |
| the correct name. If your manager has a type that will be implemented |
| as a python object you may as well now change the destination() method |
| to recognize that. (List was funny in this respect, since it has the |
| list as the last argument in stead of the first). |
| |
| Now run your scanner. This will probably go fine until it tries to |
| execute the generated code in the ...gen.py module. Look at that file, |
| it will have formalized "definitions" of all the functions and methods |
| that will be generated. Look at them all (with the documentation of the |
| manager you're implementing in hand). Now you'll have to fix the |
| blacklists and the repair instructions. This is sort of a black art, |
| but a few guidelines may be handy here: |
| - If there are argument types you cannot implement (or want to leave for |
| the moment) put them in blacklisttypes. Complex structures come to |
| mind, or routine pointers/UPP's. You will probably also want to |
| blacklist the routine that disposes of your object (since you'll do |
| that in the python destruction routine). |
| - Various types of buffers are available in bgenBuffer, bgenHeapBuffer |
| and macsupport in the bgen directory. These'll let you handle all |
| sorts of input and output parameters. You can put instructions in the |
| repair list to let the C-arguments be handled by the correct type |
| of buffer. Check the other bgen-generated modules for using this for |
| passing raw structures and input and output buffers. |
| - It appears that the parser usually guesses correctly whether a parameter |
| is meant for input or output. But, check the routines to be sure. |
| - Some types are pretty hard to handle but you need the functionality |
| the a routine that uses them anyway. Various routines expecting ProcPtrs |
| or RegionHandles come to mind. Often, you can use the FakeType class |
| to provide a sensible default (i.e. NULL or a pointer to a routine you |
| coded in C, or a region specifying "the whole window"). This way, python |
| programmers won't get the full functionality but at least they'll get the |
| common case. You put the FakeType stuff in ...support.py. |
| |
| Next you'll probably have to write the code to implement your object. |
| This will probably be a subclass of GlobalObjectDefinition. This goes |
| into ...support.py. Also, some types used by the manager may look |
| enough like standard types that you can equate them here (there are a |
| lot of 2-integer structures that look remarkably like a Point, for |
| instance). |
| |
| You'll also have to define the Function() and Method() classes. The |
| OSErrFunctionGenerator and its method-counterpart are particularly |
| handy for a lot of mac managers. |
| |
| Finally, you'll have to try and compile your resulting C-source, and go |
| through the steps above until it works. For tlist.py, the test program |
| for list, I started with the application framework. This is probably a |
| good idea for any manager that does something to the display, since |
| ApplicationFramework takes care of all the intricacies of event |
| handling and decoding (up to a point). |
| |