1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 #include "allobjects.h"
26 #include "modsupport.h" /* For getargs() etc. */
32 #include <StandardFile.h>
36 #include "nfullpath.h"
39 #define FileFilterUPP FileFilterProcPtr
42 static object
*ErrorObject
;
44 /* ----------------------------------------------------- */
45 /* Declarations for objects of type Alias */
52 staticforward typeobject Mfsatype
;
54 #define is_mfsaobject(v) ((v)->ob_type == &Mfsatype)
56 /* ---------------------------------------------------------------- */
57 /* Declarations for objects of type FSSpec */
64 staticforward typeobject Mfsstype
;
66 #define is_mfssobject(v) ((v)->ob_type == &Mfsstype)
69 /* ---------------------------------------------------------------- */
70 /* Declarations for objects of type FInfo */
77 staticforward typeobject Mfsitype
;
79 #define is_mfsiobject(v) ((v)->ob_type == &Mfsitype)
82 mfssobject
*newmfssobject(FSSpec
*fss
); /* Forward */
84 /* ---------------------------------------------------------------- */
87 mfsa_Resolve(self
, args
)
91 FSSpec from
, *fromp
, result
;
96 if (!newgetargs(args
, "|O&", PyMac_GetFSSpec
, &from
))
102 err
= ResolveAlias(fromp
, self
->alias
, &result
, &changed
);
104 PyErr_Mac(ErrorObject
, err
);
107 return mkvalue("(Oi)", newmfssobject(&result
), (int)changed
);
111 mfsa_GetInfo(self
, args
)
119 if (!newgetargs(args
, "i", &i
))
121 err
= GetAliasInfo(self
->alias
, (AliasInfoType
)i
, value
);
123 PyErr_Mac(ErrorObject
, err
);
126 return newsizedstringobject((char *)&value
[1], value
[0]);
130 mfsa_Update(self
, args
)
134 FSSpec target
, fromfile
, *fromfilep
;
138 fromfile
.name
[0] = 0;
139 if (!newgetargs(args
, "O&|O&", PyMac_GetFSSpec
, &target
,
140 PyMac_GetFSSpec
, &fromfile
))
142 if ( fromfile
.name
[0] )
143 fromfilep
= &fromfile
;
146 err
= UpdateAlias(fromfilep
, &target
, self
->alias
, &changed
);
148 PyErr_Mac(ErrorObject
, err
);
151 return mkvalue("i", (int)changed
);
154 static struct methodlist mfsa_methods
[] = {
155 {"Resolve", (method
)mfsa_Resolve
, 1},
156 {"GetInfo", (method
)mfsa_GetInfo
, 1},
157 {"Update", (method
)mfsa_Update
, 1},
159 {NULL
, NULL
} /* sentinel */
165 mfsa_getattr(self
, name
)
169 if ( strcmp(name
, "data") == 0 ) {
173 size
= GetHandleSize((Handle
)self
->alias
);
174 HLock((Handle
)self
->alias
);
175 rv
= PyString_FromStringAndSize(*(Handle
)self
->alias
, size
);
176 HUnlock((Handle
)self
->alias
);
179 return findmethod(mfsa_methods
, (object
*)self
, name
);
188 self
= NEWOBJ(mfsaobject
, &Mfsatype
);
202 should we
do something here
?
209 statichere typeobject Mfsatype
= {
210 OB_HEAD_INIT(&Typetype
)
213 sizeof(mfsaobject
), /*tp_basicsize*/
216 (destructor
)mfsa_dealloc
, /*tp_dealloc*/
217 (printfunc
)0, /*tp_print*/
218 (getattrfunc
)mfsa_getattr
, /*tp_getattr*/
219 (setattrfunc
)0, /*tp_setattr*/
220 (cmpfunc
)0, /*tp_compare*/
221 (reprfunc
)0, /*tp_repr*/
223 0, /*tp_as_sequence*/
225 (hashfunc
)0, /*tp_hash*/
228 /* End of code for Alias objects */
229 /* -------------------------------------------------------- */
231 /* ---------------------------------------------------------------- */
233 static struct methodlist mfsi_methods
[] = {
235 {NULL
, NULL
} /* sentinel */
245 self
= NEWOBJ(mfsiobject
, &Mfsitype
);
248 memset((char *)&self
->finfo
, '\0', sizeof(self
->finfo
));
260 mfsi_getattr(self
, name
)
264 if ( strcmp(name
, "Type") == 0 )
265 return PyMac_BuildOSType(self
->finfo
.fdType
);
266 else if ( strcmp(name
, "Creator") == 0 )
267 return PyMac_BuildOSType(self
->finfo
.fdCreator
);
268 else if ( strcmp(name
, "Flags") == 0 )
269 return Py_BuildValue("i", (int)self
->finfo
.fdFlags
);
270 else if ( strcmp(name
, "Location") == 0 )
271 return PyMac_BuildPoint(self
->finfo
.fdLocation
);
272 else if ( strcmp(name
, "Fldr") == 0 )
273 return Py_BuildValue("i", (int)self
->finfo
.fdFldr
);
275 return findmethod(mfsi_methods
, (object
*)self
, name
);
280 mfsi_setattr(self
, name
, v
)
289 err_setstr(AttributeError
, "Cannot delete attribute");
292 if ( strcmp(name
, "Type") == 0 )
293 rv
= PyMac_GetOSType(v
, &self
->finfo
.fdType
);
294 else if ( strcmp(name
, "Creator") == 0 )
295 rv
= PyMac_GetOSType(v
, &self
->finfo
.fdCreator
);
296 else if ( strcmp(name
, "Flags") == 0 ) {
297 rv
= PyArg_Parse(v
, "i", &i
);
298 self
->finfo
.fdFlags
= (short)i
;
299 } else if ( strcmp(name
, "Location") == 0 )
300 rv
= PyMac_GetPoint(v
, &self
->finfo
.fdLocation
);
301 else if ( strcmp(name
, "Fldr") == 0 ) {
302 rv
= PyArg_Parse(v
, "i", &i
);
303 self
->finfo
.fdFldr
= (short)i
;
305 err_setstr(AttributeError
, "No such attribute");
314 static typeobject Mfsitype
= {
315 OB_HEAD_INIT(&Typetype
)
317 "FInfo object", /*tp_name*/
318 sizeof(mfsiobject
), /*tp_basicsize*/
321 (destructor
)mfsi_dealloc
, /*tp_dealloc*/
322 (printfunc
)0, /*tp_print*/
323 (getattrfunc
)mfsi_getattr
, /*tp_getattr*/
324 (setattrfunc
)mfsi_setattr
, /*tp_setattr*/
325 (cmpfunc
)0, /*tp_compare*/
326 (reprfunc
)0, /*tp_repr*/
328 0, /*tp_as_sequence*/
330 (hashfunc
)0, /*tp_hash*/
333 /* End of code for FInfo object objects */
334 /* -------------------------------------------------------- */
338 ** Helper routine for other modules: return an FSSpec * if the
339 ** object is a python fsspec object, else NULL
342 mfs_GetFSSpecFSSpec(self
)
345 if ( is_mfssobject(self
) )
346 return &((mfssobject
*)self
)->fsspec
;
351 mfss_as_pathname(self
, args
)
358 if (!newgetargs(args
, ""))
360 err
= nfullpath(&self
->fsspec
, strbuf
);
362 PyErr_Mac(ErrorObject
, err
);
365 return newstringobject(strbuf
);
369 mfss_as_tuple(self
, args
)
373 if (!newgetargs(args
, ""))
375 return Py_BuildValue("(iis#)", self
->fsspec
.vRefNum
, self
->fsspec
.parID
,
376 &self
->fsspec
.name
[1], self
->fsspec
.name
[0]);
380 mfss_NewAlias(self
, args
)
389 if (!newgetargs(args
, "|O&", PyMac_GetFSSpec
, &src
))
395 err
= NewAlias(srcp
, &self
->fsspec
, &alias
);
397 PyErr_Mac(ErrorObject
, err
);
401 return (object
*)newmfsaobject(alias
);
405 mfss_NewAliasMinimal(self
, args
)
412 if (!newgetargs(args
, ""))
414 err
= NewAliasMinimal(&self
->fsspec
, &alias
);
416 PyErr_Mac(ErrorObject
, err
);
419 return (object
*)newmfsaobject(alias
);
422 /* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
424 mfss_GetCreatorType(self
, args
)
431 if (!newgetargs(args
, ""))
433 err
= FSpGetFInfo(&self
->fsspec
, &info
);
435 PyErr_Mac(ErrorObject
, err
);
438 return Py_BuildValue("(O&O&)",
439 PyMac_BuildOSType
, info
.fdCreator
, PyMac_BuildOSType
, info
.fdType
);
443 mfss_SetCreatorType(self
, args
)
448 OSType creator
, type
;
451 if (!newgetargs(args
, "O&O&", PyMac_GetOSType
, &creator
, PyMac_GetOSType
, &type
))
453 err
= FSpGetFInfo(&self
->fsspec
, &info
);
455 PyErr_Mac(ErrorObject
, err
);
459 info
.fdCreator
= creator
;
460 err
= FSpSetFInfo(&self
->fsspec
, &info
);
462 PyErr_Mac(ErrorObject
, err
);
470 mfss_GetFInfo(self
, args
)
478 if (!newgetargs(args
, ""))
480 if ( (fip
=newmfsiobject()) == NULL
)
482 err
= FSpGetFInfo(&self
->fsspec
, &fip
->finfo
);
484 PyErr_Mac(ErrorObject
, err
);
488 return (object
*)fip
;
492 mfss_SetFInfo(self
, args
)
499 if (!newgetargs(args
, "O!", &Mfsitype
, &fip
))
501 err
= FSpSetFInfo(&self
->fsspec
, &fip
->finfo
);
503 PyErr_Mac(ErrorObject
, err
);
510 static struct methodlist mfss_methods
[] = {
511 {"as_pathname", (method
)mfss_as_pathname
, 1},
512 {"as_tuple", (method
)mfss_as_tuple
, 1},
513 {"NewAlias", (method
)mfss_NewAlias
, 1},
514 {"NewAliasMinimal", (method
)mfss_NewAliasMinimal
, 1},
515 {"GetCreatorType", (method
)mfss_GetCreatorType
, 1},
516 {"SetCreatorType", (method
)mfss_SetCreatorType
, 1},
517 {"GetFInfo", (method
)mfss_GetFInfo
, 1},
518 {"SetFInfo", (method
)mfss_SetFInfo
, 1},
520 {NULL
, NULL
} /* sentinel */
526 mfss_getattr(self
, name
)
530 if ( strcmp(name
, "data") == 0)
531 return PyString_FromStringAndSize((char *)&self
->fsspec
, sizeof(FSSpec
));
532 return findmethod(mfss_methods
, (object
*)self
, name
);
541 self
= NEWOBJ(mfssobject
, &Mfsstype
);
561 sprintf(buf
, "FSSpec((%d, %d, '%.*s'))",
562 self
->fsspec
.vRefNum
,
564 self
->fsspec
.name
[0], self
->fsspec
.name
+1);
565 return newstringobject(buf
);
575 if ( v
->fsspec
.vRefNum
< w
->fsspec
.vRefNum
) return -1;
576 if ( v
->fsspec
.vRefNum
> w
->fsspec
.vRefNum
) return 1;
577 if ( v
->fsspec
.parID
< w
->fsspec
.parID
) return -1;
578 if ( v
->fsspec
.parID
> w
->fsspec
.parID
) return 1;
579 minlen
= v
->fsspec
.name
[0];
580 if ( w
->fsspec
.name
[0] < minlen
) minlen
= w
->fsspec
.name
[0];
581 res
= strncmp((char *)v
->fsspec
.name
+1, (char *)w
->fsspec
.name
+1, minlen
);
582 if ( res
) return res
;
583 if ( v
->fsspec
.name
[0] < w
->fsspec
.name
[0] ) return -1;
584 if ( v
->fsspec
.name
[0] > w
->fsspec
.name
[0] ) return 1;
588 statichere typeobject Mfsstype
= {
589 OB_HEAD_INIT(&Typetype
)
591 "FSSpec", /*tp_name*/
592 sizeof(mfssobject
), /*tp_basicsize*/
595 (destructor
)mfss_dealloc
, /*tp_dealloc*/
596 (printfunc
)0, /*tp_print*/
597 (getattrfunc
)mfss_getattr
, /*tp_getattr*/
598 (setattrfunc
)0, /*tp_setattr*/
599 (cmpfunc
)mfss_compare
, /*tp_compare*/
600 (reprfunc
)mfss_repr
, /*tp_repr*/
602 0, /*tp_as_sequence*/
604 (hashfunc
)0, /*tp_hash*/
607 /* End of code for FSSpec objects */
608 /* -------------------------------------------------------- */
611 mfs_ResolveAliasFile(self
, args
)
612 object
*self
; /* Not used */
616 Boolean chain
= 1, isfolder
, wasaliased
;
619 if (!newgetargs(args
, "O&|i", PyMac_GetFSSpec
, &fss
, &chain
))
621 err
= ResolveAliasFile(&fss
, chain
, &isfolder
, &wasaliased
);
623 PyErr_Mac(ErrorObject
, err
);
626 return mkvalue("Oii", newmfssobject(&fss
), (int)isfolder
, (int)wasaliased
);
630 mfs_StandardGetFile(self
, args
)
631 object
*self
; /* Not used */
636 StandardFileReply reply
;
638 list
[0] = list
[1] = list
[2] = list
[3] = 0;
640 if (!newgetargs(args
, "|O&O&O&O&", PyMac_GetOSType
, &list
[0],
641 PyMac_GetOSType
, &list
[1], PyMac_GetOSType
, &list
[2],
642 PyMac_GetOSType
, &list
[3]) )
644 while ( numtypes
< 4 && list
[numtypes
] ) {
649 StandardGetFile((FileFilterUPP
)0, numtypes
, list
, &reply
);
650 return mkvalue("(Oi)", newmfssobject(&reply
.sfFile
), reply
.sfGood
);
654 mfs_PromptGetFile(self
, args
)
655 object
*self
; /* Not used */
660 StandardFileReply reply
;
663 list
[0] = list
[1] = list
[2] = list
[3] = 0;
665 if (!newgetargs(args
, "s|O&O&O&O&", &prompt
, PyMac_GetOSType
, &list
[0],
666 PyMac_GetOSType
, &list
[1], PyMac_GetOSType
, &list
[2],
667 PyMac_GetOSType
, &list
[3]) )
669 while ( numtypes
< 4 && list
[numtypes
] ) {
674 PyMac_PromptGetFile(numtypes
, list
, &reply
, prompt
);
675 return mkvalue("(Oi)", newmfssobject(&reply
.sfFile
), reply
.sfGood
);
679 mfs_StandardPutFile(self
, args
)
680 object
*self
; /* Not used */
684 StandardFileReply reply
;
687 if (!newgetargs(args
, "O&|O&", PyMac_GetStr255
, &prompt
, PyMac_GetStr255
, &dft
) )
689 StandardPutFile(prompt
, dft
, &reply
);
690 return mkvalue("(Oi)",newmfssobject(&reply
.sfFile
), reply
.sfGood
);
694 ** Set initial directory for file dialogs */
696 mfs_SetFolder(self
, args
)
706 orefnum
= -LMGetSFSaveDisk();
707 oparid
= LMGetCurDirStore();
708 (void)FSMakeFSSpec(orefnum
, oparid
, "\pplaceholder", &ospec
);
710 /* Go to working directory by default */
711 (void)FSMakeFSSpec(0, 0, "\p:placeholder", &spec
);
712 if (!newgetargs(args
, "|O&", PyMac_GetFSSpec
, &spec
))
714 /* Set standard-file working directory */
715 LMSetSFSaveDisk(-spec
.vRefNum
);
716 LMSetCurDirStore(spec
.parID
);
717 return (object
*)newmfssobject(&ospec
);
721 mfs_FSSpec(self
, args
)
722 object
*self
; /* Not used */
727 if (!newgetargs(args
, "O&", PyMac_GetFSSpec
, &fss
))
729 return (object
*)newmfssobject(&fss
);
733 mfs_RawFSSpec(self
, args
)
734 object
*self
; /* Not used */
740 if (!newgetargs(args
, "s#", &fssp
, &size
))
742 if ( size
!= sizeof(FSSpec
) ) {
743 PyErr_SetString(PyExc_TypeError
, "Incorrect size for FSSpec record");
746 return (object
*)newmfssobject(fssp
);
750 mfs_RawAlias(self
, args
)
751 object
*self
; /* Not used */
758 if (!newgetargs(args
, "s#", &dataptr
, &size
))
766 memcpy((char *)*h
, dataptr
, size
);
768 return (object
*)newmfsaobject((AliasHandle
)h
);
772 mfs_GetDirectory(self
, args
)
773 object
*self
; /* Not used */
780 if (!newgetargs(args
, "|s", &prompt
) )
783 ok
= PyMac_GetDirectory(&fsdir
, prompt
);
784 return mkvalue("(Oi)", newmfssobject(&fsdir
), ok
);
788 mfs_FindFolder(self
, args
)
789 object
*self
; /* Not used */
799 if (!newgetargs(args
, "hO&i", &where
, PyMac_GetOSType
, &which
, &create
) )
801 err
= FindFolder(where
, which
, (Boolean
)create
, &refnum
, &dirid
);
803 PyErr_Mac(ErrorObject
, err
);
806 return mkvalue("(ii)", refnum
, dirid
);
810 mfs_FInfo(self
, args
)
814 return (object
*)newmfsiobject();
817 /* List of methods defined in the module */
819 static struct methodlist mfs_methods
[] = {
820 {"ResolveAliasFile", mfs_ResolveAliasFile
, 1},
821 {"StandardGetFile", mfs_StandardGetFile
, 1},
822 {"PromptGetFile", mfs_PromptGetFile
, 1},
823 {"StandardPutFile", mfs_StandardPutFile
, 1},
824 {"GetDirectory", mfs_GetDirectory
, 1},
825 {"SetFolder", mfs_SetFolder
, 1},
826 {"FSSpec", mfs_FSSpec
, 1},
827 {"RawFSSpec", mfs_RawFSSpec
, 1},
828 {"RawAlias", mfs_RawAlias
, 1},
829 {"FindFolder", mfs_FindFolder
, 1},
830 {"FInfo", mfs_FInfo
, 1},
832 {NULL
, NULL
} /* sentinel */
836 /* Initialization function for the module (*must* be called initmacfs) */
843 /* Create the module and add the functions */
844 m
= initmodule("macfs", mfs_methods
);
846 /* Add some symbolic constants to the module */
847 d
= getmoduledict(m
);
848 ErrorObject
= newstringobject("macfs.error");
849 dictinsert(d
, "error", ErrorObject
);
851 /* XXXX Add constants here */
853 /* Check for errors */
855 fatal("can't initialize module macfs");