py-cvs-2001_07_13 (Rev 1.3) merge
[python/dscho.git] / Mac / Modules / cf / cfsupport.py
blobebfe71797ab8aa7cef089bff40ead9286ae7d8ee
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).
6 #error missing SetActionFilter
8 import string
10 # Declarations that change for each manager
11 MODNAME = 'CF' # The name of the module
13 # The following is *usually* unchanged but may still require tuning
14 MODPREFIX = MODNAME # The prefix for module-wide routines
15 INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
16 OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
18 from macsupport import *
20 # Create the type objects
22 includestuff = includestuff + """
23 #ifdef WITHOUT_FRAMEWORKS
24 #include <CoreFoundation.h>
25 #else
26 #include <CoreFoundation.h>
27 #endif
29 /* For now we declare them forward here. They'll go to mactoolbox later */
30 staticforward PyObject *CFTypeRefObj_New(CFTypeRef);
31 staticforward int CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
32 staticforward PyObject *CFStringRefObj_New(CFStringRef);
33 staticforward int CFStringRefObj_Convert(PyObject *, CFStringRef *);
35 staticforward int CFURLRefObj_Convert(PyObject *, CFURLRef *);
37 // ADD declarations
38 #ifdef NOTYET_USE_TOOLBOX_OBJECT_GLUE
39 //extern PyObject *_CFTypeRefObj_New(CFTypeRef);
40 //extern int _CFTypeRefObj_Convert(PyObject *, CFTypeRef *);
42 //#define CFTypeRefObj_New _CFTypeRefObj_New
43 //#define CFTypeRefObj_Convert _CFTypeRefObj_Convert
44 #endif
47 ** Parse/generate CFRange records
49 PyObject *CFRange_New(CFRange *itself)
52 return Py_BuildValue("ll", (long)itself->location, (long)itself->length);
55 CFRange_Convert(PyObject *v, CFRange *p_itself)
57 long location, length;
59 if( !PyArg_ParseTuple(v, "ll", &location, &length) )
60 return 0;
61 p_itself->location = (CFIndex)location;
62 p_itself->length = (CFIndex)length;
63 return 1;
66 /* Optional CFURL argument or None (passed as NULL) */
67 int
68 OptionalCFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself)
70 if ( v == Py_None ) {
71 p_itself = NULL;
72 return 1;
74 return CFURLRefObj_Convert(v, p_itself);
77 """
79 initstuff = initstuff + """
80 // PyMac_INIT_TOOLBOX_OBJECT_NEW(Track, TrackObj_New);
81 // PyMac_INIT_TOOLBOX_OBJECT_CONVERT(Track, TrackObj_Convert);
82 """
84 Boolean = Type("Boolean", "l")
85 CFTypeID = Type("CFTypeID", "l") # XXXX a guess, seems better than OSTypeType.
86 CFHashCode = Type("CFHashCode", "l")
87 CFIndex = Type("CFIndex", "l")
88 CFRange = OpaqueByValueType('CFRange', 'CFRange')
89 CFOptionFlags = Type("CFOptionFlags", "l")
90 CFStringEncoding = Type("CFStringEncoding", "l")
91 CFComparisonResult = Type("CFComparisonResult", "l") # a bit dangerous, it's an enum
92 CFURLPathStyle = Type("CFURLPathStyle", "l") # a bit dangerous, it's an enum
94 char_ptr = stringptr
95 return_stringptr = Type("char *", "s") # ONLY FOR RETURN VALUES!!
97 CFAllocatorRef = FakeType("(CFAllocatorRef)NULL")
98 CFArrayCallBacks_ptr = FakeType("&kCFTypeArrayCallBacks")
99 CFDictionaryKeyCallBacks_ptr = FakeType("&kCFTypeDictionaryKeyCallBacks")
100 CFDictionaryValueCallBacks_ptr = FakeType("&kCFTypeDictionaryValueCallBacks")
101 # The real objects
102 CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj")
103 CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj")
104 CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj")
105 CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj")
106 CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj")
107 CFDataRef = OpaqueByValueType("CFDataRef", "CFDataRefObj")
108 CFMutableDataRef = OpaqueByValueType("CFMutableDataRef", "CFMutableDataRefObj")
109 CFDictionaryRef = OpaqueByValueType("CFDictionaryRef", "CFDictionaryRefObj")
110 CFMutableDictionaryRef = OpaqueByValueType("CFMutableDictionaryRef", "CFMutableDictionaryRefObj")
111 CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj")
112 CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj")
113 CFURLRef = OpaqueByValueType("CFURLRef", "CFURLRefObj")
114 OptionalCFURLRef = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj")
115 # ADD object type here
117 # Our (opaque) objects
119 class MyGlobalObjectDefinition(GlobalObjectDefinition):
120 def outputCheckNewArg(self):
121 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
122 def outputStructMembers(self):
123 GlobalObjectDefinition.outputStructMembers(self)
124 Output("void (*ob_freeit)(CFTypeRef ptr);")
125 def outputInitStructMembers(self):
126 GlobalObjectDefinition.outputInitStructMembers(self)
127 ## Output("it->ob_freeit = NULL;")
128 Output("it->ob_freeit = CFRelease;")
129 def outputCheckConvertArg(self):
130 Out("""
131 if (v == Py_None) { *p_itself = NULL; return 1; }
132 /* Check for other CF objects here */
133 """)
134 def outputCleanupStructMembers(self):
135 Output("if (self->ob_freeit && self->ob_itself)")
136 OutLbrace()
137 Output("self->ob_freeit((CFTypeRef)self->ob_itself);")
138 OutRbrace()
140 def outputCompare(self):
141 Output()
142 Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, self.objecttype)
143 OutLbrace()
144 Output("/* XXXX Or should we use CFEqual?? */")
145 Output("if ( self->ob_itself > other->ob_itself ) return 1;")
146 Output("if ( self->ob_itself < other->ob_itself ) return -1;")
147 Output("return 0;")
148 OutRbrace()
150 def outputHash(self):
151 Output()
152 Output("static int %s_hash(%s *self)", self.prefix, self.objecttype)
153 OutLbrace()
154 Output("/* XXXX Or should we use CFHash?? */")
155 Output("return (int)self->ob_itself;")
156 OutRbrace()
158 def outputRepr(self):
159 Output()
160 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
161 OutLbrace()
162 Output("char buf[100];")
163 Output("""sprintf(buf, "<CFTypeRef type-%%d object at 0x%%08.8x for 0x%%08.8x>", CFGetTypeID(self->ob_itself), self, self->ob_itself);""")
164 Output("return PyString_FromString(buf);")
165 OutRbrace()
167 class CFTypeRefObjectDefinition(MyGlobalObjectDefinition):
168 pass
170 class CFArrayRefObjectDefinition(MyGlobalObjectDefinition):
171 basechain = "&CFTypeRefObj_chain"
173 def outputRepr(self):
174 Output()
175 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
176 OutLbrace()
177 Output("char buf[100];")
178 Output("""sprintf(buf, "<CFArrayRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
179 Output("return PyString_FromString(buf);")
180 OutRbrace()
182 class CFMutableArrayRefObjectDefinition(MyGlobalObjectDefinition):
183 basechain = "&CFArrayRefObj_chain"
185 def outputRepr(self):
186 Output()
187 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
188 OutLbrace()
189 Output("char buf[100];")
190 Output("""sprintf(buf, "<CFMutableArrayRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
191 Output("return PyString_FromString(buf);")
192 OutRbrace()
194 class CFDictionaryRefObjectDefinition(MyGlobalObjectDefinition):
195 basechain = "&CFTypeRefObj_chain"
197 def outputRepr(self):
198 Output()
199 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
200 OutLbrace()
201 Output("char buf[100];")
202 Output("""sprintf(buf, "<CFDictionaryRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
203 Output("return PyString_FromString(buf);")
204 OutRbrace()
206 class CFMutableDictionaryRefObjectDefinition(MyGlobalObjectDefinition):
207 basechain = "&CFDictionaryRefObj_chain"
209 def outputRepr(self):
210 Output()
211 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
212 OutLbrace()
213 Output("char buf[100];")
214 Output("""sprintf(buf, "<CFMutableDictionaryRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
215 Output("return PyString_FromString(buf);")
216 OutRbrace()
218 class CFDataRefObjectDefinition(MyGlobalObjectDefinition):
219 basechain = "&CFTypeRefObj_chain"
221 def outputRepr(self):
222 Output()
223 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
224 OutLbrace()
225 Output("char buf[100];")
226 Output("""sprintf(buf, "<CFDataRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
227 Output("return PyString_FromString(buf);")
228 OutRbrace()
230 class CFMutableDataRefObjectDefinition(MyGlobalObjectDefinition):
231 basechain = "&CFDataRefObj_chain"
233 def outputRepr(self):
234 Output()
235 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
236 OutLbrace()
237 Output("char buf[100];")
238 Output("""sprintf(buf, "<CFMutableDataRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
239 Output("return PyString_FromString(buf);")
240 OutRbrace()
242 class CFStringRefObjectDefinition(MyGlobalObjectDefinition):
243 basechain = "&CFTypeRefObj_chain"
245 def outputCheckConvertArg(self):
246 Out("""
247 if (v == Py_None) { *p_itself = NULL; return 1; }
248 if (PyString_Check(v)) {
249 char *cStr = PyString_AsString(v);
250 *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, 0);
251 return 1;
253 if (PyUnicode_Check(v)) {
254 /* We use the CF types here, if Python was configured differently that will give an error */
255 CFIndex size = PyUnicode_GetSize(v);
256 UniChar *unichars = PyUnicode_AsUnicode(v);
257 if (!unichars) return 0;
258 *p_itself = CFStringCreateWithCharacters((CFAllocatorRef)NULL, unichars, size);
259 return 1;
262 """)
264 def outputRepr(self):
265 Output()
266 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
267 OutLbrace()
268 Output("char buf[100];")
269 Output("""sprintf(buf, "<CFStringRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
270 Output("return PyString_FromString(buf);")
271 OutRbrace()
273 class CFMutableStringRefObjectDefinition(CFStringRefObjectDefinition):
274 basechain = "&CFStringRefObj_chain"
276 def outputCheckConvertArg(self):
277 # Mutable, don't allow Python strings
278 return MyGlobalObjectDefinition.outputCheckConvertArg(self)
280 def outputRepr(self):
281 Output()
282 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
283 OutLbrace()
284 Output("char buf[100];")
285 Output("""sprintf(buf, "<CFMutableStringRef object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
286 Output("return PyString_FromString(buf);")
287 OutRbrace()
289 class CFURLRefObjectDefinition(MyGlobalObjectDefinition):
290 basechain = "&CFTypeRefObj_chain"
292 def outputRepr(self):
293 Output()
294 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
295 OutLbrace()
296 Output("char buf[100];")
297 Output("""sprintf(buf, "<CFURL object at 0x%%08.8x for 0x%%08.8x>", self, self->ob_itself);""")
298 Output("return PyString_FromString(buf);")
299 OutRbrace()
302 # ADD object class here
304 # From here on it's basically all boiler plate...
306 # Create the generator groups and link them
307 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
308 CFTypeRef_object = CFTypeRefObjectDefinition('CFTypeRef', 'CFTypeRefObj', 'CFTypeRef')
309 CFArrayRef_object = CFArrayRefObjectDefinition('CFArrayRef', 'CFArrayRefObj', 'CFArrayRef')
310 CFMutableArrayRef_object = CFMutableArrayRefObjectDefinition('CFMutableArrayRef', 'CFMutableArrayRefObj', 'CFMutableArrayRef')
311 CFDictionaryRef_object = CFDictionaryRefObjectDefinition('CFDictionaryRef', 'CFDictionaryRefObj', 'CFDictionaryRef')
312 CFMutableDictionaryRef_object = CFMutableDictionaryRefObjectDefinition('CFMutableDictionaryRef', 'CFMutableDictionaryRefObj', 'CFMutableDictionaryRef')
313 CFDataRef_object = CFDataRefObjectDefinition('CFDataRef', 'CFDataRefObj', 'CFDataRef')
314 CFMutableDataRef_object = CFMutableDataRefObjectDefinition('CFMutableDataRef', 'CFMutableDataRefObj', 'CFMutableDataRef')
315 CFStringRef_object = CFStringRefObjectDefinition('CFStringRef', 'CFStringRefObj', 'CFStringRef')
316 CFMutableStringRef_object = CFMutableStringRefObjectDefinition('CFMutableStringRef', 'CFMutableStringRefObj', 'CFMutableStringRef')
317 CFURLRef_object = CFURLRefObjectDefinition('CFURLRef', 'CFURLRefObj', 'CFURLRef')
319 # ADD object here
321 module.addobject(CFTypeRef_object)
322 module.addobject(CFArrayRef_object)
323 module.addobject(CFMutableArrayRef_object)
324 module.addobject(CFDictionaryRef_object)
325 module.addobject(CFMutableDictionaryRef_object)
326 module.addobject(CFDataRef_object)
327 module.addobject(CFMutableDataRef_object)
328 module.addobject(CFStringRef_object)
329 module.addobject(CFMutableStringRef_object)
330 module.addobject(CFURLRef_object)
331 # ADD addobject call here
333 # Create the generator classes used to populate the lists
334 Function = OSErrWeakLinkFunctionGenerator
335 Method = OSErrWeakLinkMethodGenerator
337 # Create and populate the lists
338 functions = []
339 CFTypeRef_methods = []
340 CFArrayRef_methods = []
341 CFMutableArrayRef_methods = []
342 CFDictionaryRef_methods = []
343 CFMutableDictionaryRef_methods = []
344 CFDataRef_methods = []
345 CFMutableDataRef_methods = []
346 CFStringRef_methods = []
347 CFMutableStringRef_methods = []
348 CFURLRef_methods = []
350 # ADD _methods initializer here
351 execfile(INPUTFILE)
354 # add the populated lists to the generator groups
355 # (in a different wordl the scan program would generate this)
356 for f in functions: module.add(f)
357 for f in CFTypeRef_methods: CFTypeRef_object.add(f)
358 for f in CFArrayRef_methods: CFArrayRef_object.add(f)
359 for f in CFMutableArrayRef_methods: CFMutableArrayRef_object.add(f)
360 for f in CFDictionaryRef_methods: CFDictionaryRef_object.add(f)
361 for f in CFMutableDictionaryRef_methods: CFMutableDictionaryRef_object.add(f)
362 for f in CFDataRef_methods: CFDataRef_object.add(f)
363 for f in CFMutableDataRef_methods: CFMutableDataRef_object.add(f)
364 for f in CFStringRef_methods: CFStringRef_object.add(f)
365 for f in CFMutableStringRef_methods: CFMutableStringRef_object.add(f)
366 for f in CFURLRef_methods: CFURLRef_object.add(f)
368 # Manual generators for getting data out of strings
370 getasstring_body = """
371 int size = CFStringGetLength(_self->ob_itself)+1;
372 char *data = malloc(size);
374 if( data == NULL ) return PyErr_NoMemory();
375 if ( CFStringGetCString(_self->ob_itself, data, size, 0) ) {
376 _res = (PyObject *)PyString_FromString(data);
377 } else {
378 PyErr_SetString(PyExc_RuntimeError, "CFStringGetCString could not fit the string");
379 _res = NULL;
381 free(data);
382 return _res;
385 f = ManualGenerator("CFStringGetString", getasstring_body);
386 f.docstring = lambda: "() -> (string _rv)"
387 CFStringRef_object.add(f)
389 getasunicode_body = """
390 int size = CFStringGetLength(_self->ob_itself)+1;
391 Py_UNICODE *data = malloc(size*sizeof(Py_UNICODE));
392 CFRange range;
394 range.location = 0;
395 range.length = size;
396 if( data == NULL ) return PyErr_NoMemory();
397 CFStringGetCharacters(_self->ob_itself, range, data);
398 _res = (PyObject *)PyUnicode_FromUnicode(data, size);
399 free(data);
400 return _res;
403 f = ManualGenerator("CFStringGetUnicode", getasunicode_body);
404 f.docstring = lambda: "() -> (unicode _rv)"
405 CFStringRef_object.add(f)
407 # ADD add forloop here
409 # generate output (open the output file as late as possible)
410 SetOutputFileName(OUTPUTFILE)
411 module.generate()