(py-outdent-p): new function
[python/dscho.git] / Mac / Modules / macfsmodule.c
blobe1ba4e173800894020992cea7f434c61faf63c74
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 #include "allobjects.h"
26 #include "modsupport.h" /* For getargs() etc. */
27 #include "macglue.h"
29 #include <Memory.h>
30 #include <Files.h>
31 #include <StandardFile.h>
32 #include <Aliases.h>
34 #include "nfullpath.h"
36 #ifdef THINK_C
37 #define FileFilterUPP FileFilterProcPtr
38 #endif
40 static object *ErrorObject;
42 /* ----------------------------------------------------- */
43 /* Declarations for objects of type Alias */
45 typedef struct {
46 OB_HEAD
47 AliasHandle alias;
48 } mfsaobject;
50 staticforward typeobject Mfsatype;
52 #define is_mfsaobject(v) ((v)->ob_type == &Mfsatype)
54 /* ---------------------------------------------------------------- */
55 /* Declarations for objects of type FSSpec */
57 typedef struct {
58 OB_HEAD
59 FSSpec fsspec;
60 } mfssobject;
62 staticforward typeobject Mfsstype;
64 #define is_mfssobject(v) ((v)->ob_type == &Mfsstype)
67 mfssobject *newmfssobject(FSSpec *fss); /* Forward */
69 /* ---------------------------------------------------------------- */
71 static object *
72 mfsa_Resolve(self, args)
73 mfsaobject *self;
74 object *args;
76 FSSpec from, *fromp, result;
77 Boolean changed;
78 OSErr err;
80 from.name[0] = 0;
81 if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &from))
82 return NULL;
83 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;
92 return mkvalue("(Oi)", newmfssobject(&result), (int)changed);
95 static object *
96 mfsa_GetInfo(self, args)
97 mfsaobject *self;
98 object *args;
100 Str63 value;
101 int i;
102 OSErr err;
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;
111 return newsizedstringobject((char *)&value[1], value[0]);
114 static object *
115 mfsa_Update(self, args)
116 mfsaobject *self;
117 object *args;
119 FSSpec target, fromfile, *fromfilep;
120 OSErr err;
121 Boolean changed;
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;
136 return mkvalue("i", (int)changed);
139 static struct methodlist mfsa_methods[] = {
140 {"Resolve", (method)mfsa_Resolve, 1},
141 {"GetInfo", (method)mfsa_GetInfo, 1},
142 {"Update", (method)mfsa_Update, 1},
144 {NULL, NULL} /* sentinel */
147 /* ---------- */
149 static object *
150 mfsa_getattr(self, name)
151 mfsaobject *self;
152 char *name;
154 if ( strcmp(name, "data") == 0 ) {
155 int size;
156 PyObject *rv;
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;
164 return findmethod(mfsa_methods, (object *)self, name);
167 mfsaobject *
168 newmfsaobject(alias)
169 AliasHandle alias;
171 mfsaobject *self;
173 self = NEWOBJ(mfsaobject, &Mfsatype);
174 if (self == NULL)
175 return NULL;
176 self->alias = alias;
177 return self;
181 static void
182 mfsa_dealloc(self)
183 mfsaobject *self;
185 #if 0
186 if ( self->alias ) {
187 should we do something here?
189 #endif
191 DEL(self);
194 statichere 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*/
213 /* End of code for Alias objects */
214 /* -------------------------------------------------------- */
217 ** Helper routine for other modules: return an FSSpec * if the
218 ** object is a python fsspec object, else NULL
220 FSSpec *
221 mfs_GetFSSpecFSSpec(self)
222 object *self;
224 if ( is_mfssobject(self) )
225 return &((mfssobject *)self)->fsspec;
226 return NULL;
229 static object *
230 mfss_as_pathname(self, args)
231 mfssobject *self;
232 object *args;
234 char strbuf[257];
235 OSErr err;
237 if (!newgetargs(args, ""))
238 return NULL;
239 err = nfullpath(&self->fsspec, strbuf);
240 if ( err ) {
241 PyErr_Mac(ErrorObject, err);
242 return NULL;
244 return newstringobject(strbuf);
247 static object *
248 mfss_as_tuple(self, args)
249 mfssobject *self;
250 object *args;
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]);
258 static object *
259 mfss_NewAlias(self, args)
260 mfssobject *self;
261 object *args;
263 FSSpec src, *srcp;
264 OSErr err;
265 AliasHandle alias;
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;
280 return (object *)newmfsaobject(alias);
283 static object *
284 mfss_NewAliasMinimal(self, args)
285 mfssobject *self;
286 object *args;
288 OSErr err;
289 AliasHandle alias;
291 if (!newgetargs(args, ""))
292 return NULL;
293 err = NewAliasMinimal(&self->fsspec, &alias);
294 if ( err ) {
295 PyErr_Mac(ErrorObject, err);
296 return NULL;
298 return (object *)newmfsaobject(alias);
301 /* XXXX These routines should be replaced with a complete interface to *FInfo */
302 static object *
303 mfss_GetCreatorType(self, args)
304 mfssobject *self;
305 object *args;
307 OSErr err;
308 FInfo info;
310 if (!newgetargs(args, ""))
311 return NULL;
312 err = FSpGetFInfo(&self->fsspec, &info);
313 if ( err ) {
314 PyErr_Mac(ErrorObject, err);
315 return NULL;
317 return Py_BuildValue("(O&O&)",
318 PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType);
321 static object *
322 mfss_SetCreatorType(self, args)
323 mfssobject *self;
324 object *args;
326 OSErr err;
327 OSType creator, type;
328 FInfo info;
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;
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;
344 INCREF(None);
345 return None;
348 static struct methodlist mfss_methods[] = {
349 {"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},
353 {"GetCreatorType", (method)mfss_GetCreatorType, 1},
354 {"SetCreatorType", (method)mfss_SetCreatorType, 1},
356 {NULL, NULL} /* sentinel */
359 /* ---------- */
361 static object *
362 mfss_getattr(self, name)
363 mfssobject *self;
364 char *name;
366 if ( strcmp(name, "data") == 0)
367 return PyString_FromStringAndSize((char *)&self->fsspec, sizeof(FSSpec));
368 return findmethod(mfss_methods, (object *)self, name);
371 mfssobject *
372 newmfssobject(fss)
373 FSSpec *fss;
375 mfssobject *self;
377 self = NEWOBJ(mfssobject, &Mfsstype);
378 if (self == NULL)
379 return NULL;
380 self->fsspec = *fss;
381 return self;
384 static void
385 mfss_dealloc(self)
386 mfssobject *self;
388 DEL(self);
391 static object *
392 mfss_repr(self)
393 mfssobject *self;
395 char buf[512];
397 sprintf(buf, "FSSpec((%d, %d, '%.*s'))",
398 self->fsspec.vRefNum,
399 self->fsspec.parID,
400 self->fsspec.name[0], self->fsspec.name+1);
401 return newstringobject(buf);
404 static int
405 mfss_compare(v, w)
406 mfssobject *v, *w;
408 int minlen;
409 int res;
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;
424 statichere typeobject Mfsstype = {
425 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*/
443 /* End of code for FSSpec objects */
444 /* -------------------------------------------------------- */
446 static object *
447 mfs_ResolveAliasFile(self, args)
448 object *self; /* Not used */
449 object *args;
451 FSSpec fss;
452 Boolean chain = 1, isfolder, wasaliased;
453 OSErr err;
455 if (!newgetargs(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
456 return NULL;
457 err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
458 if ( err ) {
459 PyErr_Mac(ErrorObject, err);
460 return NULL;
462 return mkvalue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
465 static object *
466 mfs_StandardGetFile(self, args)
467 object *self; /* Not used */
468 object *args;
470 SFTypeList list;
471 short numtypes;
472 StandardFileReply reply;
474 list[0] = list[1] = list[2] = list[3] = 0;
475 numtypes = 0;
476 if (!newgetargs(args, "|O&O&O&O&", PyMac_GetOSType, &list[0],
477 PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
478 PyMac_GetOSType, &list[3]) )
479 return NULL;
480 while ( numtypes < 4 && list[numtypes] ) {
481 numtypes++;
483 StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
484 return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
487 static object *
488 mfs_StandardPutFile(self, args)
489 object *self; /* Not used */
490 object *args;
492 Str255 prompt, dft;
493 StandardFileReply reply;
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);
502 static object *
503 mfs_FSSpec(self, args)
504 object *self; /* Not used */
505 object *args;
507 FSSpec fss;
509 if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss))
510 return NULL;
511 return (object *)newmfssobject(&fss);
514 static object *
515 mfs_RawFSSpec(self, args)
516 object *self; /* Not used */
517 object *args;
519 FSSpec *fssp;
520 int size;
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;
528 return (object *)newmfssobject(fssp);
531 static object *
532 mfs_RawAlias(self, args)
533 object *self; /* Not used */
534 object *args;
536 char *dataptr;
537 Handle h;
538 int size;
540 if (!newgetargs(args, "s#", &dataptr, &size))
541 return NULL;
542 h = NewHandle(size);
543 if ( h == NULL ) {
544 PyErr_NoMemory();
545 return NULL;
547 HLock(h);
548 memcpy((char *)*h, dataptr, size);
549 HUnlock(h);
550 return (object *)newmfsaobject((AliasHandle)h);
553 static object *
554 mfs_GetDirectory(self, args)
555 object *self; /* Not used */
556 object *args;
558 FSSpec fsdir;
559 int ok;
561 if (!newgetargs(args, "") )
562 return NULL;
564 ok = PyMac_GetDirectory(&fsdir);
565 return mkvalue("(Oi)", newmfssobject(&fsdir), ok);
568 /* List of methods defined in the module */
570 static struct methodlist mfs_methods[] = {
571 {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
572 {"StandardGetFile", mfs_StandardGetFile, 1},
573 {"StandardPutFile", mfs_StandardPutFile, 1},
574 {"GetDirectory", mfs_GetDirectory, 1},
575 {"FSSpec", mfs_FSSpec, 1},
576 {"RawFSSpec", mfs_RawFSSpec, 1},
577 {"RawAlias", mfs_RawAlias, 1},
579 {NULL, NULL} /* sentinel */
583 /* Initialization function for the module (*must* be called initmacfs) */
585 void
586 initmacfs()
588 object *m, *d;
590 /* Create the module and add the functions */
591 m = initmodule("macfs", mfs_methods);
593 /* Add some symbolic constants to the module */
594 d = getmoduledict(m);
595 ErrorObject = newstringobject("macfs.error");
596 dictinsert(d, "error", ErrorObject);
598 /* XXXX Add constants here */
600 /* Check for errors */
601 if (err_occurred())
602 fatal("can't initialize module macfs");