blob: e1ba4e173800894020992cea7f434c61faf63c74 [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
Guido van Rossumbecdbec1995-02-14 01:27:24 +000029#include <Memory.h>
Jack Jansen84fa5ec1995-01-18 14:04:40 +000030#include <Files.h>
31#include <StandardFile.h>
32#include <Aliases.h>
33
34#include "nfullpath.h"
35
Guido van Rossuma42960c1995-01-19 00:03:47 +000036#ifdef THINK_C
37#define FileFilterUPP FileFilterProcPtr
38#endif
39
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
Guido van Rossumf45b53b1995-02-20 23:43:29 +0000194statichere typeobject Mfsatype = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000195 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*/
Guido van Rossumf45b53b1995-02-20 23:43:29 +0000202 (printfunc)0, /*tp_print*/
Jack Jansen17ba43f1995-01-26 16:22:07 +0000203 (getattrfunc)mfsa_getattr, /*tp_getattr*/
Guido van Rossumf45b53b1995-02-20 23:43:29 +0000204 (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*/
Jack Jansen17ba43f1995-01-26 16:22:07 +0000211};
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
Guido van Rossumf45b53b1995-02-20 23:43:29 +0000397 sprintf(buf, "FSSpec((%d, %d, '%.*s'))",
398 self->fsspec.vRefNum,
399 self->fsspec.parID,
400 self->fsspec.name[0], self->fsspec.name+1);
Jack Jansen17ba43f1995-01-26 16:22:07 +0000401 return newstringobject(buf);
402}
403
404static int
405mfss_compare(v, w)
406 mfssobject *v, *w;
407{
408 int minlen;
409 int res;
410
411 if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1;
412 if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1;
413 if ( v->fsspec.parID < w->fsspec.parID ) return -1;
414 if ( v->fsspec.parID > w->fsspec.parID ) return 1;
415 minlen = v->fsspec.name[0];
416 if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0];
417 res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen);
418 if ( res ) return res;
419 if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1;
420 if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1;
421 return res;
422}
423
Guido van Rossumf45b53b1995-02-20 23:43:29 +0000424statichere typeobject Mfsstype = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000425 OB_HEAD_INIT(&Typetype)
426 0, /*ob_size*/
427 "FSSpec", /*tp_name*/
428 sizeof(mfssobject), /*tp_basicsize*/
429 0, /*tp_itemsize*/
430 /* methods */
431 (destructor)mfss_dealloc, /*tp_dealloc*/
432 (printfunc)0, /*tp_print*/
433 (getattrfunc)mfss_getattr, /*tp_getattr*/
434 (setattrfunc)0, /*tp_setattr*/
435 (cmpfunc)mfss_compare, /*tp_compare*/
436 (reprfunc)mfss_repr, /*tp_repr*/
437 0, /*tp_as_number*/
438 0, /*tp_as_sequence*/
439 0, /*tp_as_mapping*/
440 (hashfunc)0, /*tp_hash*/
441};
442
443/* End of code for FSSpec objects */
444/* -------------------------------------------------------- */
445
446static object *
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000447mfs_ResolveAliasFile(self, args)
448 object *self; /* Not used */
449 object *args;
450{
Jack Jansen17ba43f1995-01-26 16:22:07 +0000451 FSSpec fss;
452 Boolean chain = 1, isfolder, wasaliased;
453 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000454
Jack Jansen17ba43f1995-01-26 16:22:07 +0000455 if (!newgetargs(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000456 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000457 err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
458 if ( err ) {
459 PyErr_Mac(ErrorObject, err);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000460 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000461 }
462 return mkvalue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000463}
464
465static object *
466mfs_StandardGetFile(self, args)
467 object *self; /* Not used */
468 object *args;
469{
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000470 SFTypeList list;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000471 short numtypes;
472 StandardFileReply reply;
473
474 list[0] = list[1] = list[2] = list[3] = 0;
475 numtypes = 0;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000476 if (!newgetargs(args, "|O&O&O&O&", PyMac_GetOSType, &list[0],
Jack Jansen17ba43f1995-01-26 16:22:07 +0000477 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
478 PyMac_GetOSType, &list[3]) )
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000479 return NULL;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000480 while ( numtypes < 4 && list[numtypes] ) {
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000481 numtypes++;
482 }
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000483 StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
Jack Jansen17ba43f1995-01-26 16:22:07 +0000484 return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000485}
486
487static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000488mfs_StandardPutFile(self, args)
489 object *self; /* Not used */
490 object *args;
491{
492 Str255 prompt, dft;
493 StandardFileReply reply;
494
495 dft[0] = 0;
496 if (!newgetargs(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
497 return NULL;
498 StandardPutFile(prompt, dft, &reply);
499 return mkvalue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
500}
501
502static object *
503mfs_FSSpec(self, args)
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000504 object *self; /* Not used */
505 object *args;
506{
507 FSSpec fss;
508
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000509 if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000510 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000511 return (object *)newmfssobject(&fss);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000512}
513
Jack Jansenc889b761995-02-13 12:00:46 +0000514static object *
515mfs_RawFSSpec(self, args)
516 object *self; /* Not used */
517 object *args;
518{
519 FSSpec *fssp;
520 int size;
521
522 if (!newgetargs(args, "s#", &fssp, &size))
523 return NULL;
524 if ( size != sizeof(FSSpec) ) {
525 PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record");
526 return NULL;
527 }
528 return (object *)newmfssobject(fssp);
529}
530
531static object *
532mfs_RawAlias(self, args)
533 object *self; /* Not used */
534 object *args;
535{
536 char *dataptr;
537 Handle h;
538 int size;
539
540 if (!newgetargs(args, "s#", &dataptr, &size))
541 return NULL;
542 h = NewHandle(size);
543 if ( h == NULL ) {
544 PyErr_NoMemory();
545 return NULL;
546 }
547 HLock(h);
548 memcpy((char *)*h, dataptr, size);
549 HUnlock(h);
550 return (object *)newmfsaobject((AliasHandle)h);
551}
552
Jack Jansen81f51c71995-02-20 15:45:25 +0000553static object *
554mfs_GetDirectory(self, args)
555 object *self; /* Not used */
556 object *args;
557{
558 FSSpec fsdir;
559 int ok;
560
561 if (!newgetargs(args, "") )
562 return NULL;
563
564 ok = PyMac_GetDirectory(&fsdir);
565 return mkvalue("(Oi)", newmfssobject(&fsdir), ok);
566}
567
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000568/* List of methods defined in the module */
569
570static struct methodlist mfs_methods[] = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000571 {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
572 {"StandardGetFile", mfs_StandardGetFile, 1},
573 {"StandardPutFile", mfs_StandardPutFile, 1},
Jack Jansen81f51c71995-02-20 15:45:25 +0000574 {"GetDirectory", mfs_GetDirectory, 1},
Jack Jansen17ba43f1995-01-26 16:22:07 +0000575 {"FSSpec", mfs_FSSpec, 1},
Jack Jansenc889b761995-02-13 12:00:46 +0000576 {"RawFSSpec", mfs_RawFSSpec, 1},
577 {"RawAlias", mfs_RawAlias, 1},
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000578
579 {NULL, NULL} /* sentinel */
580};
581
582
583/* Initialization function for the module (*must* be called initmacfs) */
584
585void
586initmacfs()
587{
588 object *m, *d;
589
590 /* Create the module and add the functions */
591 m = initmodule("macfs", mfs_methods);
592
593 /* Add some symbolic constants to the module */
594 d = getmoduledict(m);
595 ErrorObject = newstringobject("macfs.error");
596 dictinsert(d, "error", ErrorObject);
597
598 /* XXXX Add constants here */
599
600 /* Check for errors */
601 if (err_occurred())
602 fatal("can't initialize module macfs");
603}