Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4e566ab

Browse files
committed
Implemented minimal FSRef support, plus conversion between FSRefs, FSSpecs and pathnames where applicable.
PyMac_GetFSSpec and PyMac_BuildFSSpec have moved to macfsmodule from macglue. These mods are untested on OSX.
1 parent 2d96f11 commit 4e566ab

3 files changed

Lines changed: 282 additions & 74 deletions

File tree

Mac/Include/macglue.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,6 @@ int PyMac_GetStr255(PyObject *, Str255); /* argument parser for Str255 */
106106
PyObject *PyMac_BuildStr255(Str255); /* Convert Str255 to PyObject */
107107
PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, NULL to None */
108108

109-
int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */
110-
PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */
111-
112109
int PyMac_GetRect(PyObject *, Rect *); /* argument parser for Rect */
113110
PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */
114111

@@ -129,6 +126,14 @@ void PyMac_Initialize(void); /* Initialize function for embedding Python */
129126
short PyMac_OpenPrefFile(void); /* From macgetpath.c, open and return preference file */
130127
#endif
131128

129+
/* from macfsmodule.c: */
130+
int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */
131+
PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */
132+
133+
int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */
134+
PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */
135+
136+
132137
/* From macfiletype.c: */
133138

134139
long PyMac_getfiletype(char *); /* Get file type */

Mac/Modules/macfsmodule.c

Lines changed: 274 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3838

3939
#include "getapplbycreator.h"
4040

41-
/* Should this be in macglue.h? */
42-
extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *);
4341

4442
static PyObject *ErrorObject;
4543

@@ -67,6 +65,18 @@ staticforward PyTypeObject Mfsstype;
6765

6866
#define is_mfssobject(v) ((v)->ob_type == &Mfsstype)
6967

68+
/* ---------------------------------------------------------------- */
69+
/* Declarations for objects of type FSRef */
70+
71+
typedef struct {
72+
PyObject_HEAD
73+
FSRef fsref;
74+
} mfsrobject;
75+
76+
staticforward PyTypeObject Mfsrtype;
77+
78+
#define is_mfsrobject(v) ((v)->ob_type == &Mfsrtype)
79+
7080

7181
/* ---------------------------------------------------------------- */
7282
/* Declarations for objects of type FInfo */
@@ -81,7 +91,8 @@ staticforward PyTypeObject Mfsitype;
8191
#define is_mfsiobject(v) ((v)->ob_type == &Mfsitype)
8292

8393

84-
mfssobject *newmfssobject(FSSpec *fss); /* Forward */
94+
staticforward mfssobject *newmfssobject(FSSpec *fss); /* Forward */
95+
staticforward mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */
8596

8697
/* ---------------------------------------------------------------- */
8798

@@ -336,15 +347,56 @@ static PyTypeObject Mfsitype = {
336347

337348

338349
/*
339-
** Helper routine for other modules: return an FSSpec * if the
340-
** object is a python fsspec object, else NULL
350+
** Helper routines for the FSRef and FSSpec creators in macglue.c
351+
** They return an FSSpec/FSRef if the Python object encapsulating
352+
** either is passed. They return a boolean success indicator.
353+
** Note that they do not set an exception on failure, they're only
354+
** helper routines.
341355
*/
342-
FSSpec *
343-
mfs_GetFSSpecFSSpec(PyObject *self)
356+
static int
357+
_mfs_GetFSSpecFromFSSpec(PyObject *self, FSSpec *fssp)
358+
{
359+
if ( is_mfssobject(self) ) {
360+
*fssp = ((mfssobject *)self)->fsspec;
361+
return 1;
362+
}
363+
return 0;
364+
}
365+
366+
/* Return an FSSpec if this is an FSref */
367+
static int
368+
_mfs_GetFSSpecFromFSRef(PyObject *self, FSSpec *fssp)
344369
{
345-
if ( is_mfssobject(self) )
346-
return &((mfssobject *)self)->fsspec;
347-
return NULL;
370+
static FSRef *fsrp;
371+
372+
if ( is_mfsrobject(self) ) {
373+
fsrp = &((mfsrobject *)self)->fsref;
374+
if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr )
375+
return 1;
376+
}
377+
return 0;
378+
}
379+
380+
/* Return an FSRef if this is an FSRef */
381+
static int
382+
_mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp)
383+
{
384+
if ( is_mfsrobject(self) ) {
385+
*fsrp = ((mfsrobject *)self)->fsref;
386+
return 1;
387+
}
388+
return 0;
389+
}
390+
391+
/* Return an FSRef if this is an FSSpec */
392+
static int
393+
_mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp)
394+
{
395+
if ( is_mfssobject(self) ) {
396+
if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr )
397+
return 1;
398+
}
399+
return 0;
348400
}
349401

350402
/*
@@ -467,6 +519,24 @@ mfss_NewAliasMinimal(self, args)
467519
return (PyObject *)newmfsaobject(alias);
468520
}
469521

522+
static PyObject *
523+
mfss_FSpMakeFSRef(self, args)
524+
mfssobject *self;
525+
PyObject *args;
526+
{
527+
OSErr err;
528+
FSRef fsref;
529+
530+
if (!PyArg_ParseTuple(args, ""))
531+
return NULL;
532+
err = FSpMakeFSRef(&self->fsspec, &fsref);
533+
if ( err ) {
534+
PyErr_Mac(ErrorObject, err);
535+
return NULL;
536+
}
537+
return (PyObject *)newmfsrobject(&fsref);
538+
}
539+
470540
/* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
471541
static PyObject *
472542
mfss_GetCreatorType(self, args)
@@ -596,6 +666,8 @@ mfss_SetDates(self, args)
596666
static struct PyMethodDef mfss_methods[] = {
597667
{"as_pathname", (PyCFunction)mfss_as_pathname, 1},
598668
{"as_tuple", (PyCFunction)mfss_as_tuple, 1},
669+
{"as_fsref", (PyCFunction)mfss_FSpMakeFSRef, 1},
670+
{"FSpMakeFSRef", (PyCFunction)mfss_FSpMakeFSRef, 1},
599671
{"NewAlias", (PyCFunction)mfss_NewAlias, 1},
600672
{"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1},
601673
{"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1},
@@ -695,6 +767,112 @@ statichere PyTypeObject Mfsstype = {
695767
/* End of code for FSSpec objects */
696768
/* -------------------------------------------------------- */
697769

770+
static PyObject *
771+
mfsr_as_fsspec(self, args)
772+
mfsrobject *self;
773+
PyObject *args;
774+
{
775+
OSErr err;
776+
FSSpec fss;
777+
778+
if (!PyArg_ParseTuple(args, ""))
779+
return NULL;
780+
err = FSGetCatalogInfo(&self->fsref, kFSCatInfoNone, NULL, NULL, &fss, NULL);
781+
if ( err ) {
782+
PyErr_Mac(ErrorObject, err);
783+
return NULL;
784+
}
785+
Py_INCREF(Py_None);
786+
return (PyObject *)newmfssobject(&fss);
787+
}
788+
789+
static struct PyMethodDef mfsr_methods[] = {
790+
{"as_fsspec", (PyCFunction)mfsr_as_fsspec, 1},
791+
#if 0
792+
{"as_pathname", (PyCFunction)mfss_as_pathname, 1},
793+
{"as_tuple", (PyCFunction)mfss_as_tuple, 1},
794+
{"NewAlias", (PyCFunction)mfss_NewAlias, 1},
795+
{"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1},
796+
{"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1},
797+
{"SetCreatorType", (PyCFunction)mfss_SetCreatorType, 1},
798+
{"GetFInfo", (PyCFunction)mfss_GetFInfo, 1},
799+
{"SetFInfo", (PyCFunction)mfss_SetFInfo, 1},
800+
{"GetDates", (PyCFunction)mfss_GetDates, 1},
801+
{"SetDates", (PyCFunction)mfss_SetDates, 1},
802+
#endif
803+
804+
{NULL, NULL} /* sentinel */
805+
};
806+
807+
/* ---------- */
808+
809+
static PyObject *
810+
mfsr_getattr(self, name)
811+
mfsrobject *self;
812+
char *name;
813+
{
814+
if ( strcmp(name, "data") == 0)
815+
return PyString_FromStringAndSize((char *)&self->fsref, sizeof(FSRef));
816+
return Py_FindMethod(mfsr_methods, (PyObject *)self, name);
817+
}
818+
819+
mfsrobject *
820+
newmfsrobject(fsr)
821+
FSRef *fsr;
822+
{
823+
mfsrobject *self;
824+
825+
self = PyObject_NEW(mfsrobject, &Mfsrtype);
826+
if (self == NULL)
827+
return NULL;
828+
self->fsref = *fsr;
829+
return self;
830+
}
831+
832+
static int
833+
mfsr_compare(v, w)
834+
mfsrobject *v, *w;
835+
{
836+
OSErr err;
837+
838+
if ( v == w ) return 0;
839+
err = FSCompareFSRefs(&v->fsref, &w->fsref);
840+
if ( err == 0 )
841+
return 0;
842+
if (v < w )
843+
return -1;
844+
return 1;
845+
}
846+
847+
static void
848+
mfsr_dealloc(self)
849+
mfsrobject *self;
850+
{
851+
PyMem_DEL(self);
852+
}
853+
854+
statichere PyTypeObject Mfsrtype = {
855+
PyObject_HEAD_INIT(&PyType_Type)
856+
0, /*ob_size*/
857+
"FSRef", /*tp_name*/
858+
sizeof(mfsrobject), /*tp_basicsize*/
859+
0, /*tp_itemsize*/
860+
/* methods */
861+
(destructor)mfsr_dealloc, /*tp_dealloc*/
862+
(printfunc)0, /*tp_print*/
863+
(getattrfunc)mfsr_getattr, /*tp_getattr*/
864+
(setattrfunc)0, /*tp_setattr*/
865+
(cmpfunc)mfsr_compare, /*tp_compare*/
866+
(reprfunc)0, /*tp_repr*/
867+
0, /*tp_as_number*/
868+
0, /*tp_as_sequence*/
869+
0, /*tp_as_mapping*/
870+
(hashfunc)0, /*tp_hash*/
871+
};
872+
873+
/* End of code for FSRef objects */
874+
/* -------------------------------------------------------- */
875+
698876
static PyObject *
699877
mfs_ResolveAliasFile(self, args)
700878
PyObject *self; /* Not used */
@@ -819,6 +997,18 @@ mfs_FSSpec(self, args)
819997
return (PyObject *)newmfssobject(&fss);
820998
}
821999

1000+
static PyObject *
1001+
mfs_FSRef(self, args)
1002+
PyObject *self; /* Not used */
1003+
PyObject *args;
1004+
{
1005+
FSRef fsr;
1006+
1007+
if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr))
1008+
return NULL;
1009+
return (PyObject *)newmfsrobject(&fsr);
1010+
}
1011+
8221012
static PyObject *
8231013
mfs_RawFSSpec(self, args)
8241014
PyObject *self; /* Not used */
@@ -963,6 +1153,7 @@ static struct PyMethodDef mfs_methods[] = {
9631153
{"SetFolder", mfs_SetFolder, 1},
9641154
#endif
9651155
{"FSSpec", mfs_FSSpec, 1},
1156+
{"FSRef", mfs_FSRef, 1},
9661157
{"RawFSSpec", mfs_RawFSSpec, 1},
9671158
{"RawAlias", mfs_RawAlias, 1},
9681159
{"FindFolder", mfs_FindFolder, 1},
@@ -973,6 +1164,79 @@ static struct PyMethodDef mfs_methods[] = {
9731164
{NULL, NULL} /* sentinel */
9741165
};
9751166

1167+
/*
1168+
** Convert a Python object to an FSSpec.
1169+
** The object may either be a full pathname, an FSSpec, an FSRef or a triple
1170+
** (vrefnum, dirid, path).
1171+
*/
1172+
int
1173+
PyMac_GetFSRef(PyObject *v, FSRef *fsr)
1174+
{
1175+
OSErr err;
1176+
1177+
/* If it's an FSRef we're also okay. */
1178+
if (_mfs_GetFSRefFromFSRef(v, fsr))
1179+
return 1;
1180+
/* first check whether it already is an FSSpec */
1181+
if ( _mfs_GetFSRefFromFSSpec(v, fsr) )
1182+
return 1;
1183+
if ( PyString_Check(v) ) {
1184+
PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform");
1185+
return 0;
1186+
}
1187+
PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname");
1188+
return 0;
1189+
}
1190+
1191+
/* Convert FSSpec to PyObject */
1192+
PyObject *PyMac_BuildFSRef(FSRef *v)
1193+
{
1194+
return (PyObject *)newmfsrobject(v);
1195+
}
1196+
1197+
/*
1198+
** Convert a Python object to an FSRef.
1199+
** The object may either be a full pathname (OSX only), an FSSpec or an FSRef.
1200+
*/
1201+
int
1202+
PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
1203+
{
1204+
Str255 path;
1205+
short refnum;
1206+
long parid;
1207+
OSErr err;
1208+
1209+
/* first check whether it already is an FSSpec */
1210+
if ( _mfs_GetFSSpecFromFSSpec(v, fs) )
1211+
return 1;
1212+
/* If it's an FSRef we're also okay. */
1213+
if (_mfs_GetFSSpecFromFSRef(v, fs))
1214+
return 1;
1215+
if ( PyString_Check(v) ) {
1216+
/* It's a pathname */
1217+
if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
1218+
return 0;
1219+
refnum = 0; /* XXXX Should get CurWD here?? */
1220+
parid = 0;
1221+
} else {
1222+
if( !PyArg_Parse(v, "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)",
1223+
&refnum, &parid, PyMac_GetStr255, &path)) {
1224+
return 0;
1225+
}
1226+
}
1227+
err = FSMakeFSSpec(refnum, parid, path, fs);
1228+
if ( err && err != fnfErr ) {
1229+
PyMac_Error(err);
1230+
return 0;
1231+
}
1232+
return 1;
1233+
}
1234+
1235+
/* Convert FSSpec to PyObject */
1236+
PyObject *PyMac_BuildFSSpec(FSSpec *v)
1237+
{
1238+
return (PyObject *)newmfssobject(v);
1239+
}
9761240

9771241
/* Initialization function for the module (*must* be called initmacfs) */
9781242

0 commit comments

Comments
 (0)