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