blob: 21836859ec9e3209d989a9397d4ce7744aeb9454 [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
291static struct methodlist mfss_methods[] = {
Guido van Rossumefd97671995-01-26 22:56:16 +0000292 {"as_pathname", (method)mfss_as_pathname, 1},
293 {"as_tuple", (method)mfss_as_tuple, 1},
294 {"NewAlias", (method)mfss_NewAlias, 1},
295 {"NewAliasMinimal", (method)mfss_NewAliasMinimal, 1},
Jack Jansen17ba43f1995-01-26 16:22:07 +0000296
297 {NULL, NULL} /* sentinel */
298};
299
300/* ---------- */
301
302static object *
303mfss_getattr(self, name)
304 mfssobject *self;
305 char *name;
306{
307 return findmethod(mfss_methods, (object *)self, name);
308}
309
310mfssobject *
311newmfssobject(fss)
312 FSSpec *fss;
313{
314 mfssobject *self;
315
316 self = NEWOBJ(mfssobject, &Mfsstype);
317 if (self == NULL)
318 return NULL;
319 self->fsspec = *fss;
320 return self;
321}
322
323static void
324mfss_dealloc(self)
325 mfssobject *self;
326{
327 DEL(self);
328}
329
330static object *
331mfss_repr(self)
332 mfssobject *self;
333{
334 char buf[512];
335
336 /* XXXX Does %#s work for all compilers? */
337 sprintf(buf, "FSSpec((%d, %d, '%#s'))", self->fsspec.vRefNum,
338 self->fsspec.parID, self->fsspec.name);
339 return newstringobject(buf);
340}
341
342static int
343mfss_compare(v, w)
344 mfssobject *v, *w;
345{
346 int minlen;
347 int res;
348
349 if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1;
350 if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1;
351 if ( v->fsspec.parID < w->fsspec.parID ) return -1;
352 if ( v->fsspec.parID > w->fsspec.parID ) return 1;
353 minlen = v->fsspec.name[0];
354 if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0];
355 res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen);
356 if ( res ) return res;
357 if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1;
358 if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1;
359 return res;
360}
361
362static typeobject Mfsstype = {
363 OB_HEAD_INIT(&Typetype)
364 0, /*ob_size*/
365 "FSSpec", /*tp_name*/
366 sizeof(mfssobject), /*tp_basicsize*/
367 0, /*tp_itemsize*/
368 /* methods */
369 (destructor)mfss_dealloc, /*tp_dealloc*/
370 (printfunc)0, /*tp_print*/
371 (getattrfunc)mfss_getattr, /*tp_getattr*/
372 (setattrfunc)0, /*tp_setattr*/
373 (cmpfunc)mfss_compare, /*tp_compare*/
374 (reprfunc)mfss_repr, /*tp_repr*/
375 0, /*tp_as_number*/
376 0, /*tp_as_sequence*/
377 0, /*tp_as_mapping*/
378 (hashfunc)0, /*tp_hash*/
379};
380
381/* End of code for FSSpec objects */
382/* -------------------------------------------------------- */
383
384static object *
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000385mfs_ResolveAliasFile(self, args)
386 object *self; /* Not used */
387 object *args;
388{
Jack Jansen17ba43f1995-01-26 16:22:07 +0000389 FSSpec fss;
390 Boolean chain = 1, isfolder, wasaliased;
391 OSErr err;
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000392
Jack Jansen17ba43f1995-01-26 16:22:07 +0000393 if (!newgetargs(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000394 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000395 err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
396 if ( err ) {
397 PyErr_Mac(ErrorObject, err);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000398 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000399 }
400 return mkvalue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000401}
402
403static object *
404mfs_StandardGetFile(self, args)
405 object *self; /* Not used */
406 object *args;
407{
408 char *list[4];
409 SFTypeList typelist;
410 short numtypes;
411 StandardFileReply reply;
412
413 list[0] = list[1] = list[2] = list[3] = 0;
414 numtypes = 0;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000415#if 0
416 /* XXXX Why doesn't this work? */
417 if (!newgetargs(args, "|O&|O&|O&|O&", PyMac_GetOSType, &list[0],
418 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
419 PyMac_GetOSType, &list[3]) )
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000420 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000421#else
422 if (!newgetargs(args, "|O&", PyMac_GetOSType, &list[0]) )
423 return NULL;
424#endif
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000425 while ( list[numtypes] && numtypes < 4 ) {
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000426 numtypes++;
427 }
428 StandardGetFile((FileFilterUPP)0, numtypes, typelist, &reply);
Jack Jansen17ba43f1995-01-26 16:22:07 +0000429 return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000430}
431
432static object *
Jack Jansen17ba43f1995-01-26 16:22:07 +0000433mfs_StandardPutFile(self, args)
434 object *self; /* Not used */
435 object *args;
436{
437 Str255 prompt, dft;
438 StandardFileReply reply;
439
440 dft[0] = 0;
441 if (!newgetargs(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
442 return NULL;
443 StandardPutFile(prompt, dft, &reply);
444 return mkvalue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
445}
446
447static object *
448mfs_FSSpec(self, args)
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000449 object *self; /* Not used */
450 object *args;
451{
452 FSSpec fss;
453
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000454 if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss))
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000455 return NULL;
Jack Jansen17ba43f1995-01-26 16:22:07 +0000456 return (object *)newmfssobject(&fss);
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000457}
458
459/* List of methods defined in the module */
460
461static struct methodlist mfs_methods[] = {
Jack Jansen17ba43f1995-01-26 16:22:07 +0000462 {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
463 {"StandardGetFile", mfs_StandardGetFile, 1},
464 {"StandardPutFile", mfs_StandardPutFile, 1},
465 {"FSSpec", mfs_FSSpec, 1},
Jack Jansen84fa5ec1995-01-18 14:04:40 +0000466
467 {NULL, NULL} /* sentinel */
468};
469
470
471/* Initialization function for the module (*must* be called initmacfs) */
472
473void
474initmacfs()
475{
476 object *m, *d;
477
478 /* Create the module and add the functions */
479 m = initmodule("macfs", mfs_methods);
480
481 /* Add some symbolic constants to the module */
482 d = getmoduledict(m);
483 ErrorObject = newstringobject("macfs.error");
484 dictinsert(d, "error", ErrorObject);
485
486 /* XXXX Add constants here */
487
488 /* Check for errors */
489 if (err_occurred())
490 fatal("can't initialize module macfs");
491}