Maintain backwards compatibility with python < 2.3 by dynamically
[python/dscho.git] / Mac / Modules / file / filesupport.py
blob7223038b10f950759b63c1394ea1596fc3a9bb0e
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 # XXXX TO DO:
7 # - Implement correct missing FSSpec handling for Alias methods
8 # - Implement FInfo
10 import string
12 # Declarations that change for each manager
13 #MACHEADERFILE = 'Files.h' # The Apple header file
14 MODNAME = '_File' # The name of the module
15 LONGMODNAME = 'Carbon.File' # The "normal" external name of the module
17 # The following is *usually* unchanged but may still require tuning
18 MODPREFIX = 'File' # The prefix for module-wide routines
19 INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
20 OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
22 from macsupport import *
24 # Various integers:
25 SInt64 = Type("SInt64", "L")
26 UInt64 = Type("UInt64", "L")
27 FNMessage = Type("FNMessage", "l")
28 FSAllocationFlags = Type("FSAllocationFlags", "H")
29 FSCatalogInfoBitmap = Type("FSCatalogInfoBitmap", "l")
30 FSIteratorFlags = Type("FSIteratorFlags", "l")
31 FSVolumeRefNum = Type("FSVolumeRefNum", "h")
32 AliasInfoType = Type("AliasInfoType", "h")
34 # Various types of strings:
35 #class UniCharCountBuffer(InputOnlyType):
36 # pass
37 class VarReverseInputBufferType(ReverseInputBufferMixin, VarInputBufferType):
38 pass
39 FullPathName = VarReverseInputBufferType()
40 ConstStr31Param = OpaqueArrayType("Str31", "PyMac_BuildStr255", "PyMac_GetStr255")
41 ConstStr32Param = OpaqueArrayType("Str32", "PyMac_BuildStr255", "PyMac_GetStr255")
42 ConstStr63Param = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255")
43 Str63 = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255")
45 HFSUniStr255 = OpaqueType("HFSUniStr255", "PyMac_BuildHFSUniStr255", "PyMac_GetHFSUniStr255")
46 UInt8_ptr = InputOnlyType("UInt8 *", "s")
48 # Other types:
49 class OptionalFSxxxType(OpaqueByValueType):
50 def declare(self, name):
51 Output("%s %s__buf__;", self.typeName, name)
52 Output("%s *%s = &%s__buf__;", self.typeName, name, name)
54 class FSCatalogInfoAndBitmapType(InputOnlyType):
56 def __init__(self):
57 InputOnlyType.__init__(self, "BUG", "BUG")
59 def declare(self, name):
60 Output("PyObject *%s__object = NULL;", name)
61 Output("FSCatalogInfoBitmap %s__bitmap = 0;", name)
62 Output("FSCatalogInfo %s;", name)
64 def getargsFormat(self):
65 return "lO"
67 def getargsArgs(self, name):
68 return "%s__bitmap, %s__object"%(name, name)
70 def getargsCheck(self, name):
71 Output("if (!convert_FSCatalogInfo(%s__object, %s__bitmap, &%s)) return NULL;", name, name, name)
73 def passInput(self, name):
74 return "%s__bitmap, &%s"% (name, name)
76 def passOutput(self, name):
77 return "%s__bitmap, &%s"% (name, name)
79 def mkvalueFormat(self):
80 return "O"
82 def mkvalueArgs(self, name):
83 return "%s__object" % (name)
85 def xxxxmkvalueCheck(self, name):
86 Output("if ((%s__object = new_FSCatalogInfo(%s__bitmap, &%s)) == NULL) return NULL;", name, name)
88 class FSCatalogInfoAndBitmap_inType(FSCatalogInfoAndBitmapType, InputOnlyMixIn):
90 def xxxxmkvalueCheck(self, name):
91 pass
93 class FSCatalogInfoAndBitmap_outType(FSCatalogInfoAndBitmapType):
95 def getargsFormat(self):
96 return "l"
98 def getargsArgs(self, name):
99 return "%s__bitmap" % name
101 def getargsCheck(self, name):
102 pass
104 FInfo = OpaqueType("FInfo", "FInfo")
105 FInfo_ptr = OpaqueType("FInfo", "FInfo")
106 AliasHandle = OpaqueByValueType("AliasHandle", "Alias")
107 FSSpec = OpaqueType("FSSpec", "FSSpec")
108 FSSpec_ptr = OpaqueType("FSSpec", "FSSpec")
109 OptFSSpecPtr = OptionalFSxxxType("FSSpec", "BUG", "myPyMac_GetOptFSSpecPtr")
110 FSRef = OpaqueType("FSRef", "FSRef")
111 FSRef_ptr = OpaqueType("FSRef", "FSRef")
112 OptFSRefPtr = OptionalFSxxxType("FSRef", "BUG", "myPyMac_GetOptFSRefPtr")
113 FSCatalogInfo = OpaqueType("FSCatalogInfo", "FSCatalogInfo")
114 FSCatalogInfo_ptr = OpaqueType("FSCatalogInfo", "FSCatalogInfo")
116 # To be done:
117 #CatPositionRec
118 #FSCatalogInfo
119 #FSForkInfo
120 #FSIterator
121 #FSVolumeInfo
122 #FSSpecArrayPtr
124 includestuff = includestuff + """
125 #ifdef WITHOUT_FRAMEWORKS
126 #include <Files.h>
127 #else
128 #include <Carbon/Carbon.h>
129 #endif
131 #ifdef USE_TOOLBOX_OBJECT_GLUE
132 extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
133 extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
134 extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
135 extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
137 #define PyMac_GetFSSpec _PyMac_GetFSSpec
138 #define PyMac_GetFSRef _PyMac_GetFSRef
139 #define PyMac_BuildFSSpec _PyMac_BuildFSSpec
140 #define PyMac_BuildFSRef _PyMac_BuildFSRef
141 #else
142 extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
143 extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
144 extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
145 extern PyObject *PyMac_BuildFSRef(FSRef *spec);
146 #endif
148 /* Forward declarations */
149 static PyObject *FInfo_New(FInfo *itself);
150 static PyObject *FSRef_New(FSRef *itself);
151 static PyObject *FSSpec_New(FSSpec *itself);
152 static PyObject *Alias_New(AliasHandle itself);
153 static int FInfo_Convert(PyObject *v, FInfo *p_itself);
154 #define FSRef_Convert PyMac_GetFSRef
155 #define FSSpec_Convert PyMac_GetFSSpec
156 static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
159 ** UTCDateTime records
161 static int
162 UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr)
164 return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction);
167 static PyObject *
168 UTCDateTime_New(UTCDateTime *ptr)
170 return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction);
174 ** Optional fsspec and fsref pointers. None will pass NULL
176 static int
177 myPyMac_GetOptFSSpecPtr(PyObject *v, FSSpec **spec)
179 if (v == Py_None) {
180 *spec = NULL;
181 return 1;
183 return PyMac_GetFSSpec(v, *spec);
186 static int
187 myPyMac_GetOptFSRefPtr(PyObject *v, FSRef **ref)
189 if (v == Py_None) {
190 *ref = NULL;
191 return 1;
193 return PyMac_GetFSRef(v, *ref);
197 ** Parse/generate objsect
199 static PyObject *
200 PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
203 return Py_BuildValue("u#", itself->unicode, itself->length);
207 finalstuff = finalstuff + """
209 PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
211 Str255 path;
212 short refnum;
213 long parid;
214 OSErr err;
215 FSRef fsr;
217 if (FSSpec_Check(v)) {
218 *spec = ((FSSpecObject *)v)->ob_itself;
219 return 1;
222 if (PyArg_Parse(v, "(hlO&)",
223 &refnum, &parid, PyMac_GetStr255, &path)) {
224 err = FSMakeFSSpec(refnum, parid, path, spec);
225 if ( err && err != fnfErr ) {
226 PyMac_Error(err);
227 return 0;
229 return 1;
231 PyErr_Clear();
232 #if !TARGET_API_MAC_OSX
233 /* On OS9 we now try a pathname */
234 if ( PyString_Check(v) ) {
235 /* It's a pathname */
236 if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
237 return 0;
238 refnum = 0; /* XXXX Should get CurWD here?? */
239 parid = 0;
240 err = FSMakeFSSpec(refnum, parid, path, spec);
241 if ( err && err != fnfErr ) {
242 PyMac_Error(err);
243 return 0;
245 return 1;
247 PyErr_Clear();
248 #endif
249 /* Otherwise we try to go via an FSRef. On OSX we go all the way,
250 ** on OS9 we accept only a real FSRef object
252 #if TARGET_API_MAC_OSX
253 if ( PyMac_GetFSRef(v, &fsr) ) {
254 #else
255 if (FSRef_Check(v)) {
256 fsr = ((FSRefObject *)v)->ob_itself;
257 #endif
258 err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL);
259 if (err != noErr) {
260 PyMac_Error(err);
261 return 0;
263 return 1;
265 #if !TARGET_API_MAC_OSX
266 PyErr_SetString(PyExc_TypeError, "FSSpec, FSRef, pathname or (refnum, parid, path) required");
267 #endif
268 return 0;
272 PyMac_GetFSRef(PyObject *v, FSRef *fsr)
274 OSStatus err;
275 FSSpec fss;
277 if (FSRef_Check(v)) {
278 *fsr = ((FSRefObject *)v)->ob_itself;
279 return 1;
282 #if TARGET_API_MAC_OSX
283 /* On OSX we now try a pathname */
284 if ( PyString_Check(v) || PyUnicode_Check(v)) {
285 char *path = NULL;
286 if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
287 return NULL;
288 if ( (err=FSPathMakeRef(path, fsr, NULL)) ) {
289 PyMac_Error(err);
290 return 0;
292 return 1;
294 /* XXXX Should try unicode here too */
295 #endif
296 /* Otherwise we try to go via an FSSpec */
297 #if TARGET_API_MAC_OSX
298 if (FSSpec_Check(v)) {
299 fss = ((FSSpecObject *)v)->ob_itself;
300 #else
301 if (PyMac_GetFSSpec(v, &fss)) {
302 #endif
303 if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
304 return 1;
305 PyMac_Error(err);
306 return 0;
308 PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
309 return 0;
312 extern PyObject *
313 PyMac_BuildFSSpec(FSSpec *spec)
315 return FSSpec_New(spec);
318 extern PyObject *
319 PyMac_BuildFSRef(FSRef *spec)
321 return FSRef_New(spec);
325 initstuff = initstuff + """
326 PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
327 PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
328 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
329 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
332 execfile(string.lower(MODPREFIX) + 'typetest.py')
334 # Our object types:
335 class FSCatalogInfoDefinition(PEP253Mixin, ObjectDefinition):
336 getsetlist = [
337 ("nodeFlags",
338 "return Py_BuildValue(\"H\", self->ob_itself.nodeFlags);",
339 "return PyArg_Parse(v, \"H\", &self->ob_itself.nodeFlags)-1;",
340 None
342 ("volume",
343 "return Py_BuildValue(\"h\", self->ob_itself.volume);",
344 "return PyArg_Parse(v, \"h\", &self->ob_itself.volume)-1;",
345 None
347 ("parentDirID",
348 "return Py_BuildValue(\"l\", self->ob_itself.parentDirID);",
349 "return PyArg_Parse(v, \"l\", &self->ob_itself.parentDirID)-1;",
350 None
352 ("nodeID",
353 "return Py_BuildValue(\"l\", self->ob_itself.nodeID);",
354 "return PyArg_Parse(v, \"l\", &self->ob_itself.nodeID)-1;",
355 None
357 ("createDate",
358 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.createDate);",
359 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.createDate)-1;",
360 None
362 ("contentModDate",
363 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.contentModDate);",
364 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;",
365 None
367 ("attributeModDate",
368 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.attributeModDate);",
369 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;",
370 None
372 ("accessDate",
373 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.accessDate);",
374 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;",
375 None
377 ("backupDate",
378 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.backupDate);",
379 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;",
380 None
382 ("permissions",
383 "return Py_BuildValue(\"(llll)\", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);",
384 "return PyArg_Parse(v, \"(llll)\", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;",
385 None
387 # XXXX FinderInfo TBD
388 # XXXX FinderXInfo TBD
389 ("valence",
390 "return Py_BuildValue(\"l\", self->ob_itself.valence);",
391 "return PyArg_Parse(v, \"l\", &self->ob_itself.valence)-1;",
392 None
394 ("dataLogicalSize",
395 "return Py_BuildValue(\"l\", self->ob_itself.dataLogicalSize);",
396 "return PyArg_Parse(v, \"l\", &self->ob_itself.dataLogicalSize)-1;",
397 None
399 ("dataPhysicalSize",
400 "return Py_BuildValue(\"l\", self->ob_itself.dataPhysicalSize);",
401 "return PyArg_Parse(v, \"l\", &self->ob_itself.dataPhysicalSize)-1;",
402 None
404 ("rsrcLogicalSize",
405 "return Py_BuildValue(\"l\", self->ob_itself.rsrcLogicalSize);",
406 "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcLogicalSize)-1;",
407 None
409 ("rsrcPhysicalSize",
410 "return Py_BuildValue(\"l\", self->ob_itself.rsrcPhysicalSize);",
411 "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcPhysicalSize)-1;",
412 None
414 ("sharingFlags",
415 "return Py_BuildValue(\"l\", self->ob_itself.sharingFlags);",
416 "return PyArg_Parse(v, \"l\", &self->ob_itself.sharingFlags)-1;",
417 None
419 ("userPrivileges",
420 "return Py_BuildValue(\"b\", self->ob_itself.userPrivileges);",
421 "return PyArg_Parse(v, \"b\", &self->ob_itself.userPrivileges)-1;",
422 None
425 # The same info, but in a different form
426 INITFORMAT = "HhllO&O&O&O&O&llllllb"
427 INITARGS = """&((FSCatalogInfoObject *)self)->ob_itself.nodeFlags,
428 &((FSCatalogInfoObject *)self)->ob_itself.volume,
429 &((FSCatalogInfoObject *)self)->ob_itself.parentDirID,
430 &((FSCatalogInfoObject *)self)->ob_itself.nodeID,
431 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.createDate,
432 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.contentModDate,
433 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.attributeModDate,
434 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate,
435 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate,
436 &((FSCatalogInfoObject *)self)->ob_itself.valence,
437 &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize,
438 &((FSCatalogInfoObject *)self)->ob_itself.dataPhysicalSize,
439 &((FSCatalogInfoObject *)self)->ob_itself.rsrcLogicalSize,
440 &((FSCatalogInfoObject *)self)->ob_itself.rsrcPhysicalSize,
441 &((FSCatalogInfoObject *)self)->ob_itself.sharingFlags,
442 &((FSCatalogInfoObject *)self)->ob_itself.userPrivileges"""
443 INITNAMES = """
444 "nodeFlags",
445 "volume",
446 "parentDirID",
447 "nodeID",
448 "createDate",
449 "contentModDate",
450 "atributeModDate",
451 "accessDate",
452 "backupDate",
453 "valence",
454 "dataLogicalSize",
455 "dataPhysicalSize",
456 "rsrcLogicalSize",
457 "rsrcPhysicalSize",
458 "sharingFlags",
459 "userPrivileges"
462 def __init__(self, name, prefix, itselftype):
463 ObjectDefinition.__init__(self, name, prefix, itselftype)
464 self.argref = "*" # Store FSSpecs, but pass them by address
466 def outputCheckNewArg(self):
467 Output("if (itself == NULL) return Py_None;")
469 def output_tp_newBody(self):
470 Output("PyObject *self;");
471 Output()
472 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
473 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
474 self.objecttype, self.itselftype)
475 Output("return self;")
477 def output_tp_initBody(self):
478 Output("static char *kw[] = {%s, 0};", self.INITNAMES)
479 Output()
480 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|%s\", kw, %s))",
481 self.INITFORMAT, self.INITARGS)
482 OutLbrace()
483 Output("return -1;")
484 OutRbrace()
485 Output("return 0;")
487 class FInfoDefinition(PEP253Mixin, ObjectDefinition):
488 getsetlist = [
489 ("Type",
490 "return Py_BuildValue(\"O&\", PyMac_BuildOSType, self->ob_itself.fdType);",
491 "return PyArg_Parse(v, \"O&\", PyMac_GetOSType, &self->ob_itself.fdType)-1;",
492 "4-char file type"
494 ("Creator",
495 "return Py_BuildValue(\"O&\", PyMac_BuildOSType, self->ob_itself.fdCreator);",
496 "return PyArg_Parse(v, \"O&\", PyMac_GetOSType, &self->ob_itself.fdCreator)-1;",
497 "4-char file creator"
499 ("Flags",
500 "return Py_BuildValue(\"H\", self->ob_itself.fdFlags);",
501 "return PyArg_Parse(v, \"H\", &self->ob_itself.fdFlags)-1;",
502 "Finder flag bits"
504 ("Location",
505 "return Py_BuildValue(\"O&\", PyMac_BuildPoint, self->ob_itself.fdLocation);",
506 "return PyArg_Parse(v, \"O&\", PyMac_GetPoint, &self->ob_itself.fdLocation)-1;",
507 "(x, y) location of the file's icon in its parent finder window"
509 ("Fldr",
510 "return Py_BuildValue(\"h\", self->ob_itself.fdFldr);",
511 "return PyArg_Parse(v, \"h\", &self->ob_itself.fdFldr)-1;",
512 "Original folder, for 'put away'"
517 def __init__(self, name, prefix, itselftype):
518 ObjectDefinition.__init__(self, name, prefix, itselftype)
519 self.argref = "*" # Store FSSpecs, but pass them by address
521 def outputCheckNewArg(self):
522 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
524 def output_tp_newBody(self):
525 Output("PyObject *self;");
526 Output()
527 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
528 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
529 self.objecttype, self.itselftype)
530 Output("return self;")
532 def output_tp_initBody(self):
533 Output("%s *itself = NULL;", self.itselftype)
534 Output("static char *kw[] = {\"itself\", 0};")
535 Output()
536 Output("if (PyArg_ParseTupleAndKeywords(args, kwds, \"|O&\", kw, FInfo_Convert, &itself))")
537 OutLbrace()
538 Output("if (itself) memcpy(&((%s *)self)->ob_itself, itself, sizeof(%s));",
539 self.objecttype, self.itselftype)
540 Output("return 0;")
541 OutRbrace()
542 Output("return -1;")
544 class FSSpecDefinition(PEP253Mixin, ObjectDefinition):
545 getsetlist = [
546 ("data",
547 "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
548 None,
549 "Raw data of the FSSpec object"
553 def __init__(self, name, prefix, itselftype):
554 ObjectDefinition.__init__(self, name, prefix, itselftype)
555 self.argref = "*" # Store FSSpecs, but pass them by address
557 def outputCheckNewArg(self):
558 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
560 # We do Convert ourselves (with PyMac_GetFSxxx)
561 def outputConvert(self):
562 pass
564 def output_tp_newBody(self):
565 Output("PyObject *self;");
566 Output()
567 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
568 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
569 self.objecttype, self.itselftype)
570 Output("return self;")
572 def output_tp_initBody(self):
573 Output("PyObject *v = NULL;")
574 Output("char *rawdata = NULL;")
575 Output("int rawdatalen = 0;")
576 Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
577 Output()
578 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))")
579 Output("return -1;")
580 Output("if (v && rawdata)")
581 OutLbrace()
582 Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
583 Output("return -1;")
584 OutRbrace()
585 Output("if (!v && !rawdata)")
586 OutLbrace()
587 Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
588 Output("return -1;")
589 OutRbrace()
590 Output("if (rawdata)")
591 OutLbrace()
592 Output("if (rawdatalen != sizeof(%s))", self.itselftype)
593 OutLbrace()
594 Output("PyErr_SetString(PyExc_TypeError, \"%s rawdata incorrect size\");",
595 self.itselftype)
596 Output("return -1;")
597 OutRbrace()
598 Output("memcpy(&((%s *)self)->ob_itself, rawdata, rawdatalen);", self.objecttype)
599 Output("return 0;")
600 OutRbrace()
601 Output("if (PyMac_GetFSSpec(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype)
602 Output("return -1;")
604 def outputRepr(self):
605 Output()
606 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
607 OutLbrace()
608 Output("char buf[512];")
609 Output("""PyOS_snprintf(buf, sizeof(buf), \"%%s((%%d, %%ld, '%%.*s'))\",
610 self->ob_type->tp_name,
611 self->ob_itself.vRefNum,
612 self->ob_itself.parID,
613 self->ob_itself.name[0], self->ob_itself.name+1);""")
614 Output("return PyString_FromString(buf);")
615 OutRbrace()
617 class FSRefDefinition(PEP253Mixin, ObjectDefinition):
618 getsetlist = [
619 ("data",
620 "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
621 None,
622 "Raw data of the FSRef object"
626 def __init__(self, name, prefix, itselftype):
627 ObjectDefinition.__init__(self, name, prefix, itselftype)
628 self.argref = "*" # Store FSRefs, but pass them by address
630 def outputCheckNewArg(self):
631 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
633 # We do Convert ourselves (with PyMac_GetFSxxx)
634 def outputConvert(self):
635 pass
637 def output_tp_newBody(self):
638 Output("PyObject *self;");
639 Output()
640 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
641 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
642 self.objecttype, self.itselftype)
643 Output("return self;")
645 def output_tp_initBody(self):
646 Output("PyObject *v = NULL;")
647 Output("char *rawdata = NULL;")
648 Output("int rawdatalen = 0;")
649 Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
650 Output()
651 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))")
652 Output("return -1;")
653 Output("if (v && rawdata)")
654 OutLbrace()
655 Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
656 Output("return -1;")
657 OutRbrace()
658 Output("if (!v && !rawdata)")
659 OutLbrace()
660 Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
661 Output("return -1;")
662 OutRbrace()
663 Output("if (rawdata)")
664 OutLbrace()
665 Output("if (rawdatalen != sizeof(%s))", self.itselftype)
666 OutLbrace()
667 Output("PyErr_SetString(PyExc_TypeError, \"%s rawdata incorrect size\");",
668 self.itselftype)
669 Output("return -1;")
670 OutRbrace()
671 Output("memcpy(&((%s *)self)->ob_itself, rawdata, rawdatalen);", self.objecttype)
672 Output("return 0;")
673 OutRbrace()
674 Output("if (PyMac_GetFSRef(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype)
675 Output("return -1;")
677 class AliasDefinition(PEP253Mixin, ObjectDefinition):
678 # XXXX Should inherit from resource?
679 getsetlist = [
680 ("data",
681 """int size;
682 PyObject *rv;
684 size = GetHandleSize((Handle)self->ob_itself);
685 HLock((Handle)self->ob_itself);
686 rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
687 HUnlock((Handle)self->ob_itself);
688 return rv;
689 """,
690 None,
691 "Raw data of the alias object"
695 def outputCheckNewArg(self):
696 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
698 def outputStructMembers(self):
699 ObjectDefinition.outputStructMembers(self)
700 Output("void (*ob_freeit)(%s ptr);", self.itselftype)
702 def outputInitStructMembers(self):
703 ObjectDefinition.outputInitStructMembers(self)
704 Output("it->ob_freeit = NULL;")
706 def outputCleanupStructMembers(self):
707 Output("if (self->ob_freeit && self->ob_itself)")
708 OutLbrace()
709 Output("self->ob_freeit(self->ob_itself);")
710 OutRbrace()
711 Output("self->ob_itself = NULL;")
713 def output_tp_newBody(self):
714 Output("PyObject *self;");
715 Output()
716 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
717 Output("((%s *)self)->ob_itself = NULL;", self.objecttype)
718 Output("return self;")
720 def output_tp_initBody(self):
721 Output("%s itself = NULL;", self.itselftype)
722 Output("char *rawdata = NULL;")
723 Output("int rawdatalen = 0;")
724 Output("Handle h;")
725 Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
726 Output()
727 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|O&s#\", kw, %s_Convert, &itself, &rawdata, &rawdatalen))",
728 self.prefix)
729 Output("return -1;")
730 Output("if (itself && rawdata)")
731 OutLbrace()
732 Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
733 Output("return -1;")
734 OutRbrace()
735 Output("if (!itself && !rawdata)")
736 OutLbrace()
737 Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
738 Output("return -1;")
739 OutRbrace()
740 Output("if (rawdata)")
741 OutLbrace()
742 Output("if ((h = NewHandle(rawdatalen)) == NULL)")
743 OutLbrace()
744 Output("PyErr_NoMemory();")
745 Output("return -1;")
746 OutRbrace()
747 Output("HLock(h);")
748 Output("memcpy((char *)*h, rawdata, rawdatalen);")
749 Output("HUnlock(h);")
750 Output("((%s *)self)->ob_itself = (%s)h;", self.objecttype, self.itselftype)
751 Output("return 0;")
752 OutRbrace()
753 Output("((%s *)self)->ob_itself = itself;", self.objecttype)
754 Output("return 0;")
756 # Alias methods come in two flavors: those with the alias as arg1 and
757 # those with the alias as arg 2.
758 class Arg2MethodGenerator(OSErrMethodGenerator):
759 """Similar to MethodGenerator, but has self as second argument"""
761 def parseArgumentList(self, args):
762 args0, arg1, argsrest = args[:1], args[1], args[2:]
763 t0, n0, m0 = arg1
764 args = args0 + argsrest
765 if m0 != InMode:
766 raise ValueError, "method's 'self' must be 'InMode'"
767 self.itself = Variable(t0, "_self->ob_itself", SelfMode)
768 FunctionGenerator.parseArgumentList(self, args)
769 self.argumentList.insert(2, self.itself)
771 # From here on it's basically all boiler plate...
773 # Create the generator groups and link them
774 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff,
775 longname=LONGMODNAME)
777 fscataloginfoobject = FSCatalogInfoDefinition('FSCatalogInfo', 'FSCatalogInfo', 'FSCatalogInfo')
778 finfoobject = FInfoDefinition('FInfo', 'FInfo', 'FInfo')
779 aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle')
780 fsspecobject = FSSpecDefinition('FSSpec', 'FSSpec', 'FSSpec')
781 fsrefobject = FSRefDefinition('FSRef', 'FSRef', 'FSRef')
783 module.addobject(fscataloginfoobject)
784 module.addobject(finfoobject)
785 module.addobject(aliasobject)
786 module.addobject(fsspecobject)
787 module.addobject(fsrefobject)
789 # Create the generator classes used to populate the lists
790 Function = OSErrFunctionGenerator
791 Method = OSErrMethodGenerator
793 # Create and populate the lists
794 functions = []
795 alias_methods = []
796 fsref_methods = []
797 fsspec_methods = []
798 execfile(INPUTFILE)
800 # Manual generators:
801 FSRefMakePath_body = """
802 OSStatus _err;
803 #define MAXPATHNAME 1024
804 UInt8 path[MAXPATHNAME];
805 UInt32 maxPathSize = MAXPATHNAME;
807 if (!PyArg_ParseTuple(_args, ""))
808 return NULL;
809 _err = FSRefMakePath(&_self->ob_itself,
810 path,
811 maxPathSize);
812 if (_err != noErr) return PyMac_Error(_err);
813 _res = Py_BuildValue("s", path);
814 return _res;
816 f = ManualGenerator("FSRefMakePath", FSRefMakePath_body)
817 f.docstring = lambda: "() -> string"
818 fsref_methods.append(f)
820 FSRef_as_pathname_body = """
821 #if TARGET_API_MAC_OSX
822 if (!PyArg_ParseTuple(_args, ""))
823 return NULL;
824 _res = FSRef_FSRefMakePath(_self, _args);
825 #else
826 char strbuf[1024];
827 OSErr err;
828 FSSpec fss;
830 if (!PyArg_ParseTuple(_args, ""))
831 return NULL;
832 if ( !PyMac_GetFSSpec((PyObject *)_self, &fss))
833 return NULL;
834 err = PyMac_GetFullPathname(&fss, strbuf, sizeof(strbuf));
835 if ( err ) {
836 PyMac_Error(err);
837 return NULL;
839 _res = PyString_FromString(strbuf);
840 #endif
841 return _res;
843 f = ManualGenerator("as_pathname", FSRef_as_pathname_body)
844 f.docstring = lambda: "() -> string"
845 fsref_methods.append(f)
847 FSSpec_as_pathname_body = """
848 char strbuf[1024];
849 OSErr err;
851 if (!PyArg_ParseTuple(_args, ""))
852 return NULL;
853 err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
854 if ( err ) {
855 PyMac_Error(err);
856 return NULL;
858 _res = PyString_FromString(strbuf);
859 return _res;
861 f = ManualGenerator("as_pathname", FSSpec_as_pathname_body)
862 f.docstring = lambda: "() -> string"
863 fsspec_methods.append(f)
865 FSSpec_as_tuple_body = """
866 if (!PyArg_ParseTuple(_args, ""))
867 return NULL;
868 _res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID,
869 &_self->ob_itself.name[1], _self->ob_itself.name[0]);
870 return _res;
872 f = ManualGenerator("as_tuple", FSSpec_as_tuple_body)
873 f.docstring = lambda: "() -> (vRefNum, dirID, name)"
874 fsspec_methods.append(f)
876 pathname_body = """
877 PyObject *obj;
879 if (!PyArg_ParseTuple(_args, "O", &obj))
880 return NULL;
881 if (PyString_Check(obj)) {
882 Py_INCREF(obj);
883 return obj;
885 if (PyUnicode_Check(obj))
886 return PyUnicode_AsEncodedString(obj, "utf8", "strict");
887 _res = PyObject_CallMethod(obj, "as_pathname", NULL);
888 return _res;
890 f = ManualGenerator("pathname", pathname_body)
891 f.docstring = lambda: "(str|unicode|FSSpec|FSref) -> pathname"
892 functions.append(f)
894 # add the populated lists to the generator groups
895 # (in a different wordl the scan program would generate this)
896 for f in functions: module.add(f)
897 for f in alias_methods: aliasobject.add(f)
898 for f in fsspec_methods: fsspecobject.add(f)
899 for f in fsref_methods: fsrefobject.add(f)
901 # generate output (open the output file as late as possible)
902 SetOutputFileName(OUTPUTFILE)
903 module.generate()