Home | History | Annotate | Download | only in file
      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 
     14 import sys
     15 sys.exit(42)
     16 
     17 import string
     18 
     19 # Declarations that change for each manager
     20 #MACHEADERFILE = 'Files.h'              # The Apple header file
     21 MODNAME = '_File'                               # The name of the module
     22 LONGMODNAME = 'Carbon.File'             # The "normal" external name of the module
     23 
     24 # The following is *usually* unchanged but may still require tuning
     25 MODPREFIX = 'File'                      # The prefix for module-wide routines
     26 INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
     27 OUTPUTFILE = MODNAME + "module.c"       # The file generated by this program
     28 
     29 from macsupport import *
     30 
     31 # Various integers:
     32 SInt64 = Type("SInt64", "L")
     33 UInt64 = Type("UInt64", "L")
     34 FNMessage = Type("FNMessage", "l")
     35 FSAllocationFlags = Type("FSAllocationFlags", "H")
     36 FSCatalogInfoBitmap = Type("FSCatalogInfoBitmap", "l")
     37 FSIteratorFlags = Type("FSIteratorFlags", "l")
     38 FSVolumeRefNum = Type("FSVolumeRefNum", "h")
     39 AliasInfoType = Type("AliasInfoType", "h")
     40 
     41 # Various types of strings:
     42 #class UniCharCountBuffer(InputOnlyType):
     43 #       pass
     44 class VarReverseInputBufferType(ReverseInputBufferMixin, VarInputBufferType):
     45     pass
     46 FullPathName = VarReverseInputBufferType()
     47 ConstStr31Param = OpaqueArrayType("Str31", "PyMac_BuildStr255", "PyMac_GetStr255")
     48 ConstStr32Param = OpaqueArrayType("Str32", "PyMac_BuildStr255", "PyMac_GetStr255")
     49 ConstStr63Param = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255")
     50 Str63 = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255")
     51 
     52 HFSUniStr255 = OpaqueType("HFSUniStr255", "PyMac_BuildHFSUniStr255", "PyMac_GetHFSUniStr255")
     53 UInt8_ptr = InputOnlyType("UInt8 *", "s")
     54 
     55 # Other types:
     56 class 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 
     61 class 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 
     95 class FSCatalogInfoAndBitmap_inType(FSCatalogInfoAndBitmapType, InputOnlyMixIn):
     96 
     97     def xxxxmkvalueCheck(self, name):
     98         pass
     99 
    100 class 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 
    111 FInfo = OpaqueType("FInfo", "FInfo")
    112 FInfo_ptr = OpaqueType("FInfo", "FInfo")
    113 AliasHandle = OpaqueByValueType("AliasHandle", "Alias")
    114 FSSpec = OpaqueType("FSSpec", "FSSpec")
    115 FSSpec_ptr = OpaqueType("FSSpec", "FSSpec")
    116 OptFSSpecPtr = OptionalFSxxxType("FSSpec", "BUG", "myPyMac_GetOptFSSpecPtr")
    117 FSRef = OpaqueType("FSRef", "FSRef")
    118 FSRef_ptr = OpaqueType("FSRef", "FSRef")
    119 OptFSRefPtr = OptionalFSxxxType("FSRef", "BUG", "myPyMac_GetOptFSRefPtr")
    120 FSCatalogInfo = OpaqueType("FSCatalogInfo", "FSCatalogInfo")
    121 FSCatalogInfo_ptr = OpaqueType("FSCatalogInfo", "FSCatalogInfo")
    122 
    123 # To be done:
    124 #CatPositionRec
    125 #FSCatalogInfo
    126 #FSForkInfo
    127 #FSIterator
    128 #FSVolumeInfo
    129 #FSSpecArrayPtr
    130 
    131 includestuff = includestuff + """
    132 #include <Carbon/Carbon.h>
    133 
    134 #ifdef USE_TOOLBOX_OBJECT_GLUE
    135 extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
    136 extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
    137 extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
    138 extern 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
    145 extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
    146 extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
    147 extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
    148 extern PyObject *PyMac_BuildFSRef(FSRef *spec);
    149 #endif
    150 
    151 /* Forward declarations */
    152 static PyObject *FInfo_New(FInfo *itself);
    153 static PyObject *FSRef_New(FSRef *itself);
    154 static PyObject *FSSpec_New(FSSpec *itself);
    155 static PyObject *Alias_New(AliasHandle itself);
    156 static int FInfo_Convert(PyObject *v, FInfo *p_itself);
    157 #define FSRef_Convert PyMac_GetFSRef
    158 #define FSSpec_Convert PyMac_GetFSSpec
    159 static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
    160 
    161 /*
    162 ** UTCDateTime records
    163 */
    164 static int
    165 UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr)
    166 {
    167         return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction);
    168 }
    169 
    170 static PyObject *
    171 UTCDateTime_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 */
    179 static int
    180 myPyMac_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 
    189 static int
    190 myPyMac_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 */
    202 static PyObject *
    203 PyMac_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 */
    213 static 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 
    259 finalstuff = finalstuff + """
    260 
    261 #ifndef __LP64__
    262 int
    263 PyMac_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 
    302 int
    303 PyMac_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__
    341 extern PyObject *
    342 PyMac_BuildFSSpec(FSSpec *spec)
    343 {
    344         return FSSpec_New(spec);
    345 }
    346 #endif /* __LP64__ */
    347 
    348 extern PyObject *
    349 PyMac_BuildFSRef(FSRef *spec)
    350 {
    351         return FSRef_New(spec);
    352 }
    353 """
    354 
    355 initstuff = initstuff + """
    356 #ifndef __LP64__
    357 PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
    358 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
    359 #endif /* !__LP64__*/
    360 PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
    361 PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
    362 """
    363 
    364 execfile(string.lower(MODPREFIX) + 'typetest.py')
    365 
    366 # Our object types:
    367 class 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 
    519 class 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 
    576 class 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 
    649 class 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 
    709 class 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.
    790 class 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
    806 module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff,
    807         longname=LONGMODNAME)
    808 
    809 fscataloginfoobject = FSCatalogInfoDefinition('FSCatalogInfo', 'FSCatalogInfo', 'FSCatalogInfo')
    810 finfoobject = FInfoDefinition('FInfo', 'FInfo', 'FInfo')
    811 aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle')
    812 fsspecobject = FSSpecDefinition('FSSpec', 'FSSpec', 'FSSpec')
    813 fsrefobject = FSRefDefinition('FSRef', 'FSRef', 'FSRef')
    814 
    815 module.addobject(fscataloginfoobject)
    816 module.addobject(finfoobject)
    817 module.addobject(aliasobject)
    818 module.addobject(fsspecobject)
    819 module.addobject(fsrefobject)
    820 
    821 # Create the generator classes used to populate the lists
    822 Function = OSErrFunctionGenerator
    823 Method = OSErrMethodGenerator
    824 
    825 # Create and populate the lists
    826 functions = []
    827 alias_methods = []
    828 fsref_methods = []
    829 fsspec_methods = []
    830 execfile(INPUTFILE)
    831 
    832 # Manual generators:
    833 FSRefMakePath_body = """
    834 OSStatus _err;
    835 #define MAXPATHNAME 1024
    836 UInt8 path[MAXPATHNAME];
    837 UInt32 maxPathSize = MAXPATHNAME;
    838 
    839 if (!PyArg_ParseTuple(_args, ""))
    840         return NULL;
    841 _err = FSRefMakePath(&_self->ob_itself,
    842                                          path,
    843                                          maxPathSize);
    844 if (_err != noErr) return PyMac_Error(_err);
    845 _res = Py_BuildValue("s", path);
    846 return _res;
    847 """
    848 f = ManualGenerator("FSRefMakePath", FSRefMakePath_body)
    849 f.docstring = lambda: "() -> string"
    850 fsref_methods.append(f)
    851 
    852 FSRef_as_pathname_body = """
    853 if (!PyArg_ParseTuple(_args, ""))
    854         return NULL;
    855 _res = FSRef_FSRefMakePath(_self, _args);
    856 return _res;
    857 """
    858 f = ManualGenerator("as_pathname", FSRef_as_pathname_body)
    859 f.docstring = lambda: "() -> string"
    860 fsref_methods.append(f)
    861 
    862 FSSpec_as_pathname_body = """
    863 char strbuf[1024];
    864 OSErr err;
    865 
    866 if (!PyArg_ParseTuple(_args, ""))
    867         return NULL;
    868 err = _PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
    869 if ( err ) {
    870         PyMac_Error(err);
    871         return NULL;
    872 }
    873 _res = PyString_FromString(strbuf);
    874 return _res;
    875 """
    876 f = ManualGenerator("as_pathname", FSSpec_as_pathname_body)
    877 f.docstring = lambda: "() -> string"
    878 fsspec_methods.append(f)
    879 
    880 FSSpec_as_tuple_body = """
    881 if (!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]);
    885 return _res;
    886 """
    887 f = ManualGenerator("as_tuple", FSSpec_as_tuple_body)
    888 f.docstring = lambda: "() -> (vRefNum, dirID, name)"
    889 fsspec_methods.append(f)
    890 
    891 pathname_body = """
    892 PyObject *obj;
    893 
    894 if (!PyArg_ParseTuple(_args, "O", &obj))
    895         return NULL;
    896 if (PyString_Check(obj)) {
    897         Py_INCREF(obj);
    898         return obj;
    899 }
    900 if (PyUnicode_Check(obj))
    901         return PyUnicode_AsEncodedString(obj, "utf8", "strict");
    902 _res = PyObject_CallMethod(obj, "as_pathname", NULL);
    903 return _res;
    904 """
    905 f = ManualGenerator("pathname", pathname_body)
    906 f.docstring = lambda: "(str|unicode|FSSpec|FSref) -> pathname"
    907 functions.append(f)
    908 
    909 # add the populated lists to the generator groups
    910 # (in a different wordl the scan program would generate this)
    911 for f in functions: module.add(f)
    912 for f in alias_methods: aliasobject.add(f)
    913 for f in fsspec_methods: fsspecobject.add(f)
    914 for f in fsref_methods: fsrefobject.add(f)
    915 
    916 # generate output (open the output file as late as possible)
    917 SetOutputFileName(OUTPUTFILE)
    918 module.generate()
    919