Update for release.
[python/dscho.git] / Mac / Modules / file / filesupport.py
blob26821ddd69a0f3d06994396178493f7dd74305f2
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 ( PyArg_Parse(v, "O&", FSRef_Convert, &fsr) ) {
256 #endif
257 err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL);
258 if (err != noErr) {
259 PyMac_Error(err);
260 return 0;
262 return 1;
264 #if !TARGET_API_MAC_OSX
265 PyErr_SetString(PyExc_TypeError, "FSSpec, FSRef, pathname or (refnum, parid, path) required");
266 #endif
267 return 0;
271 PyMac_GetFSRef(PyObject *v, FSRef *fsr)
273 OSStatus err;
274 FSSpec fss;
276 if (FSRef_Check(v)) {
277 *fsr = ((FSRefObject *)v)->ob_itself;
278 return 1;
281 #if TARGET_API_MAC_OSX
282 /* On OSX we now try a pathname */
283 if ( PyString_Check(v) ) {
284 if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) {
285 PyMac_Error(err);
286 return 0;
288 return 1;
290 /* XXXX Should try unicode here too */
291 #endif
292 /* Otherwise we try to go via an FSSpec */
293 #if TARGET_API_MAC_OSX
294 if (FSSpec_Check(v)) {
295 fss = ((FSSpecObject *)v)->ob_itself;
296 #else
297 if (PyMac_GetFSSpec(v, &fss)) {
298 #endif
299 if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
300 return 1;
301 PyMac_Error(err);
302 return 0;
304 PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
305 return 0;
308 extern PyObject *
309 PyMac_BuildFSSpec(FSSpec *spec)
311 return FSSpec_New(spec);
314 extern PyObject *
315 PyMac_BuildFSRef(FSRef *spec)
317 return FSRef_New(spec);
321 initstuff = initstuff + """
322 PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
323 PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
324 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
325 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
328 execfile(string.lower(MODPREFIX) + 'typetest.py')
330 # Our object types:
331 class FSCatalogInfoDefinition(PEP253Mixin, ObjectDefinition):
332 getsetlist = [
333 ("nodeFlags",
334 "return Py_BuildValue(\"H\", self->ob_itself.nodeFlags);",
335 "return PyArg_Parse(v, \"H\", &self->ob_itself.nodeFlags)-1;",
336 None
338 ("volume",
339 "return Py_BuildValue(\"h\", self->ob_itself.volume);",
340 "return PyArg_Parse(v, \"h\", &self->ob_itself.volume)-1;",
341 None
343 ("parentDirID",
344 "return Py_BuildValue(\"l\", self->ob_itself.parentDirID);",
345 "return PyArg_Parse(v, \"l\", &self->ob_itself.parentDirID)-1;",
346 None
348 ("nodeID",
349 "return Py_BuildValue(\"l\", self->ob_itself.nodeID);",
350 "return PyArg_Parse(v, \"l\", &self->ob_itself.nodeID)-1;",
351 None
353 ("createDate",
354 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.createDate);",
355 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.createDate)-1;",
356 None
358 ("contentModDate",
359 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.contentModDate);",
360 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;",
361 None
363 ("attributeModDate",
364 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.attributeModDate);",
365 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;",
366 None
368 ("accessDate",
369 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.accessDate);",
370 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;",
371 None
373 ("backupDate",
374 "return Py_BuildValue(\"O&\", UTCDateTime_New, &self->ob_itself.backupDate);",
375 "return PyArg_Parse(v, \"O&\", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;",
376 None
378 ("permissions",
379 "return Py_BuildValue(\"(llll)\", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);",
380 "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;",
381 None
383 # XXXX FinderInfo TBD
384 # XXXX FinderXInfo TBD
385 ("valence",
386 "return Py_BuildValue(\"l\", self->ob_itself.valence);",
387 "return PyArg_Parse(v, \"l\", &self->ob_itself.valence)-1;",
388 None
390 ("dataLogicalSize",
391 "return Py_BuildValue(\"l\", self->ob_itself.dataLogicalSize);",
392 "return PyArg_Parse(v, \"l\", &self->ob_itself.dataLogicalSize)-1;",
393 None
395 ("dataPhysicalSize",
396 "return Py_BuildValue(\"l\", self->ob_itself.dataPhysicalSize);",
397 "return PyArg_Parse(v, \"l\", &self->ob_itself.dataPhysicalSize)-1;",
398 None
400 ("rsrcLogicalSize",
401 "return Py_BuildValue(\"l\", self->ob_itself.rsrcLogicalSize);",
402 "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcLogicalSize)-1;",
403 None
405 ("rsrcPhysicalSize",
406 "return Py_BuildValue(\"l\", self->ob_itself.rsrcPhysicalSize);",
407 "return PyArg_Parse(v, \"l\", &self->ob_itself.rsrcPhysicalSize)-1;",
408 None
410 ("sharingFlags",
411 "return Py_BuildValue(\"l\", self->ob_itself.sharingFlags);",
412 "return PyArg_Parse(v, \"l\", &self->ob_itself.sharingFlags)-1;",
413 None
415 ("userPrivileges",
416 "return Py_BuildValue(\"b\", self->ob_itself.userPrivileges);",
417 "return PyArg_Parse(v, \"b\", &self->ob_itself.userPrivileges)-1;",
418 None
421 # The same info, but in a different form
422 INITFORMAT = "HhllO&O&O&O&O&llllllb"
423 INITARGS = """&((FSCatalogInfoObject *)self)->ob_itself.nodeFlags,
424 &((FSCatalogInfoObject *)self)->ob_itself.volume,
425 &((FSCatalogInfoObject *)self)->ob_itself.parentDirID,
426 &((FSCatalogInfoObject *)self)->ob_itself.nodeID,
427 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.createDate,
428 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.contentModDate,
429 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.attributeModDate,
430 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate,
431 UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate,
432 &((FSCatalogInfoObject *)self)->ob_itself.valence,
433 &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize,
434 &((FSCatalogInfoObject *)self)->ob_itself.dataPhysicalSize,
435 &((FSCatalogInfoObject *)self)->ob_itself.rsrcLogicalSize,
436 &((FSCatalogInfoObject *)self)->ob_itself.rsrcPhysicalSize,
437 &((FSCatalogInfoObject *)self)->ob_itself.sharingFlags,
438 &((FSCatalogInfoObject *)self)->ob_itself.userPrivileges"""
439 INITNAMES = """
440 "nodeFlags",
441 "volume",
442 "parentDirID",
443 "nodeID",
444 "createDate",
445 "contentModDate",
446 "atributeModDate",
447 "accessDate",
448 "backupDate",
449 "valence",
450 "dataLogicalSize",
451 "dataPhysicalSize",
452 "rsrcLogicalSize",
453 "rsrcPhysicalSize",
454 "sharingFlags",
455 "userPrivileges"
458 def __init__(self, name, prefix, itselftype):
459 ObjectDefinition.__init__(self, name, prefix, itselftype)
460 self.argref = "*" # Store FSSpecs, but pass them by address
462 def outputCheckNewArg(self):
463 Output("if (itself == NULL) return Py_None;")
465 def output_tp_newBody(self):
466 Output("PyObject *self;");
467 Output()
468 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
469 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
470 self.objecttype, self.itselftype)
471 Output("return self;")
473 def output_tp_initBody(self):
474 Output("static char *kw[] = {%s, 0};", self.INITNAMES)
475 Output()
476 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|%s\", kw, %s))",
477 self.INITFORMAT, self.INITARGS)
478 OutLbrace()
479 Output("return -1;")
480 OutRbrace()
481 Output("return 0;")
483 class FInfoDefinition(PEP253Mixin, ObjectDefinition):
484 getsetlist = [
485 ("Type",
486 "return Py_BuildValue(\"O&\", PyMac_BuildOSType, self->ob_itself.fdType);",
487 "return PyArg_Parse(v, \"O&\", PyMac_GetOSType, &self->ob_itself.fdType)-1;",
488 "4-char file type"
490 ("Creator",
491 "return Py_BuildValue(\"O&\", PyMac_BuildOSType, self->ob_itself.fdCreator);",
492 "return PyArg_Parse(v, \"O&\", PyMac_GetOSType, &self->ob_itself.fdCreator)-1;",
493 "4-char file creator"
495 ("Flags",
496 "return Py_BuildValue(\"H\", self->ob_itself.fdFlags);",
497 "return PyArg_Parse(v, \"H\", &self->ob_itself.fdFlags)-1;",
498 "Finder flag bits"
500 ("Location",
501 "return Py_BuildValue(\"O&\", PyMac_BuildPoint, self->ob_itself.fdLocation);",
502 "return PyArg_Parse(v, \"O&\", PyMac_GetPoint, &self->ob_itself.fdLocation)-1;",
503 "(x, y) location of the file's icon in its parent finder window"
505 ("Fldr",
506 "return Py_BuildValue(\"h\", self->ob_itself.fdFldr);",
507 "return PyArg_Parse(v, \"h\", &self->ob_itself.fdFldr)-1;",
508 "Original folder, for 'put away'"
513 def __init__(self, name, prefix, itselftype):
514 ObjectDefinition.__init__(self, name, prefix, itselftype)
515 self.argref = "*" # Store FSSpecs, but pass them by address
517 def outputCheckNewArg(self):
518 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
520 def output_tp_newBody(self):
521 Output("PyObject *self;");
522 Output()
523 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
524 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
525 self.objecttype, self.itselftype)
526 Output("return self;")
528 def output_tp_initBody(self):
529 Output("%s *itself = NULL;", self.itselftype)
530 Output("static char *kw[] = {\"itself\", 0};")
531 Output()
532 Output("if (PyArg_ParseTupleAndKeywords(args, kwds, \"|O&\", kw, FInfo_Convert, &itself))")
533 OutLbrace()
534 Output("if (itself) memcpy(&((%s *)self)->ob_itself, itself, sizeof(%s));",
535 self.objecttype, self.itselftype)
536 Output("return 0;")
537 OutRbrace()
538 Output("return -1;")
540 class FSSpecDefinition(PEP253Mixin, ObjectDefinition):
541 getsetlist = [
542 ("data",
543 "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
544 None,
545 "Raw data of the FSSpec object"
549 def __init__(self, name, prefix, itselftype):
550 ObjectDefinition.__init__(self, name, prefix, itselftype)
551 self.argref = "*" # Store FSSpecs, but pass them by address
553 def outputCheckNewArg(self):
554 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
556 # We do Convert ourselves (with PyMac_GetFSxxx)
557 def outputConvert(self):
558 pass
560 def output_tp_newBody(self):
561 Output("PyObject *self;");
562 Output()
563 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
564 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
565 self.objecttype, self.itselftype)
566 Output("return self;")
568 def output_tp_initBody(self):
569 Output("PyObject *v = NULL;")
570 Output("char *rawdata = NULL;")
571 Output("int rawdatalen = 0;")
572 Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
573 Output()
574 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))")
575 Output("return -1;")
576 Output("if (v && rawdata)")
577 OutLbrace()
578 Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
579 Output("return -1;")
580 OutRbrace()
581 Output("if (!v && !rawdata)")
582 OutLbrace()
583 Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
584 Output("return -1;")
585 OutRbrace()
586 Output("if (rawdata)")
587 OutLbrace()
588 Output("if (rawdatalen != sizeof(%s))", self.itselftype)
589 OutLbrace()
590 Output("PyErr_SetString(PyExc_TypeError, \"%s rawdata incorrect size\");",
591 self.itselftype)
592 Output("return -1;")
593 OutRbrace()
594 Output("memcpy(&((%s *)self)->ob_itself, rawdata, rawdatalen);", self.objecttype)
595 Output("return 0;")
596 OutRbrace()
597 Output("if (PyMac_GetFSSpec(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype)
598 Output("return -1;")
600 def outputRepr(self):
601 Output()
602 Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
603 OutLbrace()
604 Output("char buf[512];")
605 Output("""PyOS_snprintf(buf, sizeof(buf), \"%%s((%%d, %%ld, '%%.*s'))\",
606 self->ob_type->tp_name,
607 self->ob_itself.vRefNum,
608 self->ob_itself.parID,
609 self->ob_itself.name[0], self->ob_itself.name+1);""")
610 Output("return PyString_FromString(buf);")
611 OutRbrace()
613 class FSRefDefinition(PEP253Mixin, ObjectDefinition):
614 getsetlist = [
615 ("data",
616 "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
617 None,
618 "Raw data of the FSRef object"
622 def __init__(self, name, prefix, itselftype):
623 ObjectDefinition.__init__(self, name, prefix, itselftype)
624 self.argref = "*" # Store FSRefs, but pass them by address
626 def outputCheckNewArg(self):
627 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
629 # We do Convert ourselves (with PyMac_GetFSxxx)
630 def outputConvert(self):
631 pass
633 def output_tp_newBody(self):
634 Output("PyObject *self;");
635 Output()
636 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
637 Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));",
638 self.objecttype, self.itselftype)
639 Output("return self;")
641 def output_tp_initBody(self):
642 Output("PyObject *v = NULL;")
643 Output("char *rawdata = NULL;")
644 Output("int rawdatalen = 0;")
645 Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
646 Output()
647 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|Os#\", kw, &v, &rawdata, &rawdatalen))")
648 Output("return -1;")
649 Output("if (v && rawdata)")
650 OutLbrace()
651 Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
652 Output("return -1;")
653 OutRbrace()
654 Output("if (!v && !rawdata)")
655 OutLbrace()
656 Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
657 Output("return -1;")
658 OutRbrace()
659 Output("if (rawdata)")
660 OutLbrace()
661 Output("if (rawdatalen != sizeof(%s))", self.itselftype)
662 OutLbrace()
663 Output("PyErr_SetString(PyExc_TypeError, \"%s rawdata incorrect size\");",
664 self.itselftype)
665 Output("return -1;")
666 OutRbrace()
667 Output("memcpy(&((%s *)self)->ob_itself, rawdata, rawdatalen);", self.objecttype)
668 Output("return 0;")
669 OutRbrace()
670 Output("if (PyMac_GetFSRef(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype)
671 Output("return -1;")
673 class AliasDefinition(PEP253Mixin, ObjectDefinition):
674 # XXXX Should inherit from resource?
675 getsetlist = [
676 ("data",
677 """int size;
678 PyObject *rv;
680 size = GetHandleSize((Handle)self->ob_itself);
681 HLock((Handle)self->ob_itself);
682 rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
683 HUnlock((Handle)self->ob_itself);
684 return rv;
685 """,
686 None,
687 "Raw data of the alias object"
691 def outputCheckNewArg(self):
692 Output("if (itself == NULL) return PyMac_Error(resNotFound);")
694 def outputStructMembers(self):
695 ObjectDefinition.outputStructMembers(self)
696 Output("void (*ob_freeit)(%s ptr);", self.itselftype)
698 def outputInitStructMembers(self):
699 ObjectDefinition.outputInitStructMembers(self)
700 Output("it->ob_freeit = NULL;")
702 def outputCleanupStructMembers(self):
703 Output("if (self->ob_freeit && self->ob_itself)")
704 OutLbrace()
705 Output("self->ob_freeit(self->ob_itself);")
706 OutRbrace()
707 Output("self->ob_itself = NULL;")
709 def output_tp_newBody(self):
710 Output("PyObject *self;");
711 Output()
712 Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
713 Output("((%s *)self)->ob_itself = NULL;", self.objecttype)
714 Output("return self;")
716 def output_tp_initBody(self):
717 Output("%s itself = NULL;", self.itselftype)
718 Output("char *rawdata = NULL;")
719 Output("int rawdatalen = 0;")
720 Output("Handle h;")
721 Output("static char *kw[] = {\"itself\", \"rawdata\", 0};")
722 Output()
723 Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"|O&s#\", kw, %s_Convert, &itself, &rawdata, &rawdatalen))",
724 self.prefix)
725 Output("return -1;")
726 Output("if (itself && rawdata)")
727 OutLbrace()
728 Output("PyErr_SetString(PyExc_TypeError, \"Only one of itself or rawdata may be specified\");")
729 Output("return -1;")
730 OutRbrace()
731 Output("if (!itself && !rawdata)")
732 OutLbrace()
733 Output("PyErr_SetString(PyExc_TypeError, \"One of itself or rawdata must be specified\");")
734 Output("return -1;")
735 OutRbrace()
736 Output("if (rawdata)")
737 OutLbrace()
738 Output("if ((h = NewHandle(rawdatalen)) == NULL)")
739 OutLbrace()
740 Output("PyErr_NoMemory();")
741 Output("return -1;")
742 OutRbrace()
743 Output("HLock(h);")
744 Output("memcpy((char *)*h, rawdata, rawdatalen);")
745 Output("HUnlock(h);")
746 Output("((%s *)self)->ob_itself = (%s)h;", self.objecttype, self.itselftype)
747 Output("return 0;")
748 OutRbrace()
749 Output("((%s *)self)->ob_itself = itself;", self.objecttype)
750 Output("return 0;")
752 # Alias methods come in two flavors: those with the alias as arg1 and
753 # those with the alias as arg 2.
754 class Arg2MethodGenerator(OSErrMethodGenerator):
755 """Similar to MethodGenerator, but has self as second argument"""
757 def parseArgumentList(self, args):
758 args0, arg1, argsrest = args[:1], args[1], args[2:]
759 t0, n0, m0 = arg1
760 args = args0 + argsrest
761 if m0 != InMode:
762 raise ValueError, "method's 'self' must be 'InMode'"
763 self.itself = Variable(t0, "_self->ob_itself", SelfMode)
764 FunctionGenerator.parseArgumentList(self, args)
765 self.argumentList.insert(2, self.itself)
767 # From here on it's basically all boiler plate...
769 # Create the generator groups and link them
770 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff,
771 longname=LONGMODNAME)
773 fscataloginfoobject = FSCatalogInfoDefinition('FSCatalogInfo', 'FSCatalogInfo', 'FSCatalogInfo')
774 finfoobject = FInfoDefinition('FInfo', 'FInfo', 'FInfo')
775 aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle')
776 fsspecobject = FSSpecDefinition('FSSpec', 'FSSpec', 'FSSpec')
777 fsrefobject = FSRefDefinition('FSRef', 'FSRef', 'FSRef')
779 module.addobject(fscataloginfoobject)
780 module.addobject(finfoobject)
781 module.addobject(aliasobject)
782 module.addobject(fsspecobject)
783 module.addobject(fsrefobject)
785 # Create the generator classes used to populate the lists
786 Function = OSErrFunctionGenerator
787 Method = OSErrMethodGenerator
789 # Create and populate the lists
790 functions = []
791 alias_methods = []
792 fsref_methods = []
793 fsspec_methods = []
794 execfile(INPUTFILE)
796 # Manual generators:
797 FSRefMakePath_body = """
798 OSStatus _err;
799 #define MAXPATHNAME 1024
800 UInt8 path[MAXPATHNAME];
801 UInt32 maxPathSize = MAXPATHNAME;
803 if (!PyArg_ParseTuple(_args, ""))
804 return NULL;
805 _err = FSRefMakePath(&_self->ob_itself,
806 path,
807 maxPathSize);
808 if (_err != noErr) return PyMac_Error(_err);
809 _res = Py_BuildValue("s", path);
810 return _res;
812 f = ManualGenerator("FSRefMakePath", FSRefMakePath_body)
813 f.docstring = lambda: "() -> string"
814 fsref_methods.append(f)
816 FSRef_as_pathname_body = """
817 #if TARGET_API_MAC_OSX
818 if (!PyArg_ParseTuple(_args, ""))
819 return NULL;
820 _res = FSRef_FSRefMakePath(_self, _args);
821 #else
822 char strbuf[1024];
823 OSErr err;
824 FSSpec fss;
826 if (!PyArg_ParseTuple(_args, ""))
827 return NULL;
828 if ( !PyMac_GetFSSpec((PyObject *)_self, &fss))
829 return NULL;
830 err = PyMac_GetFullPathname(&fss, strbuf, sizeof(strbuf));
831 if ( err ) {
832 PyMac_Error(err);
833 return NULL;
835 _res = PyString_FromString(strbuf);
836 #endif
837 return _res;
839 f = ManualGenerator("as_pathname", FSRef_as_pathname_body)
840 f.docstring = lambda: "() -> string"
841 fsref_methods.append(f)
843 FSSpec_as_pathname_body = """
844 char strbuf[1024];
845 OSErr err;
847 if (!PyArg_ParseTuple(_args, ""))
848 return NULL;
849 err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
850 if ( err ) {
851 PyMac_Error(err);
852 return NULL;
854 _res = PyString_FromString(strbuf);
855 return _res;
857 f = ManualGenerator("as_pathname", FSSpec_as_pathname_body)
858 f.docstring = lambda: "() -> string"
859 fsspec_methods.append(f)
861 FSSpec_as_tuple_body = """
862 if (!PyArg_ParseTuple(_args, ""))
863 return NULL;
864 _res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID,
865 &_self->ob_itself.name[1], _self->ob_itself.name[0]);
866 return _res;
868 f = ManualGenerator("as_tuple", FSSpec_as_tuple_body)
869 f.docstring = lambda: "() -> (vRefNum, dirID, name)"
870 fsspec_methods.append(f)
872 pathname_body = """
873 PyObject *obj;
875 if (!PyArg_ParseTuple(_args, "O", &obj))
876 return NULL;
877 if (PyString_Check(obj))
878 return obj;
879 if (PyUnicode_Check(obj))
880 return PyUnicode_AsEncodedString(obj, "utf8", "strict");
881 _res = PyObject_CallMethod(obj, "as_pathname", NULL);
882 return _res;
884 f = ManualGenerator("pathname", pathname_body)
885 f.docstring = lambda: "(str|unicode|FSSpec|FSref) -> pathname"
886 functions.append(f)
888 # add the populated lists to the generator groups
889 # (in a different wordl the scan program would generate this)
890 for f in functions: module.add(f)
891 for f in alias_methods: aliasobject.add(f)
892 for f in fsspec_methods: fsspecobject.add(f)
893 for f in fsref_methods: fsrefobject.add(f)
895 # generate output (open the output file as late as possible)
896 SetOutputFileName(OUTPUTFILE)
897 module.generate()