blob: d2f1a5d84216adb03a78c58a4da25683e777363c [file] [log] [blame]
Jack Jansen84fa5ec1995-01-18 14:04:40 +00001/***********************************************************
Guido van Rossumefd97671995-01-26 22:56:16 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Jack Jansen84fa5ec1995-01-18 14:04:40 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25#include "allobjects.h"
26#include "modsupport.h" /* For getargs() etc. */
27#include "macglue.h"
28
29#include <Files.h>
30#include <StandardFile.h>
31#include <Aliases.h>
32
33#include "nfullpath.h"
34
Guido van Rossuma42960c1995-01-19 00:03:47 +000035#ifdef THINK_C
36#define FileFilterUPP FileFilterProcPtr
37#endif
38
Jack Jansen17ba43f1995-01-26 16:22:07 +000039
Jack Jansen84fa5ec1995-01-18 14:04:40 +000040static object *ErrorObject;
41
42/* ----------------------------------------------------- */
Jack Jansen17ba43f1995-01-26 16:22:07 +000043/* Declarations for objects of type Alias */
44
45typedef struct {
46 OB_HEAD
47 AliasHandle alias;
48} mfsaobject;
49
50staticforward typeobject Mfsatype;
51
52#define is_mfsaobject(v) ((v)->ob_type == &Mfsatype)
53
54/* ---------------------------------------------------------------- */
55/* Declarations for objects of type FSSpec */
56
57typedef struct {
58 OB_HEAD
59 FSSpec fsspec;
60} mfssobject;
61
62staticforward typeobject Mfsstype;
63
64#define is_mfssobject(v) ((v)->ob_type == &Mfsstype)
65
Guido van Rossumefd97671995-01-26 22:56:16 +000066
67mfssobject *newmfssobject(FSSpec *fss); /* Forward */
68
Jack Jansen17ba43f1995-01-26 16:22:07 +000069/* ---------------------------------------------------------------- */
Jack Jansen84fa5ec1995-01-18 14:04:40 +000070
71static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +000072mfsa_Resolve(self, args)
73 mfsaobject *self;
Jack Jansen84fa5ec1995-01-18 14:04:40 +000074 object *args;
75{
Jack Jansen17ba43f1995-01-26 16:22:07 +000076 FSSpec from, *fromp, result;
77 Boolean changed;
78 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +000079
Jack Jansen17ba43f1995-01-26 16:22:07 +000080 from.name[0] = 0;
81 if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &from))
Jack Jansen84fa5ec1995-01-18 14:04:40 +000082 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +000083 if (from.name[0] )
84 fromp = &from;
85 else
86 fromp = NULL;
87 err = ResolveAlias(fromp, self->alias, &result, &changed);
88 if ( err ) {
89 PyErr_Mac(ErrorObject, err);
90 return NULL;
91 }
92 return mkvalue("(Oi)", newmfssobject(&result), (int)changed);
Jack Jansen84fa5ec1995-01-18 14:04:40 +000093}
94
95static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +000096mfsa_GetInfo(self, args)
97 mfsaobject *self;
Jack Jansen84fa5ec1995-01-18 14:04:40 +000098 object *args;
99{
Jack Jansen17ba43f1995-01-26 16:22:07 +0000100 Str63 value;
101 int i;
102 OSErr err;
103
104 if (!newgetargs(args, "i", &i))
105 return NULL;
106 err = GetAliasInfo(self->alias, (AliasInfoType)i, value);
107 if ( err ) {
108 PyErr_Mac(ErrorObject, err);
109 return 0;
110 }
111 return newsizedstringobject((char *)&value[1], value[0]);
112}
113
114static object *
115mfsa_Update(self, args)
116 mfsaobject *self;
117 object *args;
118{
119 FSSpec target, fromfile, *fromfilep;
120 OSErr err;
121 Boolean changed;
122
123 fromfile.name[0] = 0;
124 if (!newgetargs(args, "O&|O&", PyMac_GetFSSpec, &target,
125 PyMac_GetFSSpec, &fromfile))
126 return NULL;
127 if ( fromfile.name[0] )
128 fromfilep = &fromfile;
129 else
130 fromfilep = NULL;
131 err = UpdateAlias(fromfilep, &target, self->alias, &changed);
132 if ( err ) {
133 PyErr_Mac(ErrorObject, err);
134 return 0;
135 }
136 return mkvalue("i", (int)changed);
137}
138
139static struct methodlist mfsa_methods[] = {
Guido van Rossumefd97671995-01-26 22:56:16 +0000140 {"Resolve", (method)mfsa_Resolve, 1},
141 {"GetInfo", (method)mfsa_GetInfo, 1},
142 {"Update", (method)mfsa_Update, 1},
Jack Jansen17ba43f1995-01-26 16:22:07 +0000143
144 {NULL, NULL} /* sentinel */
145};
146
147/* ---------- */
148
149static object *
150mfsa_getattr(self, name)
151 mfsaobject *self;
152 char *name;
153{
Jack Jansenc889b761995-02-13 12:00:46 +0000154 if ( strcmp(name, "data") == 0 ) {
155 int size;
156 PyObject *rv;
157
158 size = GetHandleSize((Handle)self->alias);
159 HLock((Handle)self->alias);
160 rv = PyString_FromStringAndSize(*(Handle)self->alias, size);
161 HUnlock((Handle)self->alias);
162 return rv;
163 }
Jack Jansen17ba43f1995-01-26 16:22:07 +0000164 return findmethod(mfsa_methods, (object *)self, name);
165}
166
167mfsaobject *
168newmfsaobject(alias)
169 AliasHandle alias;
170{
171 mfsaobject *self;
172
173 self = NEWOBJ(mfsaobject, &Mfsatype);
174 if (self == NULL)
175 return NULL;
176 self->alias = alias;
177 return self;
178}
179
180
181static void
182mfsa_dealloc(self)
183 mfsaobject *self;
184{
185#if 0
186 if ( self->alias ) {
187 should we do something here?
188 }
189#endif
190
191 DEL(self);
192}
193
194static typeobject Mfsatype = {
195 OB_HEAD_INIT(&Typetype)
196 0, /*ob_size*/
197 "Alias", /*tp_name*/
198 sizeof(mfsaobject), /*tp_basicsize*/
199 0, /*tp_itemsize*/
200 /* methods */
201 (destructor)mfsa_dealloc, /*tp_dealloc*/
202 (printfunc)0, /*tp_print*/
203 (getattrfunc)mfsa_getattr, /*tp_getattr*/
204 (setattrfunc)0, /*tp_setattr*/
205 (cmpfunc)0, /*tp_compare*/
206 (reprfunc)0, /*tp_repr*/
207 0, /*tp_as_number*/
208 0, /*tp_as_sequence*/
209 0, /*tp_as_mapping*/
210 (hashfunc)0, /*tp_hash*/
211};
212
213/* End of code for Alias objects */
214/* -------------------------------------------------------- */
215
216/*
217** Helper routine for other modules: return an FSSpec * if the
218** object is a python fsspec object, else NULL
219*/
220FSSpec *
221mfs_GetFSSpecFSSpec(self)
222 object *self;
223{
224 if ( is_mfssobject(self) )
225 return &((mfssobject *)self)->fsspec;
226 return NULL;
227}
228
229static object *
230mfss_as_pathname(self, args)
231 mfssobject *self;
232 object *args;
233{
234 char strbuf[257];
235 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000236
237 if (!newgetargs(args, ""))
238 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000239 err = nfullpath(&self->fsspec, strbuf);
240 if ( err ) {
241 PyErr_Mac(ErrorObject, err);
242 return NULL;
243 }
244 return newstringobject(strbuf);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000245}
246
247static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000248mfss_as_tuple(self, args)
249 mfssobject *self;
250 object *args;
251{
252 if (!newgetargs(args, ""))
253 return NULL;
254 return Py_BuildValue("(iis#)", self->fsspec.vRefNum, self->fsspec.parID,
255 &self->fsspec.name[1], self->fsspec.name[0]);
256}
257
258static object *
259mfss_NewAlias(self, args)
260 mfssobject *self;
261 object *args;
262{
263 FSSpec src, *srcp;
264 OSErr err;
265 AliasHandle alias;
266
267 src.name[0] = 0;
268 if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &src))
269 return NULL;
270 if ( src.name[0] )
271 srcp = &src;
272 else
273 srcp = NULL;
274 err = NewAlias(srcp, &self->fsspec, &alias);
275 if ( err ) {
276 PyErr_Mac(ErrorObject, err);
277 return NULL;
278 }
279
280 return (object *)newmfsaobject(alias);
281}
282
283static object *
284mfss_NewAliasMinimal(self, args)
285 mfssobject *self;
286 object *args;
287{
288 OSErr err;
289 AliasHandle alias;
290
291 if (!newgetargs(args, ""))
292 return NULL;
293 err = NewAliasMinimal(&self->fsspec, &alias);
294 if ( err ) {
295 PyErr_Mac(ErrorObject, err);
296 return NULL;
297 }
298 return (object *)newmfsaobject(alias);
299}
300
Jack Jansen8828fcf1995-02-02 14:23:52 +0000301/* XXXX These routines should be replaced with a complete interface to *FInfo */
302static object *
303mfss_GetCreatorType(self, args)
304 mfssobject *self;
305 object *args;
306{
307 OSErr err;
308 FInfo info;
309
310 if (!newgetargs(args, ""))
311 return NULL;
312 err = FSpGetFInfo(&self->fsspec, &info);
313 if ( err ) {
314 PyErr_Mac(ErrorObject, err);
315 return NULL;
316 }
317 return Py_BuildValue("(O&O&)",
318 PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType);
319}
320
321static object *
322mfss_SetCreatorType(self, args)
323 mfssobject *self;
324 object *args;
325{
326 OSErr err;
327 OSType creator, type;
328 FInfo info;
329
330 if (!newgetargs(args, "O&O&", PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
331 return NULL;
332 err = FSpGetFInfo(&self->fsspec, &info);
333 if ( err ) {
334 PyErr_Mac(ErrorObject, err);
335 return NULL;
336 }
337 info.fdType = type;
338 info.fdCreator = creator;
339 err = FSpSetFInfo(&self->fsspec, &info);
340 if ( err ) {
341 PyErr_Mac(ErrorObject, err);
342 return NULL;
343 }
344 INCREF(None);
345 return None;
346}
347
Jack Jansen17ba43f1995-01-26 16:22:07 +0000348static struct methodlist mfss_methods[] = {
Guido van Rossumefd97671995-01-26 22:56:16 +0000349 {"as_pathname", (method)mfss_as_pathname, 1},
350 {"as_tuple", (method)mfss_as_tuple, 1},
351 {"NewAlias", (method)mfss_NewAlias, 1},
352 {"NewAliasMinimal", (method)mfss_NewAliasMinimal, 1},
Jack Jansen8828fcf1995-02-02 14:23:52 +0000353 {"GetCreatorType", (method)mfss_GetCreatorType, 1},
354 {"SetCreatorType", (method)mfss_SetCreatorType, 1},
Jack Jansen17ba43f1995-01-26 16:22:07 +0000355
356 {NULL, NULL} /* sentinel */
357};
358
359/* ---------- */
360
361static object *
362mfss_getattr(self, name)
363 mfssobject *self;
364 char *name;
365{
Jack Jansenc889b761995-02-13 12:00:46 +0000366 if ( strcmp(name, "data") == 0)
367 return PyString_FromStringAndSize((char *)&self->fsspec, sizeof(FSSpec));
Jack Jansen17ba43f1995-01-26 16:22:07 +0000368 return findmethod(mfss_methods, (object *)self, name);
369}
370
371mfssobject *
372newmfssobject(fss)
373 FSSpec *fss;
374{
375 mfssobject *self;
376
377 self = NEWOBJ(mfssobject, &Mfsstype);
378 if (self == NULL)
379 return NULL;
380 self->fsspec = *fss;
381 return self;
382}
383
384static void
385mfss_dealloc(self)
386 mfssobject *self;
387{
388 DEL(self);
389}
390
391static object *
392mfss_repr(self)
393 mfssobject *self;
394{
395 char buf[512];
396
397 /* XXXX Does %#s work for all compilers? */
398 sprintf(buf, "FSSpec((%d, %d, '%#s'))", self->fsspec.vRefNum,
399 self->fsspec.parID, self->fsspec.name);
400 return newstringobject(buf);
401}
402
403static int
404mfss_compare(v, w)
405 mfssobject *v, *w;
406{
407 int minlen;
408 int res;
409
410 if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1;
411 if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1;
412 if ( v->fsspec.parID < w->fsspec.parID ) return -1;
413 if ( v->fsspec.parID > w->fsspec.parID ) return 1;
414 minlen = v->fsspec.name[0];
415 if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0];
416 res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen);
417 if ( res ) return res;
418 if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1;
419 if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1;
420 return res;
421}
422
423static typeobject Mfsstype = {
424 OB_HEAD_INIT(&Typetype)
425 0, /*ob_size*/
426 "FSSpec", /*tp_name*/
427 sizeof(mfssobject), /*tp_basicsize*/
428 0, /*tp_itemsize*/
429 /* methods */
430 (destructor)mfss_dealloc, /*tp_dealloc*/
431 (printfunc)0, /*tp_print*/
432 (getattrfunc)mfss_getattr, /*tp_getattr*/
433 (setattrfunc)0, /*tp_setattr*/
434 (cmpfunc)mfss_compare, /*tp_compare*/
435 (reprfunc)mfss_repr, /*tp_repr*/
436 0, /*tp_as_number*/
437 0, /*tp_as_sequence*/
438 0, /*tp_as_mapping*/
439 (hashfunc)0, /*tp_hash*/
440};
441
442/* End of code for FSSpec objects */
443/* -------------------------------------------------------- */
444
445static object *
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000446mfs_ResolveAliasFile(self, args)
447 object *self; /* Not used */
448 object *args;
449{
Jack Jansen17ba43f1995-01-26 16:22:07 +0000450 FSSpec fss;
451 Boolean chain = 1, isfolder, wasaliased;
452 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000453
Jack Jansen17ba43f1995-01-26 16:22:07 +0000454 if (!newgetargs(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000455 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000456 err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
457 if ( err ) {
458 PyErr_Mac(ErrorObject, err);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000459 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000460 }
461 return mkvalue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000462}
463
464static object *
465mfs_StandardGetFile(self, args)
466 object *self; /* Not used */
467 object *args;
468{
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000469 SFTypeList list;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000470 short numtypes;
471 StandardFileReply reply;
472
473 list[0] = list[1] = list[2] = list[3] = 0;
474 numtypes = 0;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000475 if (!newgetargs(args, "|O&O&O&O&", PyMac_GetOSType, &list[0],
Jack Jansen17ba43f1995-01-26 16:22:07 +0000476 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
477 PyMac_GetOSType, &list[3]) )
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000478 return NULL;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000479 while ( numtypes < 4 && list[numtypes] ) {
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000480 numtypes++;
481 }
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000482 StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
Jack Jansen17ba43f1995-01-26 16:22:07 +0000483 return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000484}
485
486static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000487mfs_StandardPutFile(self, args)
488 object *self; /* Not used */
489 object *args;
490{
491 Str255 prompt, dft;
492 StandardFileReply reply;
493
494 dft[0] = 0;
495 if (!newgetargs(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
496 return NULL;
497 StandardPutFile(prompt, dft, &reply);
498 return mkvalue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
499}
500
501static object *
502mfs_FSSpec(self, args)
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000503 object *self; /* Not used */
504 object *args;
505{
506 FSSpec fss;
507
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000508 if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000509 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000510 return (object *)newmfssobject(&fss);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000511}
512
Jack Jansenc889b761995-02-13 12:00:46 +0000513static object *
514mfs_RawFSSpec(self, args)
515 object *self; /* Not used */
516 object *args;
517{
518 FSSpec *fssp;
519 int size;
520
521 if (!newgetargs(args, "s#", &fssp, &size))
522 return NULL;
523 if ( size != sizeof(FSSpec) ) {
524 PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record");
525 return NULL;
526 }
527 return (object *)newmfssobject(fssp);
528}
529
530static object *
531mfs_RawAlias(self, args)
532 object *self; /* Not used */
533 object *args;
534{
535 char *dataptr;
536 Handle h;
537 int size;
538
539 if (!newgetargs(args, "s#", &dataptr, &size))
540 return NULL;
541 h = NewHandle(size);
542 if ( h == NULL ) {
543 PyErr_NoMemory();
544 return NULL;
545 }
546 HLock(h);
547 memcpy((char *)*h, dataptr, size);
548 HUnlock(h);
549 return (object *)newmfsaobject((AliasHandle)h);
550}
551
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000552/* List of methods defined in the module */
553
554static struct methodlist mfs_methods[] = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000555 {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
556 {"StandardGetFile", mfs_StandardGetFile, 1},
557 {"StandardPutFile", mfs_StandardPutFile, 1},
558 {"FSSpec", mfs_FSSpec, 1},
Jack Jansenc889b761995-02-13 12:00:46 +0000559 {"RawFSSpec", mfs_RawFSSpec, 1},
560 {"RawAlias", mfs_RawAlias, 1},
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000561
562 {NULL, NULL} /* sentinel */
563};
564
565
566/* Initialization function for the module (*must* be called initmacfs) */
567
568void
569initmacfs()
570{
571 object *m, *d;
572
573 /* Create the module and add the functions */
574 m = initmodule("macfs", mfs_methods);
575
576 /* Add some symbolic constants to the module */
577 d = getmoduledict(m);
578 ErrorObject = newstringobject("macfs.error");
579 dictinsert(d, "error", ErrorObject);
580
581 /* XXXX Add constants here */
582
583 /* Check for errors */
584 if (err_occurred())
585 fatal("can't initialize module macfs");
586}