]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Implemented minimal FSRef support, plus conversion between FSRefs, FSSpecs and pathna...
authorJack Jansen <jack.jansen@cwi.nl>
Sun, 8 Jul 2001 22:07:23 +0000 (22:07 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Sun, 8 Jul 2001 22:07:23 +0000 (22:07 +0000)
PyMac_GetFSSpec and PyMac_BuildFSSpec have moved to macfsmodule from macglue.

These mods are untested on OSX.

Mac/Include/macglue.h
Mac/Modules/macfsmodule.c
Mac/Python/macglue.c

index 9b55a4f60665e35bf40fa51188413e8b3f9ca1a9..e0c0ff52f06d108580002666e13008af4da38e3c 100644 (file)
@@ -106,9 +106,6 @@ int PyMac_GetStr255(PyObject *, Str255);    /* argument parser for Str255 */
 PyObject *PyMac_BuildStr255(Str255);           /* Convert Str255 to PyObject */
 PyObject *PyMac_BuildOptStr255(Str255);                /* Convert Str255 to PyObject, NULL to None */
 
-int PyMac_GetFSSpec(PyObject *, FSSpec *);     /* argument parser for FSSpec */
-PyObject *PyMac_BuildFSSpec(FSSpec *);         /* Convert FSSpec to PyObject */
-
 int PyMac_GetRect(PyObject *, Rect *);         /* argument parser for Rect */
 PyObject *PyMac_BuildRect(Rect *);             /* Convert Rect to PyObject */
 
@@ -129,6 +126,14 @@ void PyMac_Initialize(void);                       /* Initialize function for embedding Python */
 short PyMac_OpenPrefFile(void);                        /* From macgetpath.c, open and return preference file */
 #endif
 
+/* from macfsmodule.c: */
+int PyMac_GetFSSpec(PyObject *, FSSpec *);     /* argument parser for FSSpec */
+PyObject *PyMac_BuildFSSpec(FSSpec *);         /* Convert FSSpec to PyObject */
+
+int PyMac_GetFSRef(PyObject *, FSRef *);       /* argument parser for FSRef */
+PyObject *PyMac_BuildFSRef(FSRef *);           /* Convert FSRef to PyObject */
+
+
 /* From macfiletype.c: */
 
 long PyMac_getfiletype(char *);                        /* Get file type */
index c16bed0029af203e3859621190c57df6240d9497..5e34a648fc5e1f08ae59de8267876ed62b2f6c29 100644 (file)
@@ -38,8 +38,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #include "getapplbycreator.h"
 
-/* Should this be in macglue.h? */
-extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *);
 
 static PyObject *ErrorObject;
 
@@ -67,6 +65,18 @@ staticforward PyTypeObject Mfsstype;
 
 #define is_mfssobject(v)               ((v)->ob_type == &Mfsstype)
 
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type FSRef */
+
+typedef struct {
+       PyObject_HEAD
+       FSRef fsref;
+} mfsrobject;
+
+staticforward PyTypeObject Mfsrtype;
+
+#define is_mfsrobject(v)               ((v)->ob_type == &Mfsrtype)
+
 
 /* ---------------------------------------------------------------- */
 /* Declarations for objects of type FInfo */
@@ -81,7 +91,8 @@ staticforward PyTypeObject Mfsitype;
 #define is_mfsiobject(v)               ((v)->ob_type == &Mfsitype)
 
 
-mfssobject *newmfssobject(FSSpec *fss); /* Forward */
+staticforward mfssobject *newmfssobject(FSSpec *fss); /* Forward */
+staticforward mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */
 
 /* ---------------------------------------------------------------- */
 
@@ -336,15 +347,56 @@ static PyTypeObject Mfsitype = {
 
 
 /*
-** Helper routine for other modules: return an FSSpec * if the
-** object is a python fsspec object, else NULL
+** 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.
 */
-FSSpec *
-mfs_GetFSSpecFSSpec(PyObject *self)
+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 ( is_mfssobject(self) )
-               return &((mfssobject *)self)->fsspec;
-       return NULL;
+       static FSRef *fsrp;
+       
+       if ( is_mfsrobject(self) ) {
+               fsrp = &((mfsrobject *)self)->fsref;
+               if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr )
+                       return 1;
+       }
+       return 0;
+}
+
+/* Return an FSRef if this is an FSRef */
+static int
+_mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp)
+{
+       if ( is_mfsrobject(self) ) {
+               *fsrp = ((mfsrobject *)self)->fsref;
+               return 1;
+       }
+       return 0;
+}
+
+/* Return an FSRef if this is an FSSpec */
+static int
+_mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp)
+{
+       if ( is_mfssobject(self) ) {
+               if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr )
+                       return 1;
+       }
+       return 0;
 }
 
 /*
@@ -467,6 +519,24 @@ mfss_NewAliasMinimal(self, args)
        return (PyObject *)newmfsaobject(alias);
 }
 
+static PyObject *
+mfss_FSpMakeFSRef(self, args)
+       mfssobject *self;
+       PyObject *args;
+{
+       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);
+}
+
 /* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
 static PyObject *
 mfss_GetCreatorType(self, args)
@@ -596,6 +666,8 @@ mfss_SetDates(self, args)
 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},
@@ -695,6 +767,112 @@ statichere PyTypeObject Mfsstype = {
 /* End of code for FSSpec objects */
 /* -------------------------------------------------------- */
 
+static PyObject *
+mfsr_as_fsspec(self, args)
+       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 struct PyMethodDef mfsr_methods[] = {
+       {"as_fsspec",           (PyCFunction)mfsr_as_fsspec,    1},
+#if 0
+       {"as_pathname",         (PyCFunction)mfss_as_pathname,                  1},
+       {"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(self, name)
+       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(fsr)
+       FSRef *fsr;
+{
+       mfsrobject *self;
+       
+       self = PyObject_NEW(mfsrobject, &Mfsrtype);
+       if (self == NULL)
+               return NULL;
+       self->fsref = *fsr;
+       return self;
+}
+
+static int
+mfsr_compare(v, w)
+       mfsrobject *v, *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(self)
+       mfsrobject *self;
+{
+       PyMem_DEL(self);
+}
+
+statichere PyTypeObject Mfsrtype = {
+       PyObject_HEAD_INIT(&PyType_Type)
+       0,                              /*ob_size*/
+       "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 */
+/* -------------------------------------------------------- */
+
 static PyObject *
 mfs_ResolveAliasFile(self, args)
        PyObject *self; /* Not used */
@@ -819,6 +997,18 @@ mfs_FSSpec(self, args)
        return (PyObject *)newmfssobject(&fss);
 }
 
+static PyObject *
+mfs_FSRef(self, args)
+       PyObject *self; /* Not used */
+       PyObject *args;
+{
+       FSRef fsr;
+
+       if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr))
+               return NULL;
+       return (PyObject *)newmfsrobject(&fsr);
+}
+
 static PyObject *
 mfs_RawFSSpec(self, args)
        PyObject *self; /* Not used */
@@ -963,6 +1153,7 @@ static struct PyMethodDef mfs_methods[] = {
        {"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},
@@ -973,6 +1164,79 @@ static struct PyMethodDef mfs_methods[] = {
        {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)
+{
+       OSErr err;
+
+       /* 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) ) {
+               PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform");
+               return 0;
+       }
+       PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname");
+       return 0;
+}
+
+/* Convert FSSpec to PyObject */
+PyObject *PyMac_BuildFSRef(FSRef *v)
+{
+       return (PyObject *)newmfsrobject(v);
+}
+
+/*
+** 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) ) {
+               /* It's a pathname */
+               if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
+                       return 0;
+               refnum = 0; /* XXXX Should get CurWD here?? */
+               parid = 0;
+       } 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);
+}
 
 /* Initialization function for the module (*must* be called initmacfs) */
 
index 052c1ee9158423a5722023c6f5f415aad9005564..9c21ed20abffcb345d1c1d6680e290f54c6694e4 100644 (file)
@@ -130,10 +130,6 @@ extern pascal unsigned char *PLstrrchr(unsigned char *, unsigned char);
 ** with the python errors.h. */
 #define fnfErr -43
 
-/* Declared in macfsmodule.c: */
-extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *);
-extern PyObject *newmfssobject(FSSpec *);
-
 /* Interrupt code variables: */
 static int interrupted;                        /* Set to true when cmd-. seen */
 static RETSIGTYPE intcatcher(int);
@@ -1044,63 +1040,6 @@ PyMac_BuildOptStr255(Str255 s)
 }
 
 
-/*
-** Convert a Python object to an FSSpec.
-** The object may either be a full pathname or a triple
-** (vrefnum, dirid, path).
-** NOTE: This routine will fail on pre-sys7 machines. 
-** The caller is responsible for not calling this routine
-** in those cases (which is fine, since everyone calling
-** this is probably sys7 dependent anyway).
-*/
-int
-PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
-{
-       Str255 path;
-       short refnum;
-       long parid;
-       OSErr err;
-       FSSpec *fs2;
-
-#if !TARGET_API_MAC_OSX
-       /* XXX This #if is temporary */
-       /* first check whether it already is an FSSpec */
-       fs2 = mfs_GetFSSpecFSSpec(v);
-       if ( fs2 ) {
-               (void)FSMakeFSSpec(fs2->vRefNum, fs2->parID, fs2->name, fs);
-               return 1;
-       }
-#endif
-       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;
-       } else {
-               if( !PyArg_Parse(v, "(hlO&); FSSpec should be 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)
-{
-#if TARGET_API_MAC_OSX
-       PyErr_SetString(PyExc_NotImplementedError, "FSSpec not yet done for OSX");
-       return NULL;
-#else
-       return newmfssobject(v);
-#endif
-}
 
 /* Convert a Python object to a Rect.
    The object must be a (left, top, right, bottom) tuple.