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()
|
---|