diff options
Diffstat (limited to 'Mac/Modules/file/filesupport.py')
-rw-r--r-- | Mac/Modules/file/filesupport.py | 303 |
1 files changed, 259 insertions, 44 deletions
diff --git a/Mac/Modules/file/filesupport.py b/Mac/Modules/file/filesupport.py index f916c34..c431d42 100644 --- a/Mac/Modules/file/filesupport.py +++ b/Mac/Modules/file/filesupport.py @@ -6,7 +6,7 @@ import string # Declarations that change for each manager -MACHEADERFILE = 'Files.h' # The Apple header file +#MACHEADERFILE = 'Files.h' # The Apple header file MODNAME = '_File' # The name of the module # The following is *usually* unchanged but may still require tuning @@ -16,37 +16,46 @@ OUTPUTFILE = MODNAME + "module.c" # The file generated by this program from macsupport import * -# Create the type objects -#ConstStrFileNameParam = ConstStr255Param -#StrFileName = Str255 -#FolderClass = OSTypeType("FolderClass") -# FolderDesc -#FolderDescFlags = Type("FolderDescFlags", "l") -#FolderLocation = OSTypeType("FolderLocation") -# FolderRouting -#FolderType = OSTypeType("FolderType") -#RoutingFlags = Type("RoutingFlags", "l") - -class UniCharCountBuffer(InputOnlyType): - pass +# Various integers: +SInt64 = Type("SInt64", "L") +UInt64 = Type("UInt64", "L") +FNMessage = Type("FNMessage", "l") +FSAllocationFlags = Type("FSAllocationFlags", "H") +FSCatalogInfoBitmap = Type("FSCatalogInfoBitmap", "l") +FSIteratorFlags = Type("FSIteratorFlags", "l") +FSVolumeRefNum = Type("FSVolumeRefNum", "h") +AliasInfoType = Type("AliasInfoType", "h") -#CatPositionRec +# Various types of strings: +#class UniCharCountBuffer(InputOnlyType): +# pass +class VarReverseInputBufferType(ReverseInputBufferMixin, VarInputBufferType): + pass +FullPathName = VarReverseInputBufferType() +ConstStr31Param = OpaqueArrayType("Str31", "PyMac_BuildStr255", "PyMac_GetStr255") +ConstStr32Param = OpaqueArrayType("Str32", "PyMac_BuildStr255", "PyMac_GetStr255") ConstStr63Param = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255") +Str63 = OpaqueArrayType("Str63", "PyMac_BuildStr255", "PyMac_GetStr255") + +HFSUniStr255 = OpaqueType("HFSUniStr255", "PyMac_BuildHFSUniStr255", "PyMac_GetHFSUniStr255") +UInt8_ptr = InputOnlyType("UInt8 *", "s") + +# Other types: FInfo = OpaqueByValueStructType("FInfo", "PyMac_BuildFInfo", "PyMac_GetFInfo") FInfo_ptr = OpaqueType("FInfo", "PyMac_BuildFInfo", "PyMac_GetFInfo") -FNMessage = Type("FNMessage", "l") -FSAllocationFlags = Type("FSAllocationFlags", "H") +AliasHandle = OpaqueByValueType("AliasHandle", "Alias") +FSSpec = OpaqueType("FSSpec", "FSSpec") +FSSpec_ptr = OpaqueType("FSSpec", "FSSpec") +FSRef = OpaqueType("FSRef", "FSRef") +FSRef_ptr = OpaqueType("FSRef", "FSRef") + +# To be done: +#CatPositionRec #FSCatalogInfo -FSCatalogInfoBitmap = Type("FSCatalogInfoBitmap", "l") #FSForkInfo #FSIterator -FSIteratorFlags = Type("FSIteratorFlags", "l") #FSVolumeInfo -FSVolumeRefNum = Type("FSVolumeRefNum", "h") -HFSUniStr255 = OpaqueType("HFSUniStr255", "PyMac_BuildHFSUniStr255", "PyMac_GetHFSUniStr255") -SInt64 = Type("SInt64", "L") -UInt64 = Type("UInt64", "L") -UInt8_ptr = InputOnlyType("UInt8 *", "s") +#FSSpecArrayPtr includestuff = includestuff + """ #ifdef WITHOUT_FRAMEWORKS @@ -55,6 +64,16 @@ includestuff = includestuff + """ #include <Carbon/Carbon.h> #endif +/* Forward declarations */ +extern PyObject *FSRef_New(FSRef *itself); +extern PyObject *FSSpec_New(FSSpec *itself); +extern PyObject *Alias_New(AliasHandle itself); +extern int FSRef_Convert(PyObject *v, FSRef *p_itself); +extern int FSSpec_Convert(PyObject *v, FSSpec *p_itself); +extern int Alias_Convert(PyObject *v, AliasHandle *p_itself); +static int myPyMac_GetFSSpec(PyObject *v, FSSpec *spec); +static int myPyMac_GetFSRef(PyObject *v, FSRef *fsr); + /* ** Parse/generate objsect */ @@ -65,19 +84,6 @@ PyMac_BuildHFSUniStr255(HFSUniStr255 *itself) return Py_BuildValue("u#", itself->unicode, itself->length); } -#if 0 -static int -PyMac_GetHFSUniStr255(PyObject *v, HFSUniStr255 *itself) -{ - return PyArg_ParseTuple(v, "O&O&O&O&O&", - PyMac_GetFixed, &itself->ascent, - PyMac_GetFixed, &itself->descent, - PyMac_GetFixed, &itself->leading, - PyMac_GetFixed, &itself->widMax, - ResObj_Convert, &itself->wTabHandle); -} -#endif - /* ** Parse/generate objsect */ @@ -103,35 +109,240 @@ PyMac_GetFInfo(PyObject *v, FInfo *itself) PyMac_GetPoint, &itself->fdLocation, &itself->fdFldr); } +""" + +finalstuff = finalstuff + """ +static int +myPyMac_GetFSSpec(PyObject *v, FSSpec *spec) +{ + Str255 path; + short refnum; + long parid; + OSErr err; + FSRef fsr; + + if (FSSpec_Check(v)) { + *spec = ((FSSpecObject *)v)->ob_itself; + return 1; + } + + if (PyArg_Parse(v, "(hlO&)", + &refnum, &parid, PyMac_GetStr255, &path)) { + err = FSMakeFSSpec(refnum, parid, path, spec); + if ( err && err != fnfErr ) { + PyMac_Error(err); + return 0; + } + return 1; + } + PyErr_Clear(); +#if !TARGET_API_MAC_OSX + /* On OS9 we now try a pathname */ + if ( PyString_Check(v) ) { + /* It's a pathname */ + if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) ) + return 0; + refnum = 0; /* XXXX Should get CurWD here?? */ + parid = 0; + err = FSMakeFSSpec(refnum, parid, path, spec); + if ( err && err != fnfErr ) { + PyMac_Error(err); + return 0; + } + return 1; + } + PyErr_Clear(); +#endif + /* Otherwise we try to go via an FSRef. On OSX we go all the way, + ** on OS9 we accept only a real FSRef object + */ +#if TARGET_API_MAX_OSX + if ( myPyMac_GetFSRef(v, &fsr) >= 0 ) { +#else + if ( PyArg_Parse(v, "O&", FSRef_Convert, &fsr) ) { +#endif + err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL); + if (err != noErr) { + PyMac_Error(err); + return 0; + } + return 1; + } + PyErr_SetString(PyExc_TypeError, "FSSpec, FSRef, pathname or (refnum, parid, path) required"); + return 0; +} + +static int +myPyMac_GetFSRef(PyObject *v, FSRef *fsr) +{ + if (FSRef_Check(v)) { + *fsr = ((FSRefObject *)v)->ob_itself; + return 1; + } +#if !TARGET_API_MAC_OSX + /* On OSX we now try a pathname */ + if ( PyString_Check(args) ) { + OSStatus err; + if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) { + PyErr_Mac(ErrorObject, err); + return 0; + } + return 1; + } + /* XXXX Should try unicode here too */ +#endif + /* Otherwise we try to go via an FSSpec */ + if (FSSpec_Check(v)) { + if (FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr)) + return 1; + return 0; + } + PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required"); + return 0; +} """ execfile(string.lower(MODPREFIX) + 'typetest.py') +# Our object types: +class FSSpecDefinition(PEP253Mixin, GlobalObjectDefinition): + def __init__(self, name, prefix, itselftype): + GlobalObjectDefinition.__init__(self, name, prefix, itselftype) + self.argref = "*" # Store FSSpecs, but pass them by address + + def outputCheckNewArg(self): + Output("if (itself == NULL) return PyMac_Error(resNotFound);") + + def output_tp_newBody(self): + Output("PyObject *self;"); + Output() + Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") + Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));", + self.objecttype, self.objecttype) + Output("return self;") + + def output_tp_initBody(self): + Output("PyObject *v;") + Output("char *kw[] = {\"itself\", 0};") + Output() + Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O\", kw, &v))") + Output("return -1;") + Output("if (myPyMac_GetFSSpec(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype) + Output("return -1;") + +class FSRefDefinition(PEP253Mixin, GlobalObjectDefinition): + def __init__(self, name, prefix, itselftype): + GlobalObjectDefinition.__init__(self, name, prefix, itselftype) + self.argref = "*" # Store FSRefs, but pass them by address + + def outputCheckNewArg(self): + Output("if (itself == NULL) return PyMac_Error(resNotFound);") + + def output_tp_newBody(self): + Output("PyObject *self;"); + Output() + Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") + Output("memset(&((%s *)self)->ob_itself, 0, sizeof(%s));", + self.objecttype, self.objecttype) + Output("return self;") + + def output_tp_initBody(self): + Output("PyObject *v;") + Output("char *kw[] = {\"itself\", 0};") + Output() + Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O\", kw, &v))") + Output("return -1;") + Output("if (myPyMac_GetFSRef(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype) + Output("return -1;") + +class AliasDefinition(PEP253Mixin, GlobalObjectDefinition): + # XXXX Should inherit from resource? + + def outputCheckNewArg(self): + Output("if (itself == NULL) return PyMac_Error(resNotFound);") + + def outputStructMembers(self): + GlobalObjectDefinition.outputStructMembers(self) + Output("void (*ob_freeit)(%s ptr);", self.itselftype) + + def outputInitStructMembers(self): + GlobalObjectDefinition.outputInitStructMembers(self) + Output("it->ob_freeit = NULL;") + + def outputCleanupStructMembers(self): + Output("if (self->ob_freeit && self->ob_itself)") + OutLbrace() + Output("self->ob_freeit(self->ob_itself);") + OutRbrace() + Output("self->ob_itself = NULL;") + + def output_tp_newBody(self): + Output("PyObject *self;"); + Output() + Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") + Output("((%s *)self)->ob_itself = NULL;", self.objecttype) + Output("return self;") + + def output_tp_initBody(self): + Output("%s itself;", self.itselftype); + Output("char *kw[] = {\"itself\", 0};") + Output() + Output("if (PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself))", + self.prefix) + OutLbrace() + Output("((%s *)self)->ob_itself = itself;", self.objecttype) + Output("return 0;") + OutRbrace() + Output("return -1;") + +# Alias methods come in two flavors: those with the alias as arg1 and +# those with the alias as arg 2. +class Arg2MethodGenerator(MethodGenerator): + """Similar to MethodGenerator, but has self as second argument""" + + def parseArgumentList(self, args): + args0, arg1, argsrest = args[:1], args[1], args[2:] + t0, n0, m0 = arg1 + args = args0 + argsrest + if m0 != InMode: + raise ValueError, "method's 'self' must be 'InMode'" + self.itself = Variable(t0, "_self->ob_itself", SelfMode) + FunctionGenerator.parseArgumentList(self, args) + self.argumentList.insert(2, self.itself) + # From here on it's basically all boiler plate... # Create the generator groups and link them module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff) +aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle') +fsspecobject = FSSpecDefinition('FSSpec', 'FSSpec', 'FSSpec') +fsrefobject = FSRefDefinition('FSRef', 'FSRef', 'FSRef') + +module.addobject(aliasobject) +module.addobject(fsspecobject) +module.addobject(fsrefobject) + # Create the generator classes used to populate the lists Function = OSErrFunctionGenerator +Method = OSErrMethodGenerator # Create and populate the lists functions = [] +alias_methods = [] +fsref_methods = [] +fsspec_methods = [] execfile(INPUTFILE) # Manual generators: FSRefMakePath_body = """ OSStatus _err; -FSRef ref; #define MAXPATHNAME 1024 UInt8 path[MAXPATHNAME]; UInt32 maxPathSize = MAXPATHNAME; -if (!PyArg_ParseTuple(_args, "O&", - PyMac_GetFSRef, &ref)) - return NULL; -_err = FSRefMakePath(&ref, +_err = FSRefMakePath(&_self->ob_itself, path, maxPathSize); if (_err != noErr) return PyMac_Error(_err); @@ -139,12 +350,16 @@ _res = Py_BuildValue("s", path); return _res; """ f = ManualGenerator("FSRefMakePath", FSRefMakePath_body) -f.docstring = lambda: "(FSRef) -> string" -functions.append(f) +f.docstring = lambda: "() -> string" +fsref_methods.append(f) + # add the populated lists to the generator groups # (in a different wordl the scan program would generate this) for f in functions: module.add(f) +for f in alias_methods: aliasobject.add(f) +for f in fsspec_methods: fsspecobject.add(f) +for f in fsref_methods: fsrefobject.add(f) # generate output (open the output file as late as possible) SetOutputFileName(OUTPUTFILE) |