blob: 0d75d44361cbffb3357882be92e1c8918b9cd3e0 [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 }
Jack Jansenc2632861995-06-03 21:15:50 +0000483 if ( numtypes == 0 )
484 numtypes = -1;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000485 StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
Jack Jansen17ba43f1995-01-26 16:22:07 +0000486 return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000487}
488
489static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000490mfs_StandardPutFile(self, args)
491 object *self; /* Not used */
492 object *args;
493{
494 Str255 prompt, dft;
495 StandardFileReply reply;
496
497 dft[0] = 0;
498 if (!newgetargs(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
499 return NULL;
500 StandardPutFile(prompt, dft, &reply);
501 return mkvalue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
502}
503
504static object *
505mfs_FSSpec(self, args)
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000506 object *self; /* Not used */
507 object *args;
508{
509 FSSpec fss;
510
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000511 if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000512 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000513 return (object *)newmfssobject(&fss);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000514}
515
Jack Jansenc889b761995-02-13 12:00:46 +0000516static object *
517mfs_RawFSSpec(self, args)
518 object *self; /* Not used */
519 object *args;
520{
521 FSSpec *fssp;
522 int size;
523
524 if (!newgetargs(args, "s#", &fssp, &size))
525 return NULL;
526 if ( size != sizeof(FSSpec) ) {
527 PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record");
528 return NULL;
529 }
530 return (object *)newmfssobject(fssp);
531}
532
533static object *
534mfs_RawAlias(self, args)
535 object *self; /* Not used */
536 object *args;
537{
538 char *dataptr;
539 Handle h;
540 int size;
541
542 if (!newgetargs(args, "s#", &dataptr, &size))
543 return NULL;
544 h = NewHandle(size);
545 if ( h == NULL ) {
546 PyErr_NoMemory();
547 return NULL;
548 }
549 HLock(h);
550 memcpy((char *)*h, dataptr, size);
551 HUnlock(h);
552 return (object *)newmfsaobject((AliasHandle)h);
553}
554
Jack Jansen81f51c71995-02-20 15:45:25 +0000555static object *
556mfs_GetDirectory(self, args)
557 object *self; /* Not used */
558 object *args;
559{
560 FSSpec fsdir;
561 int ok;
562
563 if (!newgetargs(args, "") )
564 return NULL;
565
566 ok = PyMac_GetDirectory(&fsdir);
567 return mkvalue("(Oi)", newmfssobject(&fsdir), ok);
568}
569
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000570/* List of methods defined in the module */
571
572static struct methodlist mfs_methods[] = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000573 {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
574 {"StandardGetFile", mfs_StandardGetFile, 1},
575 {"StandardPutFile", mfs_StandardPutFile, 1},
Jack Jansen81f51c71995-02-20 15:45:25 +0000576 {"GetDirectory", mfs_GetDirectory, 1},
Jack Jansen17ba43f1995-01-26 16:22:07 +0000577 {"FSSpec", mfs_FSSpec, 1},
Jack Jansenc889b761995-02-13 12:00:46 +0000578 {"RawFSSpec", mfs_RawFSSpec, 1},
579 {"RawAlias", mfs_RawAlias, 1},
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000580
581 {NULL, NULL} /* sentinel */
582};
583
584
585/* Initialization function for the module (*must* be called initmacfs) */
586
587void
588initmacfs()
589{
590 object *m, *d;
591
592 /* Create the module and add the functions */
593 m = initmodule("macfs", mfs_methods);
594
595 /* Add some symbolic constants to the module */
596 d = getmoduledict(m);
597 ErrorObject = newstringobject("macfs.error");
598 dictinsert(d, "error", ErrorObject);
599
600 /* XXXX Add constants here */
601
602 /* Check for errors */
603 if (err_occurred())
604 fatal("can't initialize module macfs");
605}