|
From: <cre...@us...> - 2006-06-25 20:38:57
|
Revision: 1419 Author: creecode Date: 2006-06-25 13:38:54 -0700 (Sun, 25 Jun 2006) ViewCVS: http://svn.sourceforge.net/frontierkernel/?rev=1419&view=rev Log Message: ----------- FSRef-ized Modified Paths: -------------- Frontier/branches/FSRef_Migration/Common/source/filepath.c Modified: Frontier/branches/FSRef_Migration/Common/source/filepath.c =================================================================== --- Frontier/branches/FSRef_Migration/Common/source/filepath.c 2006-06-25 20:06:03 UTC (rev 1418) +++ Frontier/branches/FSRef_Migration/Common/source/filepath.c 2006-06-25 20:38:54 UTC (rev 1419) @@ -33,7 +33,8 @@ #include "strings.h" #include "ops.h" #include "file.h" -#include "launch.h" /* 2005-07-18 creedon */ +#include "launch.h" // 2005-07-18 creedon +#include "MoreFilesX.h" // 2006-05-31 creedon #define flaux false /*if true, we're running under the A/UX operating system*/ @@ -41,61 +42,63 @@ #ifdef MACVERSION -static FSSpec fsdefault = {0}; /*we maintain our own default directory*/ + static tyfilespec fsdefault; // we maintain our own default directory -boolean directorytopath (long DirID, short vnum, bigstring path) { + +boolean directorytopath ( const ptrfilespec fs, bigstring path ) { + + // + // 2006-06-06 creedon: FSRef-ized + // another way might be to use FSRefMakePath and then push insert the volume name on it + // + + CFMutableStringRef ioPath = CFStringCreateMutable ( NULL, 0 ); + FSCatalogInfo catalogInfo; + FSRef localRef = ( *fs ).fsref; + HFSUniStr255 names [ 100 ]; + int i, n; + OSStatus status = noErr; + UniChar inSepChar = ':'; - CInfoPBRec block; - bigstring bsdirectory; - OSErr errcode; - - setemptystring (path); - - clearbytes (&block, longsizeof (block)); - - block.dirInfo.ioNamePtr = bsdirectory; - - block.dirInfo.ioDrParID = DirID; - - do { - block.dirInfo.ioVRefNum = vnum; + clearbytes ( &catalogInfo, longsizeof ( catalogInfo ) ); + + for ( n = 0 ; status == noErr && catalogInfo.nodeID != fsRtDirID && n < 100 ; n++ ) + status = FSGetCatalogInfo ( &localRef, kFSCatInfoNodeID, &catalogInfo, &names [ n ], NULL, &localRef ); + + if ( status != noErr ) + return ( false ); - block.dirInfo.ioFDirIndex = -1; + for ( i = n - 1; i >= 0; --i ) { + CFStringAppendCharacters ( ioPath, names [ i ].unicode, names [ i ].length ); + + // if ( i > 0 ) - block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID; - - errcode = PBGetCatInfoSync (&block); - - if (errcode != noErr) - return (false); - - if (flaux) { - if (bsdirectory[1] != '/') - if (!pushchar ('/', bsdirectory)) - return (false); - } - else - if (!pushchar (':', bsdirectory)) - return (false); - - if (!pushstring (path, bsdirectory)) - return (false); - - copystring (bsdirectory, path); - } while (block.dirInfo.ioDrDirID != fsRtDirID); + CFStringAppendCharacters ( ioPath, &inSepChar, 1 ); + } - return (true); - } /*directorytopath*/ + return ( CFStringGetPascalString ( ioPath, path, 256, kCFStringEncodingMacRoman ) ); + } // directorytopath + #endif -boolean filegetdefaultpath (tyfilespec *fs) { + +boolean filegetdefaultpath ( ptrfilespec fs ) { + + // + // 2006-06-25 creedon: for Mac, FSRef-ized + // #ifdef MACVERSION - return (!oserror (FSMakeFSSpec (fsdefault.vRefNum, fsdefault.parID, nil, fs))); + + *fs = fsdefault; + + return ( true ); + #endif #ifdef WIN95VERSION + DWORD sz; sz = GetCurrentDirectory (257, stringbaseaddress (fsname (fs))); @@ -112,41 +115,29 @@ setstringlength(fsname (fs), sz + 1); return (true); + #endif } /*filegetdefaultpath*/ -boolean filesetdefaultpath (const tyfilespec *fs) { +boolean filesetdefaultpath ( const ptrfilespec fs ) { + + // + // 2006-06-18 creedon: for Mac, FSRef-ized + // #ifdef MACVERSION - CInfoPBRec pb; + + setfserrorparam ( fs ); - clearbytes (&fsdefault, longsizeof (fsdefault)); + fsdefault = *fs; - if (isemptystring ((*fs).name)) - return (true); + return (true); - setoserrorparam ((ptrstring) (*fs).name); - - clearbytes (&pb, longsizeof (pb)); - - pb.dirInfo.ioNamePtr = (StringPtr) (*fs).name; - - pb.dirInfo.ioVRefNum = (*fs).vRefNum; - - pb.dirInfo.ioDrDirID = (*fs).parID; - - if (oserror (PBGetCatInfoSync (&pb))) - return (false); - - fsdefault.vRefNum = pb.dirInfo.ioVRefNum; - - fsdefault.parID = pb.dirInfo.ioDrDirID; - - return (true); #endif #ifdef WIN95VERSION + if (isemptystring (fsname (fs))) return (true); @@ -158,55 +149,85 @@ } return (true); + #endif - } /*filesetdefaultpath*/ + + } // filesetdefaultpath -boolean filespectopath (const tyfilespec *fs, bigstring bspath) { +boolean filespectopath (const ptrfilespec fs, bigstring bspath) { - /* - 6/28/91 dmb: when you resolve an alias of a volume, the fsspec has a - parent dirid of 1. we catch this as a special case here, and return - the empty string as the path + // + // 2006-06-24 creedon: for Mac, FSRef-ized + // + // 2.1a7 dmb: if it's a null filespec, return the empty string + // + // 1991-12-17 dmb: don't check for folderness if file doesn't exist-- we dont want to generate any errors here + // + // 1991-10-14 dmb: make sure folder paths end in : + // + // 1991-06-28 dmb: when you resolve an alias of a volume, the fsspec has a parent dirid of 1. we catch this as a + // special case here, and return the empty string as the path + // - 10/14/91 dmb: make sure folder paths end in : + #ifdef MACVERSION - 12/17/91 dmb: don't check for folderness if file doesn't exist-- we - dont want to generate any errors here - - 2.1a7 dmb: if it's a null filespec, return the empty string - */ - - #ifdef MACVERSION boolean flfolder; + FSCatalogInfo catalogInfo; + tyfilespec fsp, fst = *fs; + HFSUniStr255 outName; + OSErr err; - if ((*fs).parID == fsRtParID) { /*it's a volume*/ + ( void ) extendfilespec ( &fst, &fst ); + + err = FSGetCatalogInfo ( &fst.fsref, kFSCatInfoParentDirID | kFSCatInfoVolume, &catalogInfo, &outName, NULL, + &fsp.fsref ); + + if ( catalogInfo.parentDirID == fsRtParID ) { // it's a volume + + HFSUniStr255ToStr255 ( &outName, bspath ); + + pushchar ( ':', bspath ); - copystring ((ptrstring) (*fs).name, bspath); - - pushchar (':', bspath); - - return (true); + return ( true ); } - setemptystring (bspath); + setemptystring ( bspath ); - if (((*fs).parID == 0) && ((*fs).vRefNum == 0) && (isemptystring ((*fs).name))) + if ( ! FSRefValid ( &fst.fsref ) ) // need to check for noErr here? return (true); - if (!directorytopath ((*fs).parID, (*fs).vRefNum, bspath)) + if ( ! directorytopath ( &fsp, bspath ) ) return (false); + + bigstring bs; + + HFSUniStr255ToStr255 ( &outName, bs ); - pushstring ((ptrstring) (*fs).name, bspath); + pushstring ( bs, bspath ); - if (fileexists (fs, &flfolder)) - if (flfolder) - assurelastchariscolon (bspath); + if ( fst.path != NULL ) { + + pushchar ( ':', bspath ); + + CFStringToStr255 ( fst.path, bs ); + + pushstring ( bs, bspath ); + + return ( true ); + + } + + if ( fileexists ( &fst, &flfolder ) ) + if ( flfolder ) + assurelastchariscolon ( bspath ); return (true); + #endif #ifdef WIN95VERSION + // 5.0d12 dmb: use GetFullPath to clean up 8.3 names char * fileptr; @@ -219,76 +240,164 @@ nullterminate (bspath); return (true); + #endif - } /*filespectopath*/ + + } // filespectopath -boolean pathtofilespec (bigstring bspath, tyfilespec *fs) { +boolean pathtofilespec ( bigstring bspath, ptrfilespec fs ) { - /* - 7/5/91 dmb: use FSMakeFSSpec if it's available. since it only returns - noErr if the file exists, and we want to handle non-existant files, we - don't give up right away. + // + // 2006-06-25 creedon: for Mac, FSRef-ized + // + // 5.0d8 dmb: clear fs first thing + // + // 2.1b2 dmb: use new fsdefault for building filespec. note that if bspath isn't a partial path, the vref and dirid will be + // ignored. + // + // 2.1b2 dmb: added special case for empty string. also, added drive number interpretation here. + // + // 1993-06-11 dmb: if FSMakeFSSpec returns fnfErr, the spec is cool (but file doesn't exist) + // + // 1991-012-17 dmb: dont append path to default directory if it's a full path + // + // 1991-07-05 dmb: use FSMakeFSSpec if it's available. since it only returns noErr if the file exists, and we want to handle + // non-existant files, we don't give up right away. + // - 12/17/91 dmb: dont append path to default directory if it's a full path + clearbytes ( fs, sizeof ( *fs ) ); + + if ( isemptystring ( bspath ) ) + return ( true ); + + #ifdef MACVERSION - 6/11/93 dmb: if FSMakeFSSpec returns fnfErr, the spec is cool (but file - doesn't exist) - - 2.1b2 dmb: added special case for empty string. also, added drive number - interpretation here. - - 2.1b2 dmb: use new fsdefault for building filespec. note that if bspath - isn't a partial path, the vref and dirid will be ignored. - */ - - bigstring bsfolder; - #ifdef MACVERSION - OSErr errcode; - short ix = 1; - #endif + bigstring bs, bspathtmp; + FSRef fsr; + OSStatus status; + + copystring ( bspath, bspathtmp ); - clearbytes (fs, sizeof (tyfilespec)); // 5,0d8 dmb + cleanendoffilename ( bspathtmp ); + + /* try as full path */ { + + bigstring bsfullpath; + + copystring ( bspathtmp, bsfullpath ); + + insertstring ( BIGSTRING ( "\x09" ":Volumes:" ), bsfullpath ); // this is a funky syntax but we don't want to + // convert to slashes until the last moment, so + // we can resuse - if (isemptystring (bspath)) - return (true); + copystring ( bsfullpath, bs); + + stringreplaceall ( ':', '/', bs ); + + convertpstring ( bs ); + + status = FSPathMakeRef ( bs, &fsr, NULL ); + + if ( status == noErr ) { + + HFSUniStr255 name; - #ifdef MACVERSION - errcode = FSMakeFSSpec (fsdefault.vRefNum, fsdefault.parID, bspath, fs); + status = FSGetCatalogInfo ( &fsr, kFSCatInfoNone, NULL, &name, NULL, &fsr ); + + ( *fs ).fsref = fsr; + + ( *fs ).path = CFStringCreateWithCharacters ( kCFAllocatorDefault, name.unicode, name.length ); + + return ( true ); + + } + + /* emulate behaviour of FSSpec */ { + + folderfrompath ( bsfullpath, bs ); + + stringreplaceall ( ':', '/', bs ); + + convertpstring ( bs ); + + status = FSPathMakeRef ( bs, &fsr, NULL ); + + if ( status == noErr ) { + + /* bail if fsr is Volumes directory */ { + + FSRef volumesfsref; + + status = FSPathMakeRef ( "/Volumes", &volumesfsref, NULL ); + + if ( FSCompareFSRefs ( &fsr, &volumesfsref ) != noErr ) { + + filefrompath ( bsfullpath, bs ); + + ( *fs ).fsref = fsr; + + ( *fs ).path = CFStringCreateWithPascalString ( kCFAllocatorDefault, bs, + kCFStringEncodingMacRoman ); + + return ( true ); + + } // if + } // bail + } // if + } // emulate FSSpec + } // full path + + /* try as partial path */ { - //for some reason if there is a trailing : you get a dirNFErr and it doesn't work - //This little hack saves us. It still is a fnfErr, but it works. - #if TARGET_API_MAC_CARBON - if(errcode == dirNFErr) - { - poptrailingchars(bspath, ':'); - errcode = FSMakeFSSpec (fsdefault.vRefNum, fsdefault.parID, bspath, fs); - } - #endif - if ((errcode == noErr) || (errcode == fnfErr)) - return (true); + bigstring bspartialpath; + tyfilespec fst; + + copystring ( bspathtmp, bspartialpath ); + + if ( bspartialpath [ 1 ] != chpathseparator ) + insertchar ( chpathseparator, bspartialpath ); - if (scanstring (':', bspath, &ix) && (ix > 1)) { /*includes a colon, not the first thing*/ + ( void ) extendfilespec ( &fsdefault, &fst ); - short drivenum; + status = FSRefMakePath ( &fst.fsref, ( UInt8 * ) bs, 256 ); // bs is now a c string - midstring (bspath, 1, ix - 1, bsfolder); /*pull out volume name*/ + convertcstring ( bs ); // bs is now a bigstring - if (isallnumeric (bsfolder) && stringtoshort (bsfolder, &drivenum)) { /*it's a number*/ + insertstring ( bs, bspartialpath ); + + copystring ( bspartialpath, bs ); + + stringreplaceall ( ':', '/', bs ); + + convertpstring ( bs ); // bs is now a c string + + status = FSPathMakeRef ( bs, &fsr, NULL ); + + if ( status == noErr ) { + + HFSUniStr255 name; + + status = FSGetCatalogInfo ( &fsr, kFSCatInfoNone, NULL, &name, NULL, &fsr ); + + ( *fs ).fsref = fsr; - midstring (bspath, ix, stringlength (bspath) - ix + 1, bsfolder); + ( *fs ).path = CFStringCreateWithCharacters ( kCFAllocatorDefault, name.unicode, name.length ); + + return ( true ); - errcode = FSMakeFSSpec (drivenum, 0, bsfolder, fs); + } - if ((errcode == noErr) || (errcode == fnfErr)) - return (true); - } - } + } - return (false); + return ( false ); + #endif #ifdef WIN95VERSION + + bigstring bsfolder; + copystring (bspath, fsname (fs)); folderfrompath (bspath, bsfolder); @@ -305,42 +414,40 @@ return (true); #endif - } /*pathtofilespec*/ + } // pathtofilespec -boolean setfsfile (tyfilespec *fs, bigstring bsfile) { +boolean setfsfile ( ptrfilespec fs, bigstring bsfile ) { - /* - 2004-10-26 aradke: Since the getmacfileinfo/foldertest gymnastics do not - seem to fit any particular purpose and since none of our callers - seem to rely it since they usually pass in a file rather than a directory, - I commented it out. - - The only time we get called with a directory is apparently by - shellopendefaultfile on startup in the Carbon/Mach-O build. - getapplicationfilespec returns a directory in that case and - the code below somehow screwed up when called to set the - filename to Frontier.root so that it wouldn't be found. - */ + // + // 2006-06-25 creedon: for Mac, FSRef-ized + // + // 2004-10-26 aradke: Since the getmacfileinfo/foldertest gymnastics do not seem to fit any particular purpose and since + // none of our callers seem to rely it since they usually pass in a file rather than a directory, I + // commented it out. + // + // The only time we get called with a directory is apparently by shellopendefaultfile on startup in the + // Carbon/Mach-O build. getapplicationfilespec returns a directory in that case and the code below + // somehow screwed up when called to set the filename to Frontier.root so that it wouldn't be found. + // #ifdef MACVERSION - /* - CInfoPBRec pb; - - if (getmacfileinfo (fs, &pb) && foldertest (&pb)) { - FSMakeFSSpec ((*fs).vRefNum, pb.dirInfo.ioDrDirID, bsfile, fs); - - return (false); - } - */ + HFSUniStr255 name; + OSErr err; - copystring (bsfile, (*fs).name); + bigstringToHFSUniStr255 ( bsfile, &name ); + + err = FSGetCatalogInfo ( &( *fs ).fsref, kFSCatInfoNone, NULL, NULL, NULL, &( *fs ).fsref ); + + err = FSMakeFSRefUnicode ( &( *fs ).fsref, name.length, name.unicode, kTextEncodingUnknown, &( *fs ).fsref ); - return (true); + return ( true ); + #endif #ifdef WIN95VERSION + bigstring bsfolder; folderfrompath (fsname (fs), bsfolder); @@ -352,68 +459,98 @@ nullterminate (fsname (fs)); return (true); + #endif - } /*setfsfile*/ + + } // setfsfile -boolean getfsfile (const tyfilespec *fs, bigstring bsfile) { +boolean getfsfile (const ptrfilespec fs, bigstring bsfile) { + + // + // 2006-06-18 creedon: for Mac, FSRef-ized + // + + #ifdef MACVERSION - /* - 5.0b9 dmb: we're needing this in a few places. better late - than never - */ + if ( ( *fs ).path != NULL ) { + + if ( CFStringToStr255 ( ( *fs ).path, bsfile ) ) + return ( true ); + } + else { + FSRefGetNameStr255 ( &( *fs ).fsref, bsfile ); + } - #ifdef WIN95VERSION - bigstring bspath; - - filespectopath (fs, bspath); + if (stringlength ( bsfile ) > 0) + return (true); + + long vnum; - filefrompath (bspath, bsfile); + getfsvolume ( fs, &vnum ); + + return ( filegetvolumename ( vnum, bsfile ) ); + + #endif - return (true); - #endif + #ifdef WIN95VERSION - #ifdef MACVERSION - copystring (fsname (fs), bsfile); + lastword ((ptrstring) fs -> fullSpecifier, '\\', bsfile); return (true); + #endif - } /*getfsfile*/ + } // getfsfile -boolean getfsvolume (const tyfilespec *fs, long *vnum) { +boolean getfsvolume (const ptrfilespec fs, long *vnum) { - /* - 5.1.5b11 dmb: get the volume that is actually specified in the fspec. + // + // 2006-06-25 creedon: for Mac, FSRef-ized + // + // 5.1.5b11 dmb: get the volume that is actually specified in the fspec. + // + // don't expand partial paths using the default directory. + // - don't expand partial paths using the default directory. - */ - - #ifdef WIN95VERSION - return (fileparsevolname ((ptrstring) fsname (fs), vnum, nil)); - #endif + #ifdef MACVERSION - #ifdef MACVERSION - HVolumeParam pb; + FSCatalogInfo catalogInfo; + OSErr err = FSGetCatalogInfo ( &fs->fsref, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL ); - *vnum = (*fs).vRefNum; + if ( catalogInfo.volume == 0 ) + return ( false ); - if (*vnum == 0) - return (false); + *vnum = catalogInfo.volume; + + return ( err == noErr ); - clearbytes (&pb, sizeof (pb)); /*init all fields to zero*/ + #endif + + #ifdef WIN95VERSION + + return (fileparsevolname ((ptrstring) fsname (fs), vnum, nil)); - pb.ioVRefNum = *vnum; - - return (PBHGetVInfoSync ((HParmBlkPtr) &pb) == noErr); #endif - } /*getfsvolume*/ + + } /* getfsvolume */ void initfsdefault (void) { + + // + // 2006-06-18 creedon: FSRef-ized + // + // 2005-07-18 creedon, karstenw: created + // + #ifdef MACVERSION - /* 2005-07-18 creedon, karstenw */ - getapplicationfilespec (nil, &fsdefault); + + getapplicationfilespec ( nil, &fsdefault ); + + getfilespecparent ( &fsdefault ); + #endif + } /* initfsdefault */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |