blob: d8f454c590aab4451e3f471e64c605fb518b5ba6 [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{
154 return findmethod(mfsa_methods, (object *)self, name);
155}
156
157mfsaobject *
158newmfsaobject(alias)
159 AliasHandle alias;
160{
161 mfsaobject *self;
162
163 self = NEWOBJ(mfsaobject, &Mfsatype);
164 if (self == NULL)
165 return NULL;
166 self->alias = alias;
167 return self;
168}
169
170
171static void
172mfsa_dealloc(self)
173 mfsaobject *self;
174{
175#if 0
176 if ( self->alias ) {
177 should we do something here?
178 }
179#endif
180
181 DEL(self);
182}
183
184static typeobject Mfsatype = {
185 OB_HEAD_INIT(&Typetype)
186 0, /*ob_size*/
187 "Alias", /*tp_name*/
188 sizeof(mfsaobject), /*tp_basicsize*/
189 0, /*tp_itemsize*/
190 /* methods */
191 (destructor)mfsa_dealloc, /*tp_dealloc*/
192 (printfunc)0, /*tp_print*/
193 (getattrfunc)mfsa_getattr, /*tp_getattr*/
194 (setattrfunc)0, /*tp_setattr*/
195 (cmpfunc)0, /*tp_compare*/
196 (reprfunc)0, /*tp_repr*/
197 0, /*tp_as_number*/
198 0, /*tp_as_sequence*/
199 0, /*tp_as_mapping*/
200 (hashfunc)0, /*tp_hash*/
201};
202
203/* End of code for Alias objects */
204/* -------------------------------------------------------- */
205
206/*
207** Helper routine for other modules: return an FSSpec * if the
208** object is a python fsspec object, else NULL
209*/
210FSSpec *
211mfs_GetFSSpecFSSpec(self)
212 object *self;
213{
214 if ( is_mfssobject(self) )
215 return &((mfssobject *)self)->fsspec;
216 return NULL;
217}
218
219static object *
220mfss_as_pathname(self, args)
221 mfssobject *self;
222 object *args;
223{
224 char strbuf[257];
225 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000226
227 if (!newgetargs(args, ""))
228 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000229 err = nfullpath(&self->fsspec, strbuf);
230 if ( err ) {
231 PyErr_Mac(ErrorObject, err);
232 return NULL;
233 }
234 return newstringobject(strbuf);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000235}
236
237static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000238mfss_as_tuple(self, args)
239 mfssobject *self;
240 object *args;
241{
242 if (!newgetargs(args, ""))
243 return NULL;
244 return Py_BuildValue("(iis#)", self->fsspec.vRefNum, self->fsspec.parID,
245 &self->fsspec.name[1], self->fsspec.name[0]);
246}
247
248static object *
249mfss_NewAlias(self, args)
250 mfssobject *self;
251 object *args;
252{
253 FSSpec src, *srcp;
254 OSErr err;
255 AliasHandle alias;
256
257 src.name[0] = 0;
258 if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &src))
259 return NULL;
260 if ( src.name[0] )
261 srcp = &src;
262 else
263 srcp = NULL;
264 err = NewAlias(srcp, &self->fsspec, &alias);
265 if ( err ) {
266 PyErr_Mac(ErrorObject, err);
267 return NULL;
268 }
269
270 return (object *)newmfsaobject(alias);
271}
272
273static object *
274mfss_NewAliasMinimal(self, args)
275 mfssobject *self;
276 object *args;
277{
278 OSErr err;
279 AliasHandle alias;
280
281 if (!newgetargs(args, ""))
282 return NULL;
283 err = NewAliasMinimal(&self->fsspec, &alias);
284 if ( err ) {
285 PyErr_Mac(ErrorObject, err);
286 return NULL;
287 }
288 return (object *)newmfsaobject(alias);
289}
290
Jack Jansen8828fcf1995-02-02 14:23:52 +0000291/* XXXX These routines should be replaced with a complete interface to *FInfo */
292static object *
293mfss_GetCreatorType(self, args)
294 mfssobject *self;
295 object *args;
296{
297 OSErr err;
298 FInfo info;
299
300 if (!newgetargs(args, ""))
301 return NULL;
302 err = FSpGetFInfo(&self->fsspec, &info);
303 if ( err ) {
304 PyErr_Mac(ErrorObject, err);
305 return NULL;
306 }
307 return Py_BuildValue("(O&O&)",
308 PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType);
309}
310
311static object *
312mfss_SetCreatorType(self, args)
313 mfssobject *self;
314 object *args;
315{
316 OSErr err;
317 OSType creator, type;
318 FInfo info;
319
320 if (!newgetargs(args, "O&O&", PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
321 return NULL;
322 err = FSpGetFInfo(&self->fsspec, &info);
323 if ( err ) {
324 PyErr_Mac(ErrorObject, err);
325 return NULL;
326 }
327 info.fdType = type;
328 info.fdCreator = creator;
329 err = FSpSetFInfo(&self->fsspec, &info);
330 if ( err ) {
331 PyErr_Mac(ErrorObject, err);
332 return NULL;
333 }
334 INCREF(None);
335 return None;
336}
337
Jack Jansen17ba43f1995-01-26 16:22:07 +0000338static struct methodlist mfss_methods[] = {
Guido van Rossumefd97671995-01-26 22:56:16 +0000339 {"as_pathname", (method)mfss_as_pathname, 1},
340 {"as_tuple", (method)mfss_as_tuple, 1},
341 {"NewAlias", (method)mfss_NewAlias, 1},
342 {"NewAliasMinimal", (method)mfss_NewAliasMinimal, 1},
Jack Jansen8828fcf1995-02-02 14:23:52 +0000343 {"GetCreatorType", (method)mfss_GetCreatorType, 1},
344 {"SetCreatorType", (method)mfss_SetCreatorType, 1},
Jack Jansen17ba43f1995-01-26 16:22:07 +0000345
346 {NULL, NULL} /* sentinel */
347};
348
349/* ---------- */
350
351static object *
352mfss_getattr(self, name)
353 mfssobject *self;
354 char *name;
355{
356 return findmethod(mfss_methods, (object *)self, name);
357}
358
359mfssobject *
360newmfssobject(fss)
361 FSSpec *fss;
362{
363 mfssobject *self;
364
365 self = NEWOBJ(mfssobject, &Mfsstype);
366 if (self == NULL)
367 return NULL;
368 self->fsspec = *fss;
369 return self;
370}
371
372static void
373mfss_dealloc(self)
374 mfssobject *self;
375{
376 DEL(self);
377}
378
379static object *
380mfss_repr(self)
381 mfssobject *self;
382{
383 char buf[512];
384
385 /* XXXX Does %#s work for all compilers? */
386 sprintf(buf, "FSSpec((%d, %d, '%#s'))", self->fsspec.vRefNum,
387 self->fsspec.parID, self->fsspec.name);
388 return newstringobject(buf);
389}
390
391static int
392mfss_compare(v, w)
393 mfssobject *v, *w;
394{
395 int minlen;
396 int res;
397
398 if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1;
399 if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1;
400 if ( v->fsspec.parID < w->fsspec.parID ) return -1;
401 if ( v->fsspec.parID > w->fsspec.parID ) return 1;
402 minlen = v->fsspec.name[0];
403 if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0];
404 res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen);
405 if ( res ) return res;
406 if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1;
407 if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1;
408 return res;
409}
410
411static typeobject Mfsstype = {
412 OB_HEAD_INIT(&Typetype)
413 0, /*ob_size*/
414 "FSSpec", /*tp_name*/
415 sizeof(mfssobject), /*tp_basicsize*/
416 0, /*tp_itemsize*/
417 /* methods */
418 (destructor)mfss_dealloc, /*tp_dealloc*/
419 (printfunc)0, /*tp_print*/
420 (getattrfunc)mfss_getattr, /*tp_getattr*/
421 (setattrfunc)0, /*tp_setattr*/
422 (cmpfunc)mfss_compare, /*tp_compare*/
423 (reprfunc)mfss_repr, /*tp_repr*/
424 0, /*tp_as_number*/
425 0, /*tp_as_sequence*/
426 0, /*tp_as_mapping*/
427 (hashfunc)0, /*tp_hash*/
428};
429
430/* End of code for FSSpec objects */
431/* -------------------------------------------------------- */
432
433static object *
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000434mfs_ResolveAliasFile(self, args)
435 object *self; /* Not used */
436 object *args;
437{
Jack Jansen17ba43f1995-01-26 16:22:07 +0000438 FSSpec fss;
439 Boolean chain = 1, isfolder, wasaliased;
440 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000441
Jack Jansen17ba43f1995-01-26 16:22:07 +0000442 if (!newgetargs(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000443 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000444 err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
445 if ( err ) {
446 PyErr_Mac(ErrorObject, err);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000447 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000448 }
449 return mkvalue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000450}
451
452static object *
453mfs_StandardGetFile(self, args)
454 object *self; /* Not used */
455 object *args;
456{
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000457 SFTypeList list;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000458 short numtypes;
459 StandardFileReply reply;
460
461 list[0] = list[1] = list[2] = list[3] = 0;
462 numtypes = 0;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000463 if (!newgetargs(args, "|O&O&O&O&", PyMac_GetOSType, &list[0],
Jack Jansen17ba43f1995-01-26 16:22:07 +0000464 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
465 PyMac_GetOSType, &list[3]) )
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000466 return NULL;
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000467 while ( numtypes < 4 && list[numtypes] ) {
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000468 numtypes++;
469 }
Guido van Rossumb2f524a1995-01-30 08:56:06 +0000470 StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
Jack Jansen17ba43f1995-01-26 16:22:07 +0000471 return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000472}
473
474static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000475mfs_StandardPutFile(self, args)
476 object *self; /* Not used */
477 object *args;
478{
479 Str255 prompt, dft;
480 StandardFileReply reply;
481
482 dft[0] = 0;
483 if (!newgetargs(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
484 return NULL;
485 StandardPutFile(prompt, dft, &reply);
486 return mkvalue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
487}
488
489static object *
490mfs_FSSpec(self, args)
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000491 object *self; /* Not used */
492 object *args;
493{
494 FSSpec fss;
495
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000496 if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000497 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000498 return (object *)newmfssobject(&fss);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000499}
500
501/* List of methods defined in the module */
502
503static struct methodlist mfs_methods[] = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000504 {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
505 {"StandardGetFile", mfs_StandardGetFile, 1},
506 {"StandardPutFile", mfs_StandardPutFile, 1},
507 {"FSSpec", mfs_FSSpec, 1},
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000508
509 {NULL, NULL} /* sentinel */
510};
511
512
513/* Initialization function for the module (*must* be called initmacfs) */
514
515void
516initmacfs()
517{
518 object *m, *d;
519
520 /* Create the module and add the functions */
521 m = initmodule("macfs", mfs_methods);
522
523 /* Add some symbolic constants to the module */
524 d = getmoduledict(m);
525 ErrorObject = newstringobject("macfs.error");
526 dictinsert(d, "error", ErrorObject);
527
528 /* XXXX Add constants here */
529
530 /* Check for errors */
531 if (err_occurred())
532 fatal("can't initialize module macfs");
533}