|
1 # This script will generate the Resources interface for Python. |
|
2 # It uses the "bgen" package to generate C code. |
|
3 # It execs the file resgen.py which contain the function definitions |
|
4 # (resgen.py was generated by resscan.py, scanning the <Resources.h> header file). |
|
5 |
|
6 from macsupport import * |
|
7 |
|
8 class ResMixIn: |
|
9 |
|
10 def checkit(self): |
|
11 if self.returntype.__class__ != OSErrType: |
|
12 OutLbrace() |
|
13 Output("OSErr _err = ResError();") |
|
14 Output("if (_err != noErr) return PyMac_Error(_err);") |
|
15 OutRbrace() |
|
16 FunctionGenerator.checkit(self) # XXX |
|
17 |
|
18 class ResFunction(ResMixIn, OSErrWeakLinkFunctionGenerator): pass |
|
19 class ResMethod(ResMixIn, OSErrWeakLinkMethodGenerator): pass |
|
20 |
|
21 RsrcChainLocation = Type("RsrcChainLocation", "h") |
|
22 FSCatalogInfoBitmap = FakeType("0") # Type("FSCatalogInfoBitmap", "l") |
|
23 FSCatalogInfo_ptr = FakeType("(FSCatalogInfo *)0") |
|
24 |
|
25 # includestuff etc. are imported from macsupport |
|
26 |
|
27 includestuff = includestuff + """ |
|
28 #include <Carbon/Carbon.h> |
|
29 |
|
30 #ifdef USE_TOOLBOX_OBJECT_GLUE |
|
31 extern PyObject *_ResObj_New(Handle); |
|
32 extern int _ResObj_Convert(PyObject *, Handle *); |
|
33 extern PyObject *_OptResObj_New(Handle); |
|
34 extern int _OptResObj_Convert(PyObject *, Handle *); |
|
35 #define ResObj_New _ResObj_New |
|
36 #define ResObj_Convert _ResObj_Convert |
|
37 #define OptResObj_New _OptResObj_New |
|
38 #define OptResObj_Convert _OptResObj_Convert |
|
39 #endif |
|
40 |
|
41 /* Function to dispose a resource, with a "normal" calling sequence */ |
|
42 static void |
|
43 PyMac_AutoDisposeHandle(Handle h) |
|
44 { |
|
45 DisposeHandle(h); |
|
46 } |
|
47 """ |
|
48 |
|
49 finalstuff = finalstuff + """ |
|
50 |
|
51 /* Alternative version of ResObj_New, which returns None for null argument */ |
|
52 PyObject *OptResObj_New(Handle itself) |
|
53 { |
|
54 if (itself == NULL) { |
|
55 Py_INCREF(Py_None); |
|
56 return Py_None; |
|
57 } |
|
58 return ResObj_New(itself); |
|
59 } |
|
60 |
|
61 int OptResObj_Convert(PyObject *v, Handle *p_itself) |
|
62 { |
|
63 PyObject *tmp; |
|
64 |
|
65 if ( v == Py_None ) { |
|
66 *p_itself = NULL; |
|
67 return 1; |
|
68 } |
|
69 if (ResObj_Check(v)) |
|
70 { |
|
71 *p_itself = ((ResourceObject *)v)->ob_itself; |
|
72 return 1; |
|
73 } |
|
74 /* If it isn't a resource yet see whether it is convertible */ |
|
75 if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) ) { |
|
76 *p_itself = ((ResourceObject *)tmp)->ob_itself; |
|
77 Py_DECREF(tmp); |
|
78 return 1; |
|
79 } |
|
80 PyErr_Clear(); |
|
81 PyErr_SetString(PyExc_TypeError, "Resource required"); |
|
82 return 0; |
|
83 } |
|
84 """ |
|
85 |
|
86 initstuff = initstuff + """ |
|
87 PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, ResObj_New); |
|
88 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, ResObj_Convert); |
|
89 PyMac_INIT_TOOLBOX_OBJECT_NEW(Handle, OptResObj_New); |
|
90 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Handle, OptResObj_Convert); |
|
91 """ |
|
92 |
|
93 module = MacModule('_Res', 'Res', includestuff, finalstuff, initstuff) |
|
94 |
|
95 class ResDefinition(PEP253Mixin, GlobalObjectDefinition): |
|
96 getsetlist = [ |
|
97 ('data', |
|
98 """ |
|
99 PyObject *res; |
|
100 char state; |
|
101 |
|
102 state = HGetState(self->ob_itself); |
|
103 HLock(self->ob_itself); |
|
104 res = PyString_FromStringAndSize( |
|
105 *self->ob_itself, |
|
106 GetHandleSize(self->ob_itself)); |
|
107 HUnlock(self->ob_itself); |
|
108 HSetState(self->ob_itself, state); |
|
109 return res; |
|
110 """, |
|
111 """ |
|
112 char *data; |
|
113 long size; |
|
114 |
|
115 if ( v == NULL ) |
|
116 return -1; |
|
117 if ( !PyString_Check(v) ) |
|
118 return -1; |
|
119 size = PyString_Size(v); |
|
120 data = PyString_AsString(v); |
|
121 /* XXXX Do I need the GetState/SetState calls? */ |
|
122 SetHandleSize(self->ob_itself, size); |
|
123 if ( MemError()) |
|
124 return -1; |
|
125 HLock(self->ob_itself); |
|
126 memcpy((char *)*self->ob_itself, data, size); |
|
127 HUnlock(self->ob_itself); |
|
128 /* XXXX Should I do the Changed call immedeately? */ |
|
129 return 0; |
|
130 """, |
|
131 'The resource data' |
|
132 ), ( |
|
133 'size', |
|
134 'return PyInt_FromLong(GetHandleSize(self->ob_itself));', |
|
135 None, |
|
136 'The length of the resource data' |
|
137 )] |
|
138 |
|
139 def outputCheckNewArg(self): |
|
140 Output("if (itself == NULL) return PyMac_Error(resNotFound);") |
|
141 |
|
142 def outputCheckConvertArg(self): |
|
143 # if it isn't a resource we may be able to coerce it |
|
144 Output("if (!%s_Check(v))", self.prefix) |
|
145 OutLbrace() |
|
146 Output("PyObject *tmp;") |
|
147 Output('if ( (tmp=PyObject_CallMethod(v, "as_Resource", "")) )') |
|
148 OutLbrace() |
|
149 Output("*p_itself = ((ResourceObject *)tmp)->ob_itself;") |
|
150 Output("Py_DECREF(tmp);") |
|
151 Output("return 1;") |
|
152 OutRbrace() |
|
153 Output("PyErr_Clear();") |
|
154 OutRbrace() |
|
155 |
|
156 def outputStructMembers(self): |
|
157 GlobalObjectDefinition.outputStructMembers(self) |
|
158 Output("void (*ob_freeit)(%s ptr);", self.itselftype) |
|
159 |
|
160 def outputInitStructMembers(self): |
|
161 GlobalObjectDefinition.outputInitStructMembers(self) |
|
162 Output("it->ob_freeit = NULL;") |
|
163 |
|
164 def outputCleanupStructMembers(self): |
|
165 Output("if (self->ob_freeit && self->ob_itself)") |
|
166 OutLbrace() |
|
167 Output("self->ob_freeit(self->ob_itself);") |
|
168 OutRbrace() |
|
169 Output("self->ob_itself = NULL;") |
|
170 |
|
171 def output_tp_newBody(self): |
|
172 Output("PyObject *self;") |
|
173 Output |
|
174 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") |
|
175 Output("((%s *)self)->ob_itself = NULL;", self.objecttype) |
|
176 Output("((%s *)self)->ob_freeit = NULL;", self.objecttype) |
|
177 Output("return self;") |
|
178 |
|
179 def output_tp_initBody(self): |
|
180 Output("char *srcdata = NULL;") |
|
181 Output("int srclen = 0;") |
|
182 Output("%s itself;", self.itselftype); |
|
183 Output("char *kw[] = {\"itself\", 0};") |
|
184 Output() |
|
185 Output("if (PyArg_ParseTupleAndKeywords(_args, _kwds, \"O&\", kw, %s_Convert, &itself))", |
|
186 self.prefix); |
|
187 OutLbrace() |
|
188 Output("((%s *)_self)->ob_itself = itself;", self.objecttype) |
|
189 Output("return 0;") |
|
190 OutRbrace() |
|
191 Output("PyErr_Clear();") |
|
192 Output("if (!PyArg_ParseTupleAndKeywords(_args, _kwds, \"|s#\", kw, &srcdata, &srclen)) return -1;") |
|
193 Output("if ((itself = NewHandle(srclen)) == NULL)") |
|
194 OutLbrace() |
|
195 Output("PyErr_NoMemory();") |
|
196 Output("return 0;") |
|
197 OutRbrace() |
|
198 Output("((%s *)_self)->ob_itself = itself;", self.objecttype) |
|
199 # XXXX Output("((%s *)self)->ob_freeit = PyMac_AutoDisposeHandle;") |
|
200 Output("if (srclen && srcdata)") |
|
201 OutLbrace() |
|
202 Output("HLock(itself);") |
|
203 Output("memcpy(*itself, srcdata, srclen);") |
|
204 Output("HUnlock(itself);") |
|
205 OutRbrace() |
|
206 Output("return 0;") |
|
207 |
|
208 resobject = ResDefinition('Resource', 'ResObj', 'Handle') |
|
209 module.addobject(resobject) |
|
210 |
|
211 functions = [] |
|
212 resmethods = [] |
|
213 |
|
214 execfile('resgen.py') |
|
215 execfile('resedit.py') |
|
216 |
|
217 for f in functions: module.add(f) |
|
218 for f in resmethods: resobject.add(f) |
|
219 |
|
220 SetOutputFileName('_Resmodule.c') |
|
221 module.generate() |