• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 # This script generates a Python interface for an Apple Macintosh Manager.
2 # It uses the "bgen" package to generate C code.
3 # The function specifications are generated by scanning the mamager's header file,
4 # using the "scantools" package (customized for this particular manager).
5 
6 import string
7 
8 # Declarations that change for each manager
9 MACHEADERFILE = 'Lists.h'               # The Apple header file
10 MODNAME = '_List'                               # The name of the module
11 OBJECTNAME = 'List'                     # The basic name of the objects used here
12 KIND = 'Handle'                         # Usually 'Ptr' or 'Handle'
13 
14 # The following is *usually* unchanged but may still require tuning
15 MODPREFIX = 'List'                      # The prefix for module-wide routines
16 OBJECTTYPE = "ListHandle"               # The C type used to represent them
17 OBJECTPREFIX = MODPREFIX + 'Obj'        # The prefix for object methods
18 INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
19 OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
20 
21 from macsupport import *
22 
23 # Create the type objects
24 ListHandle = OpaqueByValueType("ListHandle", "ListObj")
25 ListRef = ListHandle # Obsolete, but used in Lists.h
26 Cell = Point
27 ListBounds = Rect
28 ListBounds_ptr = Rect_ptr
29 
30 ListDefSpec = ListDefSpec_ptr = OpaqueType("ListDefSpec", "PyMac_BuildListDefSpec", "PyMac_GetListDefSpec")
31 
32 VarOutBufferShortsize = VarHeapOutputBufferType('char', 'short', 's')   # (buf, &len)
33 InBufferShortsize = VarInputBufferType('char', 'short', 's')            # (buf, len)
34 
35 RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
36 DataHandle = OpaqueByValueType("DataHandle", "ResObj")
37 Handle = OpaqueByValueType("Handle", "ResObj")
38 CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
39 EventModifiers = Type("EventModifiers", "H")
40 
41 includestuff = includestuff + """
42 #include <Carbon/Carbon.h>
43 
44 #ifdef USE_TOOLBOX_OBJECT_GLUE
45 extern PyObject *_ListObj_New(ListHandle);
46 extern int _ListObj_Convert(PyObject *, ListHandle *);
47 
48 #define ListObj_New _ListObj_New
49 #define ListObj_Convert _ListObj_Convert
50 #endif
51 
52 #define as_List(x) ((ListHandle)x)
53 #define as_Resource(lh) ((Handle)lh)
54 
55 static ListDefUPP myListDefFunctionUPP;
56 
57 """
58 
59 initstuff = initstuff + """
60 myListDefFunctionUPP = NewListDefUPP((ListDefProcPtr)myListDefFunction);
61 
62 PyMac_INIT_TOOLBOX_OBJECT_NEW(ListHandle, ListObj_New);
63 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(ListHandle, ListObj_Convert);
64 """
65 
66 class ListMethodGenerator(MethodGenerator):
67     """Similar to MethodGenerator, but has self as last argument"""
68 
69     def parseArgumentList(self, args):
70         args, a0 = args[:-1], args[-1]
71         t0, n0, m0 = a0
72         if m0 != InMode:
73             raise ValueError, "method's 'self' must be 'InMode'"
74         self.itself = Variable(t0, "_self->ob_itself", SelfMode)
75         FunctionGenerator.parseArgumentList(self, args)
76         self.argumentList.append(self.itself)
77 
78 class MyObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
79     # XXXX Should inherit from Resource
80     getsetlist = [(
81             'listFlags',
82             'return Py_BuildValue("l", (long)GetListFlags(self->ob_itself) & 0xff);',
83             'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->listFlags)) return -1;',
84             None,
85             ), (
86             'selFlags',
87             'return Py_BuildValue("l", (long)GetListSelectionFlags(self->ob_itself) & 0xff);',
88             'if (!PyArg_Parse(v, "B", &(*self->ob_itself)->selFlags)) return -1;',
89             None,
90             ), (
91             'cellSize',
92             'return Py_BuildValue("O&", PyMac_BuildPoint, (*self->ob_itself)->cellSize);',
93             'if (!PyArg_Parse(v, "O&", PyMac_GetPoint, &(*self->ob_itself)->cellSize)) return -1;',
94             None
95             )]
96 
97     def outputStructMembers(self):
98         ObjectDefinition.outputStructMembers(self)
99         Output("PyObject *ob_ldef_func;")
100         Output("int ob_must_be_disposed;")
101 
102     def outputCheckNewArg(self):
103         Output("""if (itself == NULL) {
104                                 PyErr_SetString(List_Error,"Cannot create null List");
105                                 return NULL;
106                         }""")
107 
108     def outputInitStructMembers(self):
109         ObjectDefinition.outputInitStructMembers(self)
110         Output("it->ob_ldef_func = NULL;")
111         Output("it->ob_must_be_disposed = 1;")
112         Output("SetListRefCon(itself, (long)it);")
113 
114     def outputFreeIt(self, itselfname):
115         Output("Py_XDECREF(self->ob_ldef_func);")
116         Output("self->ob_ldef_func = NULL;")
117         Output("SetListRefCon(self->ob_itself, (long)0);")
118         Output("if (self->ob_must_be_disposed && %s) LDispose(%s);", itselfname, itselfname)
119 
120 # From here on it's basically all boiler plate...
121 
122 finalstuff = finalstuff + """
123 static void myListDefFunction(SInt16 message,
124                        Boolean selected,
125                        Rect *cellRect,
126                        Cell theCell,
127                        SInt16 dataOffset,
128                        SInt16 dataLen,
129                        ListHandle theList)
130 {
131         PyObject *listDefFunc, *args, *rv=NULL;
132         ListObject *self;
133 
134         self = (ListObject*)GetListRefCon(theList);
135         if (self == NULL || self->ob_itself != theList)
136                 return;  /* nothing we can do */
137         listDefFunc = self->ob_ldef_func;
138         if (listDefFunc == NULL)
139                 return;  /* nothing we can do */
140         args = Py_BuildValue("hbO&O&hhO", message,
141                                           selected,
142                                           PyMac_BuildRect, cellRect,
143                                           PyMac_BuildPoint, theCell,
144                                           dataOffset,
145                                           dataLen,
146                                           self);
147         if (args != NULL) {
148                 rv = PyEval_CallObject(listDefFunc, args);
149                 Py_DECREF(args);
150         }
151         if (rv == NULL) {
152                 PySys_WriteStderr("error in list definition callback:\\n");
153                 PyErr_Print();
154         } else {
155                 Py_DECREF(rv);
156         }
157 }
158 """
159 
160 # Create the generator groups and link them
161 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
162 object = MyObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
163 module.addobject(object)
164 
165 # Create the generator classes used to populate the lists
166 Function = FunctionGenerator
167 Method = ListMethodGenerator
168 
169 # Create and populate the lists
170 functions = []
171 methods = []
172 execfile(INPUTFILE)
173 
174 # Function to convert any handle to a list and vv.
175 ##f = Function(ListHandle, 'as_List', (Handle, 'h', InMode))
176 as_List_body = """
177 Handle h;
178 ListObject *l;
179 if (!PyArg_ParseTuple(_args, "O&", ResObj_Convert, &h))
180         return NULL;
181 l = (ListObject *)ListObj_New(as_List(h));
182 l->ob_must_be_disposed = 0;
183 _res = Py_BuildValue("O", l);
184 return _res;
185 """
186 f = ManualGenerator("as_List", as_List_body)
187 f.docstring = lambda: "(Resource)->List.\nReturns List object (which is not auto-freed!)"
188 functions.append(f)
189 
190 f = Method(Handle, 'as_Resource', (ListHandle, 'lh', InMode))
191 methods.append(f)
192 
193 # Manual generator for CreateCustomList, due to callback ideosyncracies
194 CreateCustomList_body = """\
195 Rect rView;
196 Rect dataBounds;
197 Point cellSize;
198 
199 PyObject *listDefFunc;
200 ListDefSpec theSpec;
201 WindowPtr theWindow;
202 Boolean drawIt;
203 Boolean hasGrow;
204 Boolean scrollHoriz;
205 Boolean scrollVert;
206 ListHandle outList;
207 
208 if (!PyArg_ParseTuple(_args, "O&O&O&(iO)O&bbbb",
209                       PyMac_GetRect, &rView,
210                       PyMac_GetRect, &dataBounds,
211                       PyMac_GetPoint, &cellSize,
212                       &theSpec.defType, &listDefFunc,
213                       WinObj_Convert, &theWindow,
214                       &drawIt,
215                       &hasGrow,
216                       &scrollHoriz,
217                       &scrollVert))
218         return NULL;
219 
220 
221 /* Carbon applications use the CreateCustomList API */
222 theSpec.u.userProc = myListDefFunctionUPP;
223 CreateCustomList(&rView,
224                  &dataBounds,
225                  cellSize,
226                  &theSpec,
227                  theWindow,
228                  drawIt,
229                  hasGrow,
230                  scrollHoriz,
231                  scrollVert,
232                  &outList);
233 
234 
235 _res = ListObj_New(outList);
236 if (_res == NULL)
237         return NULL;
238 Py_INCREF(listDefFunc);
239 ((ListObject*)_res)->ob_ldef_func = listDefFunc;
240 return _res;\
241 """
242 
243 f = ManualGenerator("CreateCustomList", CreateCustomList_body);
244 f.docstring = lambda: "(Rect rView, Rect dataBounds, Point cellSize, ListDefSpec theSpec, WindowPtr theWindow, Boolean drawIt, Boolean hasGrow, Boolean scrollHoriz, Boolean scrollVert) -> (ListHandle outList)"
245 module.add(f)
246 
247 # add the populated lists to the generator groups
248 # (in a different wordl the scan program would generate this)
249 for f in functions: module.add(f)
250 for f in methods: object.add(f)
251 
252 
253 # generate output (open the output file as late as possible)
254 SetOutputFileName(OUTPUTFILE)
255 module.generate()
256