/*********************************************************** Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ #include "Python.h" #include "macglue.h" #include "pymactoolbox.h" #ifdef WITHOUT_FRAMEWORKS #include #include #include #include #include #include #else #include #endif #include "getapplbycreator.h" /* ** The next define uses PBGetCatInfoSync for GetFInfo, allowing you ** to get FInfo for folders. This works on OSX, but it may result ** in problems on OS9, hence the define (for the time being). */ #define USE_CATINFO_FOR_FINFO #ifndef TARGET_API_MAC_OSX #include "pythonresources.h" extern PyMac_PrefRecord PyMac_options; #endif #ifdef USE_TOOLBOX_OBJECT_GLUE extern int _PyMac_GetFSSpec(PyObject *, FSSpec *); extern PyObject *_PyMac_BuildFSSpec(FSSpec *); extern int _PyMac_GetFSRef(PyObject *, FSRef *); extern PyObject *_PyMac_BuildFSRef(FSRef *); #define PyMac_GetFSSpec _PyMac_GetFSSpec #define PyMac_BuildFSSpec _PyMac_BuildFSSpec #define PyMac_GetFSRef _PyMac_GetFSRef #define PyMac_BuildFSRef _PyMac_BuildFSRef #endif static PyObject *ErrorObject; #ifdef TARGET_API_MAC_OSX #define PATHNAMELEN 1024 #else #define PATHNAMELEN 256 #endif /* ----------------------------------------------------- */ /* Declarations for objects of type Alias */ typedef struct { PyObject_HEAD AliasHandle alias; } mfsaobject; static PyTypeObject Mfsatype; #define is_mfsaobject(v) ((v)->ob_type == &Mfsatype) /* ---------------------------------------------------------------- */ /* Declarations for objects of type FSSpec */ typedef struct { PyObject_HEAD FSSpec fsspec; } mfssobject; static PyTypeObject Mfsstype; #define is_mfssobject(v) ((v)->ob_type == &Mfsstype) /* ---------------------------------------------------------------- */ /* Declarations for objects of type FSRef */ typedef struct { PyObject_HEAD FSRef fsref; } mfsrobject; static PyTypeObject Mfsrtype; #define is_mfsrobject(v) ((v)->ob_type == &Mfsrtype) /* ---------------------------------------------------------------- */ /* Declarations for objects of type FInfo */ typedef struct { PyObject_HEAD FInfo finfo; } mfsiobject; static PyTypeObject Mfsitype; #define is_mfsiobject(v) ((v)->ob_type == &Mfsitype) static mfssobject *newmfssobject(FSSpec *fss); /* Forward */ static mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */ /* ---------------------------------------------------------------- */ static PyObject * mfsa_Resolve(mfsaobject *self, PyObject *args) { FSSpec from, *fromp, result; Boolean changed; OSErr err; from.name[0] = 0; if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &from)) return NULL; if (from.name[0] ) fromp = &from; else fromp = NULL; err = ResolveAlias(fromp, self->alias, &result, &changed); if ( err && err != fnfErr ) { PyErr_Mac(ErrorObject, err); return NULL; } return Py_BuildValue("(Oi)", newmfssobject(&result), (int)changed); } static PyObject * mfsa_GetInfo(mfsaobject *self, PyObject *args) { Str63 value; int i; OSErr err; if (!PyArg_ParseTuple(args, "i", &i)) return NULL; err = GetAliasInfo(self->alias, (AliasInfoType)i, value); if ( err ) { PyErr_Mac(ErrorObject, err); return 0; } return PyString_FromStringAndSize((char *)&value[1], value[0]); } static PyObject * mfsa_Update(mfsaobject *self, PyObject *args) { FSSpec target, fromfile, *fromfilep; OSErr err; Boolean changed; fromfile.name[0] = 0; if (!PyArg_ParseTuple(args, "O&|O&", PyMac_GetFSSpec, &target, PyMac_GetFSSpec, &fromfile)) return NULL; if ( fromfile.name[0] ) fromfilep = &fromfile; else fromfilep = NULL; err = UpdateAlias(fromfilep, &target, self->alias, &changed); if ( err ) { PyErr_Mac(ErrorObject, err); return 0; } return Py_BuildValue("i", (int)changed); } static struct PyMethodDef mfsa_methods[] = { {"Resolve", (PyCFunction)mfsa_Resolve, 1}, {"GetInfo", (PyCFunction)mfsa_GetInfo, 1}, {"Update", (PyCFunction)mfsa_Update, 1}, {NULL, NULL} /* sentinel */ }; /* ---------- */ static PyObject * mfsa_getattr(mfsaobject *self, char *name) { if ( strcmp(name, "data") == 0 ) { int size; PyObject *rv; size = GetHandleSize((Handle)self->alias); HLock((Handle)self->alias); rv = PyString_FromStringAndSize(*(Handle)self->alias, size); HUnlock((Handle)self->alias); return rv; } return Py_FindMethod(mfsa_methods, (PyObject *)self, name); } static mfsaobject * newmfsaobject(AliasHandle alias) { mfsaobject *self; self = PyObject_NEW(mfsaobject, &Mfsatype); if (self == NULL) return NULL; self->alias = alias; return self; } static void mfsa_dealloc(mfsaobject *self) { #if 0 if ( self->alias ) { should we do something here? } #endif PyObject_DEL(self); } statichere PyTypeObject Mfsatype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "macfs.Alias", /*tp_name*/ sizeof(mfsaobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)mfsa_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)mfsa_getattr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ }; /* End of code for Alias objects */ /* -------------------------------------------------------- */ /* ---------------------------------------------------------------- */ static struct PyMethodDef mfsi_methods[] = { {NULL, NULL} /* sentinel */ }; /* ---------- */ static mfsiobject * newmfsiobject(void) { mfsiobject *self; self = PyObject_NEW(mfsiobject, &Mfsitype); if (self == NULL) return NULL; memset((char *)&self->finfo, '\0', sizeof(self->finfo)); return self; } static void mfsi_dealloc(mfsiobject *self) { PyObject_DEL(self); } static PyObject * mfsi_getattr(mfsiobject *self, char *name) { if ( strcmp(name, "Type") == 0 ) return PyMac_BuildOSType(self->finfo.fdType); else if ( strcmp(name, "Creator") == 0 ) return PyMac_BuildOSType(self->finfo.fdCreator); else if ( strcmp(name, "Flags") == 0 ) return Py_BuildValue("i", (int)self->finfo.fdFlags); else if ( strcmp(name, "Location") == 0 ) return PyMac_BuildPoint(self->finfo.fdLocation); else if ( strcmp(name, "Fldr") == 0 ) return Py_BuildValue("i", (int)self->finfo.fdFldr); else if ( strcmp(name, "__members__") == 0 ) return Py_BuildValue("[sssss]", "Type", "Creator", "Flags", "Location", "Fldr"); else return Py_FindMethod(mfsi_methods, (PyObject *)self, name); } static int mfsi_setattr(mfsiobject *self, char *name, PyObject *v) { int rv; int i; if ( v == NULL ) { PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute"); return -1; } if ( strcmp(name, "Type") == 0 ) rv = PyMac_GetOSType(v, &self->finfo.fdType); else if ( strcmp(name, "Creator") == 0 ) rv = PyMac_GetOSType(v, &self->finfo.fdCreator); else if ( strcmp(name, "Flags") == 0 ) { rv = PyArg_Parse(v, "i", &i); self->finfo.fdFlags = (short)i; } else if ( strcmp(name, "Location") == 0 ) rv = PyMac_GetPoint(v, &self->finfo.fdLocation); else if ( strcmp(name, "Fldr") == 0 ) { rv = PyArg_Parse(v, "i", &i); self->finfo.fdFldr = (short)i; } else { PyErr_SetString(PyExc_AttributeError, "No such attribute"); return -1; } if (rv) return 0; return -1; } static PyTypeObject Mfsitype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "macfs.FInfo", /*tp_name*/ sizeof(mfsiobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)mfsi_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)mfsi_getattr, /*tp_getattr*/ (setattrfunc)mfsi_setattr, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ }; /* End of code for FInfo object objects */ /* -------------------------------------------------------- */ /* ** Helper routines for the FSRef and FSSpec creators in macglue.c ** They return an FSSpec/FSRef if the Python object encapsulating ** either is passed. They return a boolean success indicator. ** Note that they do not set an exception on failure, they're only ** helper routines. */ static int _mfs_GetFSSpecFromFSSpec(PyObject *self, FSSpec *fssp) { if ( is_mfssobject(self) ) { *fssp = ((mfssobject *)self)->fsspec; return 1; } return 0; } /* Return an FSSpec if this is an FSref */ static int _mfs_GetFSSpecFromFSRef(PyObject *self, FSSpec *fssp) { #if !TARGET_API_MAC_OS8 static FSRef *fsrp; if ( is_mfsrobject(self) ) { fsrp = &((mfsrobject *)self)->fsref; if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr ) return 1; } #endif return 0; } /* Return an FSRef if this is an FSRef */ static int _mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp) { #if !TARGET_API_MAC_OS8 if ( is_mfsrobject(self) ) { *fsrp = ((mfsrobject *)self)->fsref; return 1; } #endif return 0; } /* Return an FSRef if this is an FSSpec */ static int _mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp) { #if !TARGET_API_MAC_OS8 if ( is_mfssobject(self) ) { if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr ) return 1; } #endif return 0; } /* ** Two generally useful routines */ static OSErr PyMac_GetFileDates(FSSpec *fss, unsigned long *crdat, unsigned long *mddat, unsigned long *bkdat) { CInfoPBRec pb; OSErr error; pb.dirInfo.ioNamePtr = fss->name; pb.dirInfo.ioFDirIndex = 0; pb.dirInfo.ioVRefNum = fss->vRefNum; pb.dirInfo.ioDrDirID = fss->parID; error = PBGetCatInfoSync(&pb); if ( error ) return error; *crdat = pb.hFileInfo.ioFlCrDat; *mddat = pb.hFileInfo.ioFlMdDat; *bkdat = pb.hFileInfo.ioFlBkDat; return 0; } static OSErr PyMac_SetFileDates(FSSpec *fss, unsigned long crdat, unsigned long mddat, unsigned long bkdat) { CInfoPBRec pb; OSErr error; pb.dirInfo.ioNamePtr = fss->name; pb.dirInfo.ioFDirIndex = 0; pb.dirInfo.ioVRefNum = fss->vRefNum; pb.dirInfo.ioDrDirID = fss->parID; error = PBGetCatInfoSync(&pb); if ( error ) return error; pb.dirInfo.ioNamePtr = fss->name; pb.dirInfo.ioFDirIndex = 0; pb.dirInfo.ioVRefNum = fss->vRefNum; pb.dirInfo.ioDrDirID = fss->parID; pb.hFileInfo.ioFlCrDat = crdat; pb.hFileInfo.ioFlMdDat = mddat; pb.hFileInfo.ioFlBkDat = bkdat; error = PBSetCatInfoSync(&pb); return error; } static PyObject * mfss_as_pathname(mfssobject *self, PyObject *args) { char strbuf[PATHNAMELEN]; OSErr err; if (!PyArg_ParseTuple(args, "")) return NULL; err = PyMac_GetFullPathname(&self->fsspec, strbuf, PATHNAMELEN); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return PyString_FromString(strbuf); } static PyObject * mfss_as_tuple(mfssobject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; return Py_BuildValue("(iis#)", self->fsspec.vRefNum, self->fsspec.parID, &self->fsspec.name[1], self->fsspec.name[0]); } static PyObject * mfss_NewAlias(mfssobject *self, PyObject *args) { FSSpec src, *srcp; OSErr err; AliasHandle alias; src.name[0] = 0; if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &src)) return NULL; if ( src.name[0] ) srcp = &src; else srcp = NULL; err = NewAlias(srcp, &self->fsspec, &alias); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return (PyObject *)newmfsaobject(alias); } static PyObject * mfss_NewAliasMinimal(mfssobject *self, PyObject *args) { OSErr err; AliasHandle alias; if (!PyArg_ParseTuple(args, "")) return NULL; err = NewAliasMinimal(&self->fsspec, &alias); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return (PyObject *)newmfsaobject(alias); } static PyObject * mfss_FSpMakeFSRef(mfssobject *self, PyObject *args) { #if TARGET_API_MAC_OS8 PyErr_SetString(PyExc_NotImplementedError, "FSRef objects not supported on this platform"); return 0; #else OSErr err; FSRef fsref; if (!PyArg_ParseTuple(args, "")) return NULL; err = FSpMakeFSRef(&self->fsspec, &fsref); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return (PyObject *)newmfsrobject(&fsref); #endif } /* XXXX These routines should be replaced by a wrapper to the *FInfo routines */ static PyObject * mfss_GetCreatorType(mfssobject *self, PyObject *args) { OSErr err; FInfo info; if (!PyArg_ParseTuple(args, "")) return NULL; err = FSpGetFInfo(&self->fsspec, &info); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return Py_BuildValue("(O&O&)", PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType); } static PyObject * mfss_SetCreatorType(mfssobject *self, PyObject *args) { OSErr err; OSType creator, type; FInfo info; if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) return NULL; err = FSpGetFInfo(&self->fsspec, &info); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } info.fdType = type; info.fdCreator = creator; err = FSpSetFInfo(&self->fsspec, &info); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * mfss_GetFInfo(mfssobject *self, PyObject *args) { OSErr err; mfsiobject *fip; CInfoPBRec pb; FSSpec* fss = &self->fsspec; if (!PyArg_ParseTuple(args, "")) return NULL; if ( (fip=newmfsiobject()) == NULL ) return NULL; #ifdef USE_CATINFO_FOR_FINFO pb.dirInfo.ioNamePtr = fss->name; pb.dirInfo.ioFDirIndex = 0; pb.dirInfo.ioVRefNum = fss->vRefNum; pb.dirInfo.ioDrDirID = fss->parID; err = PBGetCatInfoSync(&pb); if ( err ) { PyErr_Mac(ErrorObject, err); Py_DECREF(fip); return NULL; } memcpy(&fip->finfo, &pb.hFileInfo.ioFlFndrInfo, sizeof(FileInfo)); #else err = FSpGetFInfo(&self->fsspec, &fip->finfo); if ( err ) { PyErr_Mac(ErrorObject, err); Py_DECREF(fip); return NULL; } #endif return (PyObject *)fip; } static PyObject * mfss_SetFInfo(mfssobject *self, PyObject *args) { OSErr err; mfsiobject *fip; if (!PyArg_ParseTuple(args, "O!", &Mfsitype, &fip)) return NULL; err = FSpSetFInfo(&self->fsspec, &fip->finfo); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * mfss_GetDates(mfssobject *self, PyObject *args) { OSErr err; unsigned long crdat, mddat, bkdat; if (!PyArg_ParseTuple(args, "")) return NULL; err = PyMac_GetFileDates(&self->fsspec, &crdat, &mddat, &bkdat); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return Py_BuildValue("ddd", (double)crdat, (double)mddat, (double)bkdat); } static PyObject * mfss_SetDates(mfssobject *self, PyObject *args) { OSErr err; double crdat, mddat, bkdat; if (!PyArg_ParseTuple(args, "ddd", &crdat, &mddat, &bkdat)) return NULL; err = PyMac_SetFileDates(&self->fsspec, (unsigned long)crdat, (unsigned long)mddat, (unsigned long)bkdat); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } Py_INCREF(Py_None); return Py_None; } static struct PyMethodDef mfss_methods[] = { {"as_pathname", (PyCFunction)mfss_as_pathname, 1}, {"as_tuple", (PyCFunction)mfss_as_tuple, 1}, {"as_fsref", (PyCFunction)mfss_FSpMakeFSRef, 1}, {"FSpMakeFSRef", (PyCFunction)mfss_FSpMakeFSRef, 1}, {"NewAlias", (PyCFunction)mfss_NewAlias, 1}, {"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1}, {"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1}, {"SetCreatorType", (PyCFunction)mfss_SetCreatorType, 1}, {"GetFInfo", (PyCFunction)mfss_GetFInfo, 1}, {"SetFInfo", (PyCFunction)mfss_SetFInfo, 1}, {"GetDates", (PyCFunction)mfss_GetDates, 1}, {"SetDates", (PyCFunction)mfss_SetDates, 1}, {NULL, NULL} /* sentinel */ }; /* ---------- */ static PyObject * mfss_getattr(mfssobject *self, char *name) { if ( strcmp(name, "data") == 0) return PyString_FromStringAndSize((char *)&self->fsspec, sizeof(FSSpec)); return Py_FindMethod(mfss_methods, (PyObject *)self, name); } mfssobject * newmfssobject(FSSpec *fss) { mfssobject *self; self = PyObject_NEW(mfssobject, &Mfsstype); if (self == NULL) return NULL; self->fsspec = *fss; return self; } static void mfss_dealloc(mfssobject *self) { PyObject_DEL(self); } static PyObject * mfss_repr(mfssobject *self) { char buf[512]; PyOS_snprintf(buf, sizeof(buf), "FSSpec((%d, %ld, '%.*s'))", self->fsspec.vRefNum, self->fsspec.parID, self->fsspec.name[0], self->fsspec.name+1); return PyString_FromString(buf); } static int mfss_compare(mfssobject *v, mfssobject *w) { int minlen; int res; if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1; if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1; if ( v->fsspec.parID < w->fsspec.parID ) return -1; if ( v->fsspec.parID > w->fsspec.parID ) return 1; minlen = v->fsspec.name[0]; if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0]; res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen); if ( res ) return res; if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1; if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1; return res; } statichere PyTypeObject Mfsstype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "macfs.FSSpec", /*tp_name*/ sizeof(mfssobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)mfss_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)mfss_getattr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ (cmpfunc)mfss_compare, /*tp_compare*/ (reprfunc)mfss_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ }; /* End of code for FSSpec objects */ /* -------------------------------------------------------- */ #if !TARGET_API_MAC_OS8 static PyObject * mfsr_as_fsspec(mfsrobject *self, PyObject *args) { OSErr err; FSSpec fss; if (!PyArg_ParseTuple(args, "")) return NULL; err = FSGetCatalogInfo(&self->fsref, kFSCatInfoNone, NULL, NULL, &fss, NULL); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } Py_INCREF(Py_None); return (PyObject *)newmfssobject(&fss); } static PyObject * mfsr_as_pathname(mfsrobject *self, PyObject *args) { unsigned char strbuf[PATHNAMELEN]; OSStatus err; if (!PyArg_ParseTuple(args, "")) return NULL; err = FSRefMakePath(&self->fsref, strbuf, PATHNAMELEN); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return PyString_FromString((char *)strbuf); } static struct PyMethodDef mfsr_methods[] = { {"as_fsspec", (PyCFunction)mfsr_as_fsspec, 1}, {"as_pathname", (PyCFunction)mfsr_as_pathname, 1}, #if 0 {"as_tuple", (PyCFunction)mfss_as_tuple, 1}, {"NewAlias", (PyCFunction)mfss_NewAlias, 1}, {"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1}, {"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1}, {"SetCreatorType", (PyCFunction)mfss_SetCreatorType, 1}, {"GetFInfo", (PyCFunction)mfss_GetFInfo, 1}, {"SetFInfo", (PyCFunction)mfss_SetFInfo, 1}, {"GetDates", (PyCFunction)mfss_GetDates, 1}, {"SetDates", (PyCFunction)mfss_SetDates, 1}, #endif {NULL, NULL} /* sentinel */ }; /* ---------- */ static PyObject * mfsr_getattr(mfsrobject *self, char *name) { if ( strcmp(name, "data") == 0) return PyString_FromStringAndSize((char *)&self->fsref, sizeof(FSRef)); return Py_FindMethod(mfsr_methods, (PyObject *)self, name); } mfsrobject * newmfsrobject(FSRef *fsr) { mfsrobject *self; self = PyObject_NEW(mfsrobject, &Mfsrtype); if (self == NULL) return NULL; self->fsref = *fsr; return self; } static int mfsr_compare(mfsrobject *v, mfsrobject *w) { OSErr err; if ( v == w ) return 0; err = FSCompareFSRefs(&v->fsref, &w->fsref); if ( err == 0 ) return 0; if (v < w ) return -1; return 1; } static void mfsr_dealloc(mfsrobject *self) { PyObject_DEL(self); } statichere PyTypeObject Mfsrtype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "macfs.FSRef", /*tp_name*/ sizeof(mfsrobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)mfsr_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)mfsr_getattr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ (cmpfunc)mfsr_compare, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ }; /* End of code for FSRef objects */ #endif /* !TARGET_API_MAC_OS8 */ /* -------------------------------------------------------- */ static PyObject * mfs_ResolveAliasFile(PyObject *self, PyObject *args) { FSSpec fss; Boolean chain = 1, isfolder, wasaliased; OSErr err; if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &chain)) return NULL; err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return Py_BuildValue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased); } #if !TARGET_API_MAC_CARBON static PyObject * mfs_StandardGetFile(PyObject *self, PyObject *args) { SFTypeList list; short numtypes; StandardFileReply reply; list[0] = list[1] = list[2] = list[3] = 0; numtypes = 0; if (!PyArg_ParseTuple(args, "|O&O&O&O&", PyMac_GetOSType, &list[0], PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2], PyMac_GetOSType, &list[3]) ) return NULL; while ( numtypes < 4 && list[numtypes] ) { numtypes++; } if ( numtypes == 0 ) numtypes = -1; StandardGetFile((FileFilterUPP)0, numtypes, list, &reply); return Py_BuildValue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood); } static PyObject * mfs_PromptGetFile(PyObject *self, PyObject *args) { SFTypeList list; short numtypes; StandardFileReply reply; char *prompt = NULL; list[0] = list[1] = list[2] = list[3] = 0; numtypes = 0; if (!PyArg_ParseTuple(args, "s|O&O&O&O&", &prompt, PyMac_GetOSType, &list[0], PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2], PyMac_GetOSType, &list[3]) ) return NULL; while ( numtypes < 4 && list[numtypes] ) { numtypes++; } if ( numtypes == 0 ) numtypes = -1; PyMac_PromptGetFile(numtypes, list, &reply, prompt); return Py_BuildValue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood); } static PyObject * mfs_StandardPutFile(PyObject *self, PyObject *args) { Str255 prompt, dft; StandardFileReply reply; dft[0] = 0; if (!PyArg_ParseTuple(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) ) return NULL; StandardPutFile(prompt, dft, &reply); return Py_BuildValue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood); } /* ** Set initial directory for file dialogs */ static PyObject * mfs_SetFolder(PyObject *self, PyObject *args) { FSSpec spec; FSSpec ospec; short orefnum; long oparid; /* Get old values */ orefnum = -LMGetSFSaveDisk(); oparid = LMGetCurDirStore(); (void)FSMakeFSSpec(orefnum, oparid, "\pplaceholder", &ospec); /* Go to working directory by default */ (void)FSMakeFSSpec(0, 0, "\p:placeholder", &spec); if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &spec)) return NULL; /* Set standard-file working directory */ LMSetSFSaveDisk(-spec.vRefNum); LMSetCurDirStore(spec.parID); return (PyObject *)newmfssobject(&ospec); } #endif static PyObject * mfs_FSSpec(PyObject *self, PyObject *args) { FSSpec fss; if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss)) return NULL; return (PyObject *)newmfssobject(&fss); } static PyObject * mfs_FSRef(PyObject *self, PyObject *args) { #if TARGET_API_MAC_OS8 PyErr_SetString(PyExc_NotImplementedError, "FSRef objects not supported on this platform"); return 0; #else FSRef fsr; if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr)) return NULL; return (PyObject *)newmfsrobject(&fsr); #endif } static PyObject * mfs_RawFSSpec(PyObject *self, PyObject *args) { FSSpec *fssp; int size; if (!PyArg_ParseTuple(args, "s#", &fssp, &size)) return NULL; if ( size != sizeof(FSSpec) ) { PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record"); return NULL; } return (PyObject *)newmfssobject(fssp); } static PyObject * mfs_RawAlias(PyObject *self, PyObject *args) { char *dataptr; Handle h; int size; if (!PyArg_ParseTuple(args, "s#", &dataptr, &size)) return NULL; h = NewHandle(size); if ( h == NULL ) { PyErr_NoMemory(); return NULL; } HLock(h); memcpy((char *)*h, dataptr, size); HUnlock(h); return (PyObject *)newmfsaobject((AliasHandle)h); } #if !TARGET_API_MAC_CARBON static PyObject * mfs_GetDirectory(PyObject *self, PyObject *args) { FSSpec fsdir; int ok; char *prompt = NULL; if (!PyArg_ParseTuple(args, "|s", &prompt) ) return NULL; ok = PyMac_GetDirectory(&fsdir, prompt); return Py_BuildValue("(Oi)", newmfssobject(&fsdir), ok); } #endif static PyObject * mfs_FindFolder(PyObject *self, PyObject *args) { OSErr err; short where; OSType which; int create; short refnum; long dirid; if (!PyArg_ParseTuple(args, "hO&i", &where, PyMac_GetOSType, &which, &create) ) return NULL; err = FindFolder(where, which, (Boolean)create, &refnum, &dirid); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return Py_BuildValue("(ii)", refnum, dirid); } static PyObject * mfs_FindApplication(PyObject *self, PyObject *args) { OSErr err; OSType which; FSSpec fss; if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &which) ) return NULL; err = FindApplicationFromCreator(which, &fss); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return (PyObject *)newmfssobject(&fss); } static PyObject * mfs_FInfo(PyObject *self, PyObject *args) { return (PyObject *)newmfsiobject(); } static PyObject * mfs_NewAliasMinimalFromFullPath(PyObject *self, PyObject *args) { OSErr err; char *fullpath; int fullpathlen; AliasHandle alias; Str32 zonename; Str31 servername; if (!PyArg_ParseTuple(args, "s#", &fullpath, &fullpathlen) ) return NULL; zonename[0] = 0; servername[0] = 0; err = NewAliasMinimalFromFullPath(fullpathlen, (Ptr)fullpath, zonename, servername, &alias); if ( err ) { PyErr_Mac(ErrorObject, err); return NULL; } return (PyObject *)newmfsaobject(alias); } /* List of methods defined in the module */ static struct PyMethodDef mfs_methods[] = { {"ResolveAliasFile", mfs_ResolveAliasFile, 1}, #if !TARGET_API_MAC_CARBON {"StandardGetFile", mfs_StandardGetFile, 1}, {"PromptGetFile", mfs_PromptGetFile, 1}, {"StandardPutFile", mfs_StandardPutFile, 1}, {"GetDirectory", mfs_GetDirectory, 1}, {"SetFolder", mfs_SetFolder, 1}, #endif {"FSSpec", mfs_FSSpec, 1}, {"FSRef", mfs_FSRef, 1}, {"RawFSSpec", mfs_RawFSSpec, 1}, {"RawAlias", mfs_RawAlias, 1}, {"FindFolder", mfs_FindFolder, 1}, {"FindApplication", mfs_FindApplication, 1}, {"FInfo", mfs_FInfo, 1}, {"NewAliasMinimalFromFullPath", mfs_NewAliasMinimalFromFullPath, 1}, {NULL, NULL} /* sentinel */ }; /* ** Convert a Python object to an FSSpec. ** The object may either be a full pathname, an FSSpec, an FSRef or a triple ** (vrefnum, dirid, path). */ int PyMac_GetFSRef(PyObject *v, FSRef *fsr) { #if TARGET_API_MAC_OS8 PyErr_SetString(PyExc_TypeError, "FSRef objects not supported on this platform"); return 0; #else /* If it's an FSRef we're also okay. */ if (_mfs_GetFSRefFromFSRef(v, fsr)) return 1; /* first check whether it already is an FSSpec */ if ( _mfs_GetFSRefFromFSSpec(v, fsr) ) return 1; if ( PyString_Check(v) ) { #if TARGET_API_MAC_OSX OSStatus err; if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) { PyErr_Mac(ErrorObject, err); return 0; } return 1; #else PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform"); return 0; #endif } PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname"); return 0; #endif } /* Convert FSSpec to PyObject */ PyObject *PyMac_BuildFSRef(FSRef *v) { #if TARGET_API_MAC_OS8 return NULL; #else return (PyObject *)newmfsrobject(v); #endif } /* ** Convert a Python object to an FSRef. ** The object may either be a full pathname (OSX only), an FSSpec or an FSRef. */ int PyMac_GetFSSpec(PyObject *v, FSSpec *fs) { Str255 path; short refnum; long parid; OSErr err; /* first check whether it already is an FSSpec */ if ( _mfs_GetFSSpecFromFSSpec(v, fs) ) return 1; /* If it's an FSRef we're also okay. */ if (_mfs_GetFSSpecFromFSRef(v, fs)) return 1; if ( PyString_Check(v) ) { #if TARGET_API_MAC_OSX FSRef fsr; if ( !PyMac_GetFSRef(v, &fsr) ) return 0; if ( FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, fs, NULL) == noErr ) return 1; return 0; #else /* It's a pathname */ if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) ) return 0; refnum = 0; /* XXXX Should get CurWD here?? */ parid = 0; #endif } else { if( !PyArg_Parse(v, "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)", &refnum, &parid, PyMac_GetStr255, &path)) { return 0; } } err = FSMakeFSSpec(refnum, parid, path, fs); if ( err && err != fnfErr ) { PyMac_Error(err); return 0; } return 1; } /* Convert FSSpec to PyObject */ PyObject *PyMac_BuildFSSpec(FSSpec *v) { return (PyObject *)newmfssobject(v); } /* ** Import the macfsn module, which will override the Standard File ** calls in the macfs builtin module by Navigation Services versions, ** if available on this machine. */ static void PyMac_InstallNavServicesForSF(void) { #ifndef TARGET_API_MAC_OSX if ( !PyMac_options.nonavservice ) { #endif PyObject *m = PyImport_ImportModule("macfsn"); if ( m == NULL ) { PySys_WriteStderr("'import macfsn' failed; "); if (Py_VerboseFlag) { PySys_WriteStderr("traceback:\n"); PyErr_Print(); } else { PySys_WriteStderr("use -v for traceback\n"); } PyErr_Clear(); } #ifndef TARGET_API_MAC_OSX } #endif } /* Initialization function for the module (*must* be called initmacfs) */ void initmacfs(void) { PyObject *m, *d; PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec); PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef); PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec); PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef); /* Create the module and add the functions */ m = Py_InitModule("macfs", mfs_methods); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); ErrorObject = PyMac_GetOSErrException(); PyDict_SetItemString(d, "error", ErrorObject); Mfsatype.ob_type = &PyType_Type; Py_INCREF(&Mfsatype); PyDict_SetItemString(d, "AliasType", (PyObject *)&Mfsatype); Mfsstype.ob_type = &PyType_Type; Py_INCREF(&Mfsstype); PyDict_SetItemString(d, "FSSpecType", (PyObject *)&Mfsstype); Mfsitype.ob_type = &PyType_Type; Py_INCREF(&Mfsitype); PyDict_SetItemString(d, "FInfoType", (PyObject *)&Mfsitype); PyMac_InstallNavServicesForSF(); }