os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacUtil.c
Update contrib.
4 * This contains utility functions used to help with
5 * implementing Macintosh specific portions of the Tcl port.
7 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
8 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * RCS: @(#) $Id: tclMacUtil.c,v 1.7 2003/03/03 20:22:44 das Exp $
18 #include "tclMacInt.h"
20 #include "tclMacPort.h"
26 #include <FSpCompat.h>
28 #include <TextUtils.h>
29 #include <MoreFilesExtras.h>
32 * The following two Includes are from the More Files package.
35 #include <MoreFiles.h>
38 *----------------------------------------------------------------------
42 * The standard math function hypot is not supported by Think C.
43 * It is included here so everything works. It is supported by
44 * CodeWarrior Pro 1, but the 68K version does not support doubles.
48 * Result of computation.
53 *----------------------------------------------------------------------
57 double hypotd(double x, double y);
61 double x, /* X value */
62 double y) /* Y value */
72 *----------------------------------------------------------------------
76 * This function gets the current default directory.
79 * The provided FSSpec is changed to point to the "default"
80 * directory. The function returns what ever errors
81 * FSMakeFSSpecCompat may encounter.
86 *----------------------------------------------------------------------
91 FSSpecPtr dirSpec) /* On return the default directory. */
97 err = HGetVol(NULL, &vRefNum, &dirID);
100 err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL,
108 *----------------------------------------------------------------------
110 * FSpSetDefaultDir --
112 * This function sets the default directory to the directory
113 * pointed to by the provided FSSpec.
116 * The function returns what ever errors HSetVol may encounter.
121 *----------------------------------------------------------------------
126 FSSpecPtr dirSpec) /* The new default directory. */
131 * The following special case is needed to work around a bug
132 * in the Macintosh OS. (Acutally PC Exchange.)
135 if (dirSpec->parID == fsRtParID) {
136 err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID);
138 err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID);
145 *----------------------------------------------------------------------
149 * This function is a version of the FindFolder function that
150 * returns the result as a FSSpec rather than a vRefNum and dirID.
153 * Results will be simaler to that of the FindFolder function.
158 *----------------------------------------------------------------------
163 short vRefNum, /* Volume reference number. */
164 OSType folderType, /* Folder type taken by FindFolder. */
165 Boolean createFolder, /* Should we create it if non-existant. */
166 FSSpec *spec) /* Pointer to resulting directory. */
172 err = FindFolder(vRefNum, folderType, createFolder,
173 &foundVRefNum, &foundDirID);
178 err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec);
183 FSpLocationFromPathAlias _ANSI_ARGS_((int length, CONST char *path,
184 FSSpecPtr fileSpecPtr, Boolean resolveLink));
187 *----------------------------------------------------------------------
189 * FSpLocationFromPath --
191 * This function obtains an FSSpec for a given macintosh path.
192 * Unlike the More Files function FSpLocationFromFullPath, this
193 * function will also accept partial paths and resolve any aliases
202 *----------------------------------------------------------------------
207 int length, /* Length of path. */
208 CONST char *path, /* The path to convert. */
209 FSSpecPtr fileSpecPtr) /* On return the spec for the path. */
211 return FSpLocationFromPathAlias(length, path, fileSpecPtr, TRUE);
215 *----------------------------------------------------------------------
217 * FSpLLocationFromPath --
219 * This function obtains an FSSpec for a given macintosh path.
220 * Unlike the More Files function FSpLocationFromFullPath, this
221 * function will also accept partial paths and resolve any aliases
222 * along the path expect for the last path component.
230 *----------------------------------------------------------------------
234 FSpLLocationFromPath(
235 int length, /* Length of path. */
236 CONST char *path, /* The path to convert. */
237 FSSpecPtr fileSpecPtr) /* On return the spec for the path. */
239 return FSpLocationFromPathAlias(length, path, fileSpecPtr, FALSE);
243 FSpLocationFromPathAlias(
244 int length, /* Length of path. */
245 CONST char *path, /* The path to convert. */
246 FSSpecPtr fileSpecPtr, /* On return the spec for the path. */
247 Boolean resolveLink) /* Resolve the last path component? */
255 Boolean wasAlias=FALSE;
259 * Check to see if this is a full path. If partial
260 * we assume that path starts with the current working
261 * directory. (Ie. volume & dir = 0)
269 if (path[cur] == ':') {
273 * If path = ":", just return current directory.
275 FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr);
279 while (path[cur] != ':' && cur < length) {
287 * This is a full path
290 strncpy((char *) fileName + 1, path, cur);
292 err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr);
293 if (err != noErr) return err;
294 FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
295 vRefNum = fileSpecPtr->vRefNum;
302 while (cur < length) {
307 while (path[pos] != ':' && pos < length) {
311 /* Move up one dir */
313 strcpy((char *) fileName + 1, "::");
315 } else if (pos - cur > 255) {
318 strncpy((char *) fileName + 1, &path[cur], pos - cur);
319 fileName[0] = pos - cur;
321 err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr);
322 if (err != noErr) return err;
323 lastFileSpec=*fileSpecPtr;
324 err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias);
326 /* ignore alias resolve errors on last path component */
327 if (pos < length) return err;
328 else *fileSpecPtr=lastFileSpec;
330 FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
331 vRefNum = fileSpecPtr->vRefNum;
333 if (path[cur] == ':') {
338 if(!resolveLink && wasAlias)
339 *fileSpecPtr=lastFileSpec;
345 *----------------------------------------------------------------------
347 * FSpPathFromLocation --
349 * This function obtains a full path name for a given macintosh
350 * FSSpec. Unlike the More Files function FSpGetFullPath, this
351 * function will return a C string in the Handle. It also will
352 * create paths for FSSpec that do not yet exist.
360 *----------------------------------------------------------------------
365 FSSpec *spec, /* The location we want a path for. */
366 int *length, /* Length of the resulting path. */
367 Handle *fullPath) /* Handle to path. */
376 * Make a copy of the input FSSpec that can be modified.
378 BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
380 if (tempSpec.parID == fsRtParID) {
382 * The object is a volume. Add a colon to make it a full
383 * pathname. Allocate a handle for it and we are done.
385 tempSpec.name[0] += 2;
386 tempSpec.name[tempSpec.name[0] - 1] = ':';
387 tempSpec.name[tempSpec.name[0]] = '\0';
389 err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
392 * The object isn't a volume. Is the object a file or a directory?
394 pb.dirInfo.ioNamePtr = tempSpec.name;
395 pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
396 pb.dirInfo.ioDrDirID = tempSpec.parID;
397 pb.dirInfo.ioFDirIndex = 0;
398 err = PBGetCatInfoSync(&pb);
400 if ((err == noErr) || (err == fnfErr)) {
402 * If the file doesn't currently exist we start over. If the
403 * directory exists everything will work just fine. Otherwise we
404 * will just fail later. If the object is a directory, append a
405 * colon so full pathname ends with colon, but only if the name is
406 * not empty. NavServices returns FSSpec's with the parent ID set,
407 * but the name empty...
410 BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
411 } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) {
412 if (tempSpec.name[0] > 0) {
413 tempSpec.name[0] += 1;
414 tempSpec.name[tempSpec.name[0]] = ':';
419 * Create a new Handle for the object - make it a C string.
421 tempSpec.name[0] += 1;
422 tempSpec.name[tempSpec.name[0]] = '\0';
423 err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
426 * Get the ancestor directory names - loop until we have an
427 * error or find the root directory.
429 pb.dirInfo.ioNamePtr = tempSpec.name;
430 pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
431 pb.dirInfo.ioDrParID = tempSpec.parID;
433 pb.dirInfo.ioFDirIndex = -1;
434 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
435 err = PBGetCatInfoSync(&pb);
438 * Append colon to directory name and add
439 * directory name to beginning of fullPath.
442 tempSpec.name[tempSpec.name[0]] = ':';
444 (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1],
448 } while ( (err == noErr) &&
449 (pb.dirInfo.ioDrDirID != fsRtDirID) );
455 * On error Dispose the handle, set it to NULL & return the err.
456 * Otherwise, set the length & return.
459 *length = GetHandleSize(*fullPath) - 1;
461 if ( *fullPath != NULL ) {
462 DisposeHandle(*fullPath);
472 *----------------------------------------------------------------------
474 * GetGlobalMouseTcl --
476 * This procedure obtains the current mouse position in global
485 *----------------------------------------------------------------------
490 Point *mouse) /* Mouse position. */
494 OSEventAvail(0, &event);
495 *mouse = event.where;
498 pascal OSErr FSpGetDirectoryIDTcl (CONST FSSpec * spec,
499 long * theDirID, Boolean * isDirectory)
501 return(FSpGetDirectoryID(spec, theDirID, isDirectory));
504 pascal short FSpOpenResFileCompatTcl (CONST FSSpec * spec, SignedByte permission)
506 return(FSpOpenResFileCompat(spec,permission));
509 pascal void FSpCreateResFileCompatTcl (
510 CONST FSSpec * spec, OSType creator,
511 OSType fileType, ScriptCode scriptTag)
513 FSpCreateResFileCompat (spec,creator,fileType,scriptTag);