|
From: <cre...@us...> - 2006-06-26 21:52:35
|
Revision: 1431 Author: creecode Date: 2006-06-26 14:52:31 -0700 (Mon, 26 Jun 2006) ViewCVS: http://svn.sourceforge.net/frontierkernel/?rev=1431&view=rev Log Message: ----------- FSRef-ized Modified Paths: -------------- Frontier/branches/FSRef_Migration/Common/source/fileloop.c Modified: Frontier/branches/FSRef_Migration/Common/source/fileloop.c =================================================================== --- Frontier/branches/FSRef_Migration/Common/source/fileloop.c 2006-06-26 21:33:54 UTC (rev 1430) +++ Frontier/branches/FSRef_Migration/Common/source/fileloop.c 2006-06-26 21:52:31 UTC (rev 1431) @@ -36,684 +36,790 @@ #include "fileloop.h" +#ifdef MACVERSION + #include "MoreFilesX.h" -#ifdef MACVERSION -typedef struct tyfilelooprecord { - - short vnum; /*the volume we're looping through*/ - - long dirid; /*the folder we're looking in*/ - - short ixdirectory; /*index for the next file to look at*/ - - hdllistrecord hfilelist; /*a list of filenames to be looped over*/ - } tyfilelooprecord, *ptrfilelooprecord, **hdlfilelooprecord; - - + typedef struct tyfilelooprecord { + + short vnum; /*the volume we're looping through*/ + + long dirid; /*the folder we're looking in*/ + + short ixdirectory; /*index for the next file to look at*/ + + hdllistrecord hfilelist; /*a list of filenames to be looped over*/ + } tyfilelooprecord, *ptrfilelooprecord, **hdlfilelooprecord; +#endif // MACVERSION -static boolean fileloopreleaseitem (Handle h) { -#pragma unused(h) - /* - callback routine that disposes of one of our items. since there are no - handles linked into our handle, there's nothing to release. - - I just wanted to have one of these around so the next guy that uses the - list facilty knows how to link a releaseitem callback routine. - */ - - return (true); - } /*fileloopreleaseitem*/ - +#ifdef WIN95VERSION -boolean diskinitloop (tyfileloopcallback diskfilter, Handle *hdiskloop) { -#pragma unused(diskfilter) + typedef struct tyfindloopinfo + { + tyfilespec fs; + HANDLE findhandle; + tyfileloopcallback ffilter; + boolean doingDrives; + short drivenum; + } findloopinfo; - /* - same as fileinitloop, but for volumes on line +#endif // WIN95VERSION + + +#ifdef MACVERSION - 8/15/92 dmb: added, but commented out, diskfilter support - */ - - tyfilelooprecord info; - ParamBlockRec pb; - register hdlfilelooprecord h; - short ix; - hdllistrecord hlist; - - clearbytes (&pb, sizeof (pb)); /*init all fields to zero*/ - - clearbytes (&info, sizeof (info)); - - info.ixdirectory = 1; /*start with the first file*/ - - if (!newfilledhandle (&info, sizeof (info), hdiskloop)) - return (false); - - h = (hdlfilelooprecord) *hdiskloop; /*copy into register*/ - - hlist = nil; - - if (!opnewlist (&hlist, false)) - goto error; - - (**h).hfilelist = hlist; - - opsetreleaseitemcallback (hlist, &fileloopreleaseitem); - - ix = 1; /*start with file index 1*/ - - while (true) { - FSSpec fsvol; - OSErr errcode; - Handle hstring; - #if TARGET_API_MAC_CARBON == 1 - HFSUniStr255 theName; - //Code change by Timothy Paustian Thursday, June 29, 2000 10:29:59 AM - //Updated to modern call for volume infomation - //Ii am checking this now against the original. - FSVolumeRefNum vRefNum;//this is just a SInt16 + static boolean fileloopreleaseitem (Handle h) { + #pragma unused(h) + + /* + callback routine that disposes of one of our items. since there are no + handles linked into our handle, there's nothing to release. - //Watch out that the fsvol.name parameter works as expected. - //this is still not working the way it should - errcode = FSGetVolumeInfo(0, ix, &vRefNum, kFSVolInfoNone, nil, &theName, nil); - if (errcode == nsvErr) /*not an error, just ran out of volumes*/ - return (true); + I just wanted to have one of these around so the next guy that uses the + list facilty knows how to link a releaseitem callback routine. + */ - { - UnicodeToTextInfo theInfo; - UnicodeMapping theMapping; - theMapping.unicodeEncoding = kTextEncodingUnicodeDefault; - theMapping.otherEncoding = kTextEncodingMacRoman; - theMapping.mappingVersion = kUnicodeUseLatestMapping; - errcode = CreateUnicodeToTextInfo(&theMapping,&theInfo); - if (oserror (errcode)) // 1/29/97 dmb: call oserror - goto error; - //fsvol.name[0] = theName.length; - errcode = ConvertFromUnicodeToPString (theInfo, theName.length * 2, theName.unicode, fsvol.name); - if (oserror (errcode)) // 1/29/97 dmb: call oserror - goto error; - } - ix++; - fsvol.vRefNum = vRefNum; + return (true); + } /*fileloopreleaseitem*/ - #else //not carbon - pb.volumeParam.ioVolIndex = ix++; + + boolean diskinitloop (tyfileloopcallback diskfilter, Handle *hdiskloop) { + #pragma unused(diskfilter) + + /* + same as fileinitloop, but for volumes on line - pb.volumeParam.ioNamePtr = fsvol.name; + 8/15/92 dmb: added, but commented out, diskfilter support + */ - errcode = PBGetVInfoSync (&pb); - fsvol.vRefNum = pb.volumeParam.ioVRefNum; + tyfilelooprecord info; + ParamBlockRec pb; + register hdlfilelooprecord h; + short ix; + hdllistrecord hlist; - if (errcode == nsvErr) /*not an error, just ran out of volumes*/ - return (true); - #endif//end carbon + clearbytes (&pb, sizeof (pb)); /*init all fields to zero*/ - if (errcode == nsvErr) /*not an error, just ran out of volumes*/ - return (true); + clearbytes (&info, sizeof (info)); - if (oserror (errcode)) // 1/29/97 dmb: call oserror - goto error; + info.ixdirectory = 1; /*start with the first file*/ - fsvol.parID = fsRtParID; + if (!newfilledhandle (&info, sizeof (info), hdiskloop)) + return (false); - if (!newfilledhandle (&fsvol, sizeof (fsvol), &hstring)) - goto error; + h = (hdlfilelooprecord) *hdiskloop; /*copy into register*/ - if (!oppushhandle (hlist, nil, (Handle) hstring)) + hlist = nil; + + if (!opnewlist (&hlist, false)) goto error; - - } /*while*/ - - error: - - opdisposelist (hlist); - - disposehandle (*hdiskloop); - - *hdiskloop = nil; - - return (false); - } /*diskinitloop*/ - - -boolean fileinitloop (const tyfilespec *fs, tyfileloopcallback filefilter, Handle *hfileloop) { -#pragma unused(filefilter) - - /* - a conglomeration of filemanager incantations which sets up a UserLand - fileloop construct. we create a new handle (allows fileloops to be - nested inside other file loops, not statically allocated) and fill it - with information that each iteration of a fileloop will need. took - a minimum of two days fiddling (3/16-17/90) to get this to work -- DW. - - 12/6/91 dmb: generate dirNFErr when fileparsevolname fails - - 8/15/92 dmb: added, but commented out, filefilter support - - 2.1b2 dmb: updated to use filespecs - - 3.0.2 dmb: make sure fs is a folder, not a file - */ - - tyfilelooprecord info; - CInfoPBRec pb; - long dirid; - register hdlfilelooprecord h; - short ix; - hdllistrecord hlist; - - clearbytes (&pb, sizeof (CInfoPBRec)); /*init all fields to zero*/ - - setoserrorparam ((ptrstring) (*fs).name); - - pb.hFileInfo.ioVRefNum = (*fs).vRefNum; - - pb.hFileInfo.ioDirID = (*fs).parID; - - pb.hFileInfo.ioNamePtr = (StringPtr) (*fs).name; - - if (oserror (PBGetCatInfoSync (&pb))) - return (false); - - if (!foldertest (&pb)) { /*3.0.2*/ - oserror (dirNFErr); + (**h).hfilelist = hlist; - return (false); - } - - dirid = pb.dirInfo.ioDrDirID; /*must remember this for loop body*/ - - clearbytes (&info, sizeof (info)); - - info.vnum = pb.hFileInfo.ioVRefNum; - - info.dirid = pb.hFileInfo.ioDirID; - - info.ixdirectory = 1; /*start with the first file*/ - - if (!newfilledhandle (&info, sizeof (info), hfileloop)) - return (false); - - h = (hdlfilelooprecord) *hfileloop; /*copy into register*/ - - hlist = nil; - - if (!opnewlist (&hlist, false)) - goto error; + opsetreleaseitemcallback (hlist, &fileloopreleaseitem); - (**h).hfilelist = hlist; - - opsetreleaseitemcallback (hlist, &fileloopreleaseitem); - - ix = 1; /*start with file index 1*/ - - while (true) { + ix = 1; /*start with file index 1*/ - bigstring bsfile; - Handle hstring; - OSErr errcode; + while (true) { + FSSpec fsvol; + OSErr errcode; + Handle hstring; + #if TARGET_API_MAC_CARBON == 1 + HFSUniStr255 theName; + //Code change by Timothy Paustian Thursday, June 29, 2000 10:29:59 AM + //Updated to modern call for volume infomation + //Ii am checking this now against the original. + FSVolumeRefNum vRefNum;//this is just a SInt16 + + //Watch out that the fsvol.name parameter works as expected. + //this is still not working the way it should + errcode = FSGetVolumeInfo(0, ix, &vRefNum, kFSVolInfoNone, nil, &theName, nil); + if (errcode == nsvErr) /*not an error, just ran out of volumes*/ + return (true); + + { + UnicodeToTextInfo theInfo; + UnicodeMapping theMapping; + theMapping.unicodeEncoding = kTextEncodingUnicodeDefault; + theMapping.otherEncoding = kTextEncodingMacRoman; + theMapping.mappingVersion = kUnicodeUseLatestMapping; + errcode = CreateUnicodeToTextInfo(&theMapping,&theInfo); + if (oserror (errcode)) // 1/29/97 dmb: call oserror + goto error; + //fsvol.name[0] = theName.length; + errcode = ConvertFromUnicodeToPString (theInfo, theName.length * 2, theName.unicode, fsvol.name); + if (oserror (errcode)) // 1/29/97 dmb: call oserror + goto error; + } + ix++; + fsvol.vRefNum = vRefNum; + + #else //not carbon + pb.volumeParam.ioVolIndex = ix++; + + pb.volumeParam.ioNamePtr = fsvol.name; + + errcode = PBGetVInfoSync (&pb); + fsvol.vRefNum = pb.volumeParam.ioVRefNum; + + if (errcode == nsvErr) /*not an error, just ran out of volumes*/ + return (true); + #endif//end carbon + + if (errcode == nsvErr) /*not an error, just ran out of volumes*/ + return (true); + + if (oserror (errcode)) // 1/29/97 dmb: call oserror + goto error; + + fsvol.parID = fsRtParID; + + if (!newfilledhandle (&fsvol, sizeof (fsvol), &hstring)) + goto error; + + if (!oppushhandle (hlist, nil, (Handle) hstring)) + goto error; + + } /*while*/ - pb.dirInfo.ioDrDirID = dirid; /*may be smashed by ioFlNum on previous loop*/ + error: - pb.dirInfo.ioFDirIndex = ix++; + opdisposelist (hlist); - pb.dirInfo.ioNamePtr = bsfile; + disposehandle (*hdiskloop); - errcode = PBGetCatInfoSync (&pb); + *hdiskloop = nil; - if (errcode == fnfErr) /*not an error, just ran out of files*/ - return (true); - - #if TARGET_API_MAC_CARBON == 1 - - if (errcode == dirNFErr) /*On OS X, this is what's returned for a read permission error. Weird.*/ - return (true); + return (false); + } /*diskinitloop*/ - if (errcode == afpAccessDenied) /* 2005-01-05 creedon - don't bail when user does not have the correct permissions < http://sourceforge.net/tracker/index.php?func=detail&aid=1096641&group_id=120666&atid=687798 > */ - return (true); - #endif + boolean diskloop (tyfileloopcallback diskcallback, long refcon) { - if (oserror (errcode)) /*errcode != noErr*/ - goto error; + /* + dmb 9/21/93: filegetvolumeinfo takes a vRefNum, not a string. + */ - /*if it's a folder, insert a colon at the end of the file name*/ + HVolumeParam pb; + short ix; - if (foldertest (&pb)) - if (!pushchar (':', bsfile)) - goto error; + clearbytes (&pb, sizeof (pb)); /*init all fields to zero*/ - /* - if (filefilter != nil) { + ix = 1; /*start with file index 1*/ + + while (true) { - if (!(*filefilter) (bspath, bsfile)) - continue; + bigstring bsvolume; + tyfileinfo info; + OSErr errcode; + + pb.ioVolIndex = ix++; + + pb.ioNamePtr = bsvolume; + + errcode = PBHGetVInfoSync ((HParmBlkPtr) &pb); + + if (errcode == nsvErr) /*not an error, just ran out of volumes*/ + return (true); + + if (oserror (errcode)) + return (false); + + filegetvolumeinfo (pb.ioVRefNum, &info); + + if (!(*diskcallback) (bsvolume, &info, refcon)) + return (false); + } /*while*/ + } /*diskloop*/ + +#endif // MACVERSION + + +#ifdef WIN95VERSION + + static boolean initfileloopspec (tyfilespec *fs) + { + HANDLE findHandle; + WIN32_FIND_DATA fileinfo; + char fn[300]; + char * filename; + short isFolder; + + copystring (fsname (fs), fn); + filename = fsname (fs); + + if (fileisvolume (fs)) { + cleanendoffilename (fsname (fs)); + appendcstring (filename, "\\*"); + return (true); } - */ + + cleanendoffilename (fn); + nullterminate (fn); - if (!newtexthandle (bsfile, &hstring)) - goto error; + findHandle = FindFirstFile (stringbaseaddress(fn), &fileinfo); + + if (findHandle == INVALID_HANDLE_VALUE) + { + oserror (GetLastError()); + return (false); //no match + } + + isFolder = (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?true:false; + + if (FindNextFile (findHandle, &fileinfo)) + { + FindClose (findHandle); + return (true); //wild card must be present to find second + } + + FindClose (findHandle); - if (!oppushhandle (hlist, nil, (Handle) hstring)) - goto error; - } /*while*/ - - error: - - opdisposelist (hlist); - - disposehandle (*hfileloop); - - *hfileloop = nil; - - return (false); - } /*fileinitloop*/ + if (isFolder) { + cleanendoffilename (filename); + appendcstring (filename, "\\*"); -void fileendloop (Handle hfileloop) { - - register hdlfilelooprecord h = (hdlfilelooprecord) hfileloop; - - opdisposelist ((**h).hfilelist); - - disposehandle ((Handle) h); - } /*fileendloop*/ + nullterminate (filename); + } + return (true); + } -boolean filenextloop (Handle hfileloop, tyfilespec *fsfile, boolean *flfolder) { +#endif // WIN95VERSION + + +boolean fileinitloop ( const ptrfilespec fst, tyfileloopcallback filefilter, Handle *hfileloop ) { + + #ifdef MACVERSION - /* - 8/17/92 dmb: we're using text handles now instead of string handles. - - 2.1b2 dmb: now we're using filespecs! - - 2.1b11 dmb: for volumes, whole fsspec is now stashed in handle - - 3.0.2b1 dmb: must set flfolder to true for disks - - 3.0.4b1 dmb: return true of fnfErr; script will have to handle error anyway - - 5.0.2b21 dmb: don't call FSMakeFSSpec for each file; just the first. - */ - - register hdlfilelooprecord h = (hdlfilelooprecord) hfileloop; - Handle hdata; - bigstring bs; - short vnum; - long dirid; - OSErr err; - - if (!opgetlisthandle ((**h).hfilelist, (**h).ixdirectory++, nil, &hdata)) - return (false); - - vnum = (**h).vnum; - - if (vnum == 0) { /*item is a volume, hdata contains refnum*/ + #pragma unused(filefilter) + + // + // a conglomeration of filemanager incantations which sets up a UserLand + // fileloop construct. we create a new handle (allows fileloops to be + // nested inside other file loops, not statically allocated) and fill it + // with information that each iteration of a fileloop will need. took + // a minimum of two days fiddling (3/16-17/90) to get this to work -- DW. + // + // 2006-06-26 creedon: minimally FSRef-ized + // + // 3.0.2 dmb: make sure fs is a folder, not a file + // + // 2.1b2 dmb: updated to use filespecs + // + // 1992-08-15 dmb: added, but commented out, filefilter support + // + // 1991-12-06 dmb: generate dirNFErr when fileparsevolname fails + // - /* - vnum = **(short **) hdata; + tyfilelooprecord info; + CInfoPBRec pb; + long dirid; + register hdlfilelooprecord h; + short ix; + hdllistrecord hlist; + FSSpec fs; + tyfilespec fst2; - setemptystring (bs); - */ + ( void ) extendfilespec ( fst, &fst2 ); - *fsfile = **(FSSpec **) hdata; + FSRefMakeFSSpec ( &fst2.fsref, &fs ); // might need to do more checking here to handle path - *flfolder = true; /*3.0.2b1*/ + clearbytes (&pb, sizeof (CInfoPBRec)); // init all fields to zero - return (true); - } - else { + setoserrorparam ((ptrstring) fs.name); - dirid = (**h).dirid; + pb.hFileInfo.ioVRefNum = fs.vRefNum; - texthandletostring (hdata, bs); + pb.hFileInfo.ioDirID = fs.parID; - *flfolder = bs [*bs] == ':'; + pb.hFileInfo.ioNamePtr = (StringPtr) fs.name; - if (*flfolder) - --*bs; + if (oserror (PBGetCatInfoSync (&pb))) + return (false); - if ((**h).ixdirectory == 2) { //first time + if (!foldertestcipbr (&pb)) { // 3.0.2 - err = FSMakeFSSpec (vnum, dirid, bs, fsfile); + oserror (dirNFErr); - (**h).vnum = (*fsfile).vRefNum; + return (false); - (**h).dirid = (*fsfile).parID; + } + + dirid = pb.dirInfo.ioDrDirID; // must remember this for loop body + + clearbytes (&info, sizeof (info)); + + info.vnum = pb.hFileInfo.ioVRefNum; + + info.dirid = pb.hFileInfo.ioDirID; + + info.ixdirectory = 1; // start with the first file + + if (!newfilledhandle (&info, sizeof (info), hfileloop)) + return (false); + + h = (hdlfilelooprecord) *hfileloop; // copy into register + + hlist = nil; + + if (!opnewlist (&hlist, false)) + goto error; - if ((err == noErr) || (err == fnfErr)) /* 3.0.4b1 dmb */ - return (true); + (**h).hfilelist = hlist; + + opsetreleaseitemcallback (hlist, &fileloopreleaseitem); + + ix = 1; // start with file index 1 + + while (true) { - return (!oserror (err)); /* false */ - } - else { + bigstring bsfile; + Handle hstring; + OSErr errcode; - (*fsfile).vRefNum = vnum; + pb.dirInfo.ioDrDirID = dirid; // may be smashed by ioFlNum on previous loop - (*fsfile).parID = dirid; + pb.dirInfo.ioFDirIndex = ix++; - copystring (bs, (*fsfile).name); + pb.dirInfo.ioNamePtr = bsfile; - return (true); - } - } - } /*filenextloop*/ + errcode = PBGetCatInfoSync (&pb); + + if (errcode == fnfErr) // not an error, just ran out of files + return (true); + + if (errcode == dirNFErr) // On OS X, this is what's returned for a read permission error. Weird. + return (true); + if (errcode == afpAccessDenied) // 2005-01-05 creedon - don't bail when user does not have the correct permissions < http://sourceforge.net/tracker/index.php?func=detail&aid=1096641&group_id=120666&atid=687798 > + return (true); -boolean diskloop (tyfileloopcallback diskcallback, long refcon) { - - /* - dmb 9/21/93: filegetvolumeinfo takes a vRefNum, not a string. - */ - - HVolumeParam pb; - short ix; - - clearbytes (&pb, sizeof (pb)); /*init all fields to zero*/ - - ix = 1; /*start with file index 1*/ - - while (true) { + if (oserror (errcode)) // errcode != noErr + goto error; + + // if it's a folder, insert a colon at the end of the file name + + if (foldertestcipbr (&pb)) + if (!pushchar (':', bsfile)) + goto error; + + /* + if (filefilter != nil) { + + if (!(*filefilter) (bspath, bsfile)) + continue; + } + */ + + if (!newtexthandle (bsfile, &hstring)) + goto error; + + if (!oppushhandle (hlist, nil, (Handle) hstring)) + goto error; + + } // while + + error: - bigstring bsvolume; - tyfileinfo info; - OSErr errcode; + opdisposelist (hlist); - pb.ioVolIndex = ix++; + disposehandle (*hfileloop); - pb.ioNamePtr = bsvolume; + *hfileloop = nil; - errcode = PBHGetVInfoSync ((HParmBlkPtr) &pb); + return (false); - if (errcode == nsvErr) /*not an error, just ran out of volumes*/ - return (true); + #endif // MACVERSION + + #ifdef WIN95VERSION + + findloopinfo ** fi; - if (oserror (errcode)) + *hfileloop = NULL; + fi = (findloopinfo **) NewHandle (sizeof(findloopinfo)); + + if (fi == NULL) return (false); + + (**fi).fs = *pfs; + (**fi).findhandle = NULL; + (**fi).ffilter = filefilter; + (**fi).doingDrives = false; + (**fi).drivenum = 0; /*start with A*/ + + if (isemptystring ((**fi).fs.fullSpecifier)) { /* do disks */ + (**fi).doingDrives = true; + } + else { + initfileloopspec (&((**fi).fs)); + } + + *hfileloop = (Handle)fi; + return (true); + + #endif // WIN95VERSION + + } // fileinitloop + + +void fileendloop (Handle hfileloop) { + + #ifdef MACVERSION + + register hdlfilelooprecord h = (hdlfilelooprecord) hfileloop; - filegetvolumeinfo (pb.ioVRefNum, &info); + opdisposelist ((**h).hfilelist); - if (!(*diskcallback) (bsvolume, &info, refcon)) - return (false); - } /*while*/ - } /*diskloop*/ + disposehandle ((Handle) h); + #endif // MACVERSION -boolean folderloop (const tyfilespec *pfs, boolean flreverse, tyfileloopcallback filecallback, long refcon) { + #ifdef WIN95VERSION - /* - loop through all of the files in the folder at fs, and call filecallback - for each one. - - if flreverse is true, loop through files backwards to allow for deletions - - DW 8/28/93: inexplicably, getmacfileinfo is determining that ctfiles is 1 - greater than the actual number of files in our folder (it's the History - folder in clayhistorymenu.c). the way the loop was structured, we visit - no files in the folder in this case. changed it so that on fnfErr we - continue the loop. the next time thru it will find a file. hope this - doesn't break anything else (it shouldn't). - */ - - FSSpec fs = *pfs; /*work with a copy*/ - CInfoPBRec pb; - long dirid; - bigstring bsfile; - short ix; - long ctfiles; - tyfileinfo info; - OSErr ec; - - setoserrorparam ((ptrstring) fs.name); - - if (!getmacfileinfo (&fs, &pb)) - return (false); + findloopinfo ** fi; + fi = (findloopinfo **) hfileloop; + + if (fi != NULL) + { + if ((**fi).findhandle != NULL) + FindClose ((**fi).findhandle); - assert (BitTst (&pb.dirInfo.ioFlAttrib, 3)); /*be sure it's a folder*/ + disposehandle ((Handle) fi); + + #endif // WIN95VERSION - dirid = pb.dirInfo.ioDrDirID; /*must remember this for loop body*/ + } // fileendloop + + +boolean folderloop ( const ptrfilespec pfs, boolean flreverse, tyfileloopcallback filecallback, long refcon ) { + + #ifdef MACVERSION - ctfiles = pb.dirInfo.ioDrNmFls; - - if (flreverse) - ix = ctfiles; - else - ix = 1; /*start with file index 1*/ - - while (--ctfiles >= 0) { + // + // loop through all of the files in the folder at fs, and call filecallback + // for each one. + // + // if flreverse is true, loop through files backwards to allow for deletions + // + // 2006-06-26 creedon: minimally FSRef-ized + // + // 1993-08-28 DW: inexplicably, getmacfileinfo is determining that ctfiles is 1 + // greater than the actual number of files in our folder (it's the History + // folder in clayhistorymenu.c). the way the loop was structured, we visit + // no files in the folder in this case. changed it so that on fnfErr we + // continue the loop. the next time thru it will find a file. hope this + // doesn't break anything else (it shouldn't). + // - pb.dirInfo.ioDrDirID = dirid; /*may be smashed by ioFlNum on previous loop*/ + FSSpec fs; + CInfoPBRec pb; + long dirid; + bigstring bsfile; + short ix; + long ctfiles; + tyfileinfo info; + OSErr ec; - pb.dirInfo.ioFDirIndex = ix; + FSRefMakeFSSpec ( &( *pfs ).fsref, &fs ); // might need to do more checking here to handle path - if (flreverse) - --ix; - else - ++ix; + setoserrorparam ((ptrstring) fs.name); - pb.dirInfo.ioNamePtr = bsfile; + if (!getmacfileinfocipbr (&fs, &pb)) + return (false); + + assert (BitTst (&pb.dirInfo.ioFlAttrib, 3)); // be sure it's a folder - ec = PBGetCatInfoSync (&pb); + dirid = pb.dirInfo.ioDrDirID; // must remember this for loop body - if (ec == fnfErr) /*DW 8/28/93: continue instead of returning true*/ - continue; - - if (oserror (ec)) - return (false); + ctfiles = pb.dirInfo.ioDrNmFls; - filegetinfofrompb (&pb, &info); + if (flreverse) + ix = ctfiles; + else + ix = 1; // start with file index 1 - if (!(*filecallback) (bsfile, &info, refcon)) - return (false); - } /*while*/ + while (--ctfiles >= 0) { + + pb.dirInfo.ioDrDirID = dirid; // may be smashed by ioFlNum on previous loop + + pb.dirInfo.ioFDirIndex = ix; + + if (flreverse) + --ix; + else + ++ix; + + pb.dirInfo.ioNamePtr = bsfile; + + ec = PBGetCatInfoSync (&pb); + + if (ec == fnfErr) // DW 8/28/93: continue instead of returning true + continue; + + if (oserror (ec)) + return (false); + + filegetinfofrompbcipbr (&pb, &info); + + if (!(*filecallback) (bsfile, &info, refcon)) + return (false); + + } // while + + return (true); - return (true); - } /*folderloop*/ -#endif - - - - -#ifdef WIN95VERSION -// start windows version...... -typedef struct tyfindloopinfo - { - tyfilespec fs; - HANDLE findhandle; - tyfileloopcallback ffilter; - boolean doingDrives; - short drivenum; - } findloopinfo; - -static boolean initfileloopspec (tyfilespec *fs) - { - HANDLE findHandle; - WIN32_FIND_DATA fileinfo; - char fn[300]; - char * filename; - short isFolder; - - copystring (fsname (fs), fn); - filename = fsname (fs); + #endif // MACVERSION - if (fileisvolume (fs)) { - cleanendoffilename (fsname (fs)); - appendcstring (filename, "\\*"); - return (true); - } - - cleanendoffilename (fn); - nullterminate (fn); + #ifdef WIN95VERSION - findHandle = FindFirstFile (stringbaseaddress(fn), &fileinfo); + HANDLE findHandle; + WIN32_FIND_DATA fileinfo; + char fn[300]; + char pathname[300]; + char * endofpath; + bigstring bsfile; + tyfileinfo info; + int errCode; - if (findHandle == INVALID_HANDLE_VALUE) - { - oserror (GetLastError()); - return (false); //no match - } - isFolder = (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?true:false; + copystring (fsname (pfs), fn); - if (FindNextFile (findHandle, &fileinfo)) - { - FindClose (findHandle); - return (true); //wild card must be present to find second - } + cleanendoffilename (fn); - FindClose (findHandle); - if (isFolder) { - cleanendoffilename (filename); + nullterminate (fn); + + findHandle = FindFirstFile (stringbaseaddress(fn), &fileinfo); - appendcstring (filename, "\\*"); + if (findHandle == INVALID_HANDLE_VALUE) + { + oserror (GetLastError()); + return (false); + } - nullterminate (filename); - } + winsetfileinfo (&fileinfo, &info); - return (true); - } + GetFullPathName (stringbaseaddress(fn), 300, stringbaseaddress(pathname), &endofpath); -boolean fileinitloop (const tyfilespec *pfs, tyfileloopcallback filefilter, Handle *hfileloop) { - - findloopinfo ** fi; - - *hfileloop = NULL; - fi = (findloopinfo **) NewHandle (sizeof(findloopinfo)); + *endofpath = 0; /*terminates path name*/ - if (fi == NULL) - return (false); + setstringlength(pathname, strlen(stringbaseaddress(pathname))); - (**fi).fs = *pfs; - (**fi).findhandle = NULL; - (**fi).ffilter = filefilter; - (**fi).doingDrives = false; - (**fi).drivenum = 0; /*start with A*/ + buildfilename (pathname, 0, fileinfo.cFileName, 1, bsfile); - if (isemptystring ((**fi).fs.fullSpecifier)) { /* do disks */ - (**fi).doingDrives = true; - } - else { - initfileloopspec (&((**fi).fs)); - } + if (!(*filecallback) (bsfile, &info, refcon)) + { + FindClose(findHandle); + return (false); + } - *hfileloop = (Handle)fi; - return (true); - } + while (FindNextFile (findHandle, &fileinfo)) + { + winsetfileinfo (&fileinfo, &info); -void fileendloop (Handle hfileloop) { - - findloopinfo ** fi; - fi = (findloopinfo **) hfileloop; + buildfilename (pathname, 0, fileinfo.cFileName, 1, bsfile); - if (fi != NULL) - { - if ((**fi).findhandle != NULL) - FindClose ((**fi).findhandle); - - disposehandle ((Handle) fi); - } - } /*fileendloop*/ + if (!(*filecallback) (bsfile, &info, refcon)) + { + FindClose(findHandle); + return (false); + } + } + errCode = GetLastError(); -boolean filenextloop (Handle hfileloop, tyfilespec *fsfile, boolean *flfolder) { - findloopinfo ** fi; - HANDLE findHandle; - WIN32_FIND_DATA fileinfo; - char fn[300]; - char pathname[300]; - char * endofpath; - int errCode; - short drivenum; - DWORD drivemap, drivemask; + FindClose(findHandle); - if (hfileloop == NULL) - return (false); + if (errCode == ERROR_NO_MORE_FILES) + return (true); - if (fsfile == NULL) + oserror(errCode); + return (false); - fi = (findloopinfo **) hfileloop; + #endif // WIN95VERSION + + } // folderloop - if ((**fi).doingDrives) { /*We are looping over each volume - not files*/ - while (true) { - drivenum = (**fi).drivenum; - ++((**fi).drivenum); +boolean filenextloop ( Handle hfileloop, ptrfilespec fsfilet, boolean *flfolder ) { - if (drivenum >= 26) - return (false); + #ifdef MACVERSION + + // + // 2006-06-26 creedon: minimally FSRef-ized + // + // 5.0.2b21 dmb: don't call FSMakeFSSpec for each file; just the first. + // + // 3.0.4b1 dmb: return true of fnfErr; script will have to handle error anyway + // + // 3.0.2b1 dmb: must set flfolder to true for disks + // + // 2.1b11 dmb: for volumes, whole fsspec is now stashed in handle + // + // 2.1b2 dmb: now we're using filespecs! + // + // 1992-08-17 dmb: we're using text handles now instead of string handles. + + register hdlfilelooprecord h = (hdlfilelooprecord) hfileloop; + Handle hdata; + bigstring bs; + short vnum; + long dirid; + OSErr err; + FSSpec fsfile; + - drivemap = GetLogicalDrives(); + if (!opgetlisthandle ((**h).hfilelist, (**h).ixdirectory++, nil, &hdata)) + return (false); - drivemask = 1 << drivenum; - - if ((drivemap & drivemask) == drivemask) { /* we found one */ - /*convert drivenum to filespec */ - wsprintf (stringbaseaddress(fsname(fsfile)), "%c:\\", drivenum + 'A'); - setstringlength (fsname(fsfile), strlen(stringbaseaddress(fsname(fsfile)))); - *flfolder = true; + vnum = (**h).vnum; + + if (vnum == 0) { /*item is a volume, hdata contains refnum*/ + + /* + vnum = **(short **) hdata; + + setemptystring (bs); + */ + + fsfile = **(FSSpec **) hdata; + + *flfolder = true; /*3.0.2b1*/ + + FSpMakeFSRef ( &fsfile, &( *fsfilet ).fsref ); + + getfilespecparent ( &( *fsfilet ) ); + + return (true); + + } + else { + + dirid = (**h).dirid; + + texthandletostring (hdata, bs); + + *flfolder = bs [*bs] == ':'; + + if (*flfolder) + --*bs; + + if ((**h).ixdirectory == 2) { //first time + + err = FSMakeFSSpec (vnum, dirid, bs, &fsfile); + + (**h).vnum = fsfile.vRefNum; + + (**h).dirid = fsfile.parID; + + if ((err == noErr) || (err == fnfErr)) { // 3.0.4b1 dmb + + FSpMakeFSRef ( &fsfile, &( *fsfilet ).fsref ); + + getfilespecparent ( &( *fsfilet ) ); + + return (true); + + } + + return ( ! oserror ( err ) ); // false + + } + else { + + fsfile.vRefNum = vnum; + + fsfile.parID = dirid; + + copystring (bs, fsfile.name); + + FSpMakeFSRef ( &fsfile, &( *fsfilet ).fsref ); + + getfilespecparent ( &( *fsfilet ) ); + return (true); } } - } + + #endif // MACVERSION + + #ifdef WIN95VERSION + + findloopinfo ** fi; + HANDLE findHandle; + WIN32_FIND_DATA fileinfo; + char fn[300]; + char pathname[300]; + char * endofpath; + int errCode; + short drivenum; + DWORD drivemap, drivemask; - if ((**fi).findhandle == NULL) /*we are looking for the first one...*/ - { - copystring (fsname (&(**fi).fs), fn); + if (hfileloop == NULL) + return (false); - cleanendoffilename (fn); + if (fsfile == NULL) + return (false); - nullterminate (fn); - - findHandle = FindFirstFile (stringbaseaddress(fn), &fileinfo); + fi = (findloopinfo **) hfileloop; - if (findHandle == INVALID_HANDLE_VALUE) - { - oserror (GetLastError()); - return (false); - } + if ((**fi).doingDrives) { /*We are looping over each volume - not files*/ + while (true) { + drivenum = (**fi).drivenum; - GetFullPathName (stringbaseaddress(fn), 300, stringbaseaddress(pathname), &endofpath); + ++((**fi).drivenum); - *endofpath = 0; /*terminates path name*/ + if (drivenum >= 26) + return (false); - setstringlength(pathname, strlen(stringbaseaddress(pathname))); + drivemap = GetLogicalDrives(); + + drivemask = 1 << drivenum; - copystring (pathname, fsname (&(**fi).fs)); - buildfilename (fsname (&(**fi).fs), 0, fileinfo.cFileName, 1, fsname (fsfile)); + if ((drivemap & drivemask) == drivemask) { /* we found one */ + /*convert drivenum to filespec */ + wsprintf (stringbaseaddress(fsname(fsfile)), "%c:\\", drivenum + 'A'); + setstringlength (fsname(fsfile), strlen(stringbaseaddress(fsname(fsfile)))); + *flfolder = true; + return (true); + } + } + } - if (flfolder != NULL) - *flfolder = (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?true:false; + if ((**fi).findhandle == NULL) /*we are looking for the first one...*/ + { + copystring (fsname (&(**fi).fs), fn); - (**fi).findhandle = findHandle; + cleanendoffilename (fn); - if (strcmp (fileinfo.cFileName, ".") == 0) - goto SkippingDotandDotDot; + nullterminate (fn); + + findHandle = FindFirstFile (stringbaseaddress(fn), &fileinfo); - if (strcmp (fileinfo.cFileName, "..") == 0) - goto SkippingDotandDotDot; + if (findHandle == INVALID_HANDLE_VALUE) + { + oserror (GetLastError()); + return (false); + } - if (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - cleanendoffilename (fsname(fsfile)); - appendcstring (fsname(fsfile), "\\"); - } + GetFullPathName (stringbaseaddress(fn), 300, stringbaseaddress(pathname), &endofpath); - return (true); - } - else - { -SkippingDotandDotDot: - if (FindNextFile ((**fi).findhandle, &fileinfo)) - { + *endofpath = 0; /*terminates path name*/ + + setstringlength(pathname, strlen(stringbaseaddress(pathname))); + + copystring (pathname, fsname (&(**fi).fs)); buildfilename (fsname (&(**fi).fs), 0, fileinfo.cFileName, 1, fsname (fsfile)); if (flfolder != NULL) *flfolder = (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?true:false; + (**fi).findhandle = findHandle; + if (strcmp (fileinfo.cFileName, ".") == 0) goto SkippingDotandDotDot; @@ -727,83 +833,41 @@ return (true); } + else + { + SkippingDotandDotDot: + if (FindNextFile ((**fi).findhandle, &fileinfo)) + { + buildfilename (fsname (&(**fi).fs), 0, fileinfo.cFileName, 1, fsname (fsfile)); - errCode = GetLastError(); + if (flfolder != NULL) + *flfolder = (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?true:false; -// FindClose((**fi).findhandle); + if (strcmp (fileinfo.cFileName, ".") == 0) + goto SkippingDotandDotDot; - if (errCode != ERROR_NO_MORE_FILES) - oserror(errCode); - } + if (strcmp (fileinfo.cFileName, "..") == 0) + goto SkippingDotandDotDot; - return (false); - } + if (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + cleanendoffilename (fsname(fsfile)); + appendcstring (fsname(fsfile), "\\"); + } + return (true); + } -boolean folderloop (const tyfilespec *pfs, boolean flreverse, tyfileloopcallback filecallback, long refcon) { - HANDLE findHandle; - WIN32_FIND_DATA fileinfo; - char fn[300]; - char pathname[300]; - char * endofpath; - bigstring bsfile; - tyfileinfo info; - int errCode; + errCode = GetLastError(); + // FindClose((**fi).findhandle); - copystring (fsname (pfs), fn); + if (errCode != ERROR_NO_MORE_FILES) + oserror(errCode); + } - cleanendoffilename (fn); - - nullterminate (fn); + return (false); - findHandle = FindFirstFile (stringbaseaddress(fn), &fileinfo); + #endif // WIN95VERSION + + } // filenextloop - if (findHandle == INVALID_HANDLE_VALUE) - { - oserror (GetLastError()); - return (false); - } - - winsetfileinfo (&fileinfo, &info); - - GetFullPathName (stringbaseaddress(fn), 300, stringbaseaddress(pathname), &endofpath); - - *endofpath = 0; /*terminates path name*/ - - setstringlength(pathname, strlen(stringbaseaddress(pathname))); - - buildfilename (pathname, 0, fileinfo.cFileName, 1, bsfile); - - if (!(*filecallback) (bsfile, &info, refcon)) - { - FindClose(findHandle); - return (false); - } - - while (FindNextFile (findHandle, &fileinfo)) - { - winsetfileinfo (&fileinfo, &info); - - buildfilename (pathname, 0, fileinfo.cFileName, 1, bsfile); - - if (!(*filecallback) (bsfile, &info, refcon)) - { - FindClose(findHandle); - return (false); - } - } - - errCode = GetLastError(); - - FindClose(findHandle); - - if (errCode == ERROR_NO_MORE_FILES) - return (true); - - oserror(errCode); - return (false); - } - -#endif - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |