// // WILDDOS.CPP // // Source file for ArchiveLib 2.0 // // Copyright (c) Greenleaf Software, Inc. 1994-1996 // All Rights Reserved // // CONTENTS // // ALWildCardExpander::ConstructOsData() // ALWildCardExpander::DestroyOsData() // ALWildCardExpander::GetNextFile() // // DESCRIPTION // // This file contains the OS specific routines need to expand // wild card file names. Different versions of these three functions // exist for DOS, Win95, and OS/2. // // REVISION HISTORY // // February 14, 1996 2.0A : New release // #include "arclib.h" #if !defined( AL_IBM ) #pragma hdrstop #endif #include #include #ifdef __BORLANDC__ #include #endif #include "wildcard.h" class AL_CLASS_TYPE ALWildCardOsData { /* Tag internal class */ public : find_t *f; }; // // NAME // // ALWildCardExpander::ConstructOsData() // // PLATFORMS/ENVIRONMENTS // // DOS Win16 // C++ // // SHORT DESCRIPTION // // Allocate space for a wildcard search under the MS-DOS file system. // // C++ SYNOPSIS // // #include "arclib.h" // #include "wildcard // // void ALWildCardExpander::ConstructOsData(); // // C SYNOPSIS // // No C translation for this internal protected function. // // VB SYNOPSIS // // No VB translation for this internal protected function. // // DELPHI SYNOPSIS // // No Delphi translation for this internal protected function. // // ARGUMENTS // // None. // // DESCRIPTION // // The process of wild card file expansion differs drastically for // all the different environments we support. Since each system // is going to have different data requirements, we don't try to // allocate it in the base class. Instead, we just keep a pointer to // the data, and allocate it in this member function. Different versions // of this member function show up in different directories, and the // BUILD.INI file directs the compiler as to which to include. // // This module supports the MS-DOS file system. The MS-DOS wild card // expansion state is stored in a find_t structure. We allocate that // structure here, and store a pointer to it in the mpOsData member // of the ALWildCardExpander structure. Note that the find_t data // isn't initialized yet, we have just allocated some space for it. // // RETURNS // // Nothing. // // EXAMPLE // // SEE ALSO // // REVISION HISTORY // // February 14, 1996 2.0A : New release. // void AL_PROTO ALWildCardExpander::ConstructOsData() /* Tag protected function */ { mpOsData = new ALWildCardOsData; mpOsData->f = new find_t; } // // NAME // // ALWildCardExpander::DestroyOsData() // // PLATFORMS/ENVIRONMENTS // // DOS Win16 // C++ // // SHORT DESCRIPTION // // Destroy the space allocated for the wildcard search under MS-DOS. // // C++ SYNOPSIS // // #include "arclib.h" // #include "wildcard // // void ALWildCardExpander::DestroyOsData(); // // C SYNOPSIS // // No C translation for this internal protected function. // // VB SYNOPSIS // // No VB translation for this internal protected function. // // DELPHI SYNOPSIS // // No Delphi translation for this internal protected function. // // ARGUMENTS // // None. // // DESCRIPTION // // The process of wild card file expansion differs drastically for // all the different environments we support. Since each system // is going to have different data requirements, we don't try to // allocate it in the base class. Instead, we just keep a pointer to // the data, and allocate it in the member function ConstructOsData(). // // If we are constructing something when the search starts, it makes sense // that we need to destroy it when the search is over. That's what this // guy does. // // RETURNS // // Nothing. // // EXAMPLE // // SEE ALSO // // REVISION HISTORY // // February 14, 1996 2.0A : New release. // void AL_PROTO ALWildCardExpander::DestroyOsData() /* Tag protected function */ { if ( mpOsData ) { delete mpOsData->f; delete mpOsData; } mpOsData = 0; } // // NAME // // ALWildCardExpander::GetNextFile() // // PLATFORMS/ENVIRONMENTS // // DOS Win16 // C++ C VB Delphi // // SHORT DESCRIPTION // // Search for an additional file in the wildcard expansion. // // C++ SYNOPSIS // // #include "arclib.h" // #include "wildcard.h" // // char *ALWildCardExpander::GetNextFile(); // // C SYNOPSIS // // #include "arclib.h" // #include "wildcard.h" // // char * ALExpanderGetNextFile( hALExpander this_object ); // // VB SYNOPSIS // // Declare Function ALExpanderGetNextFile Lib "AL20LW" // Alias "ALExpanderGetNextFileVB" // (ByVal this_object&) As String // // DELPHI SYNOPSIS // // function ALExpanderGetNextFile( this_object : hALExpander ) : PChar; // // ARGUMENTS // // this_object : A reference or pointer to the ALWildCardExpander that // is performing the expansion. Note that the C++ member // version of this call doesn't have an explicit argument // here, since it has access to 'this' implicitly. // // DESCRIPTION // // The ALWildCardExpander has what amounts to six different internal // states. They are: // // Searching subdirectories, using another object // // Extracting the next wild spec from the input line // // Expanding the wild card to get the first matching file // // Expanding the wild card to get the next matching file // // Looking for the first subdirectory // // Looking for the next subdirectory // // For the most part, we keep track of the state using the mState // variable. However, we keep track of whether we are searching // subdirectories by examining the pointer to the next expander. If // it is non-null, it means we are in that state. // // // RETURNS // // In the event that this routine is able to come up with a new // file name, it returns a character pointer to the name, which // is kept in member variable mResultFileName. If no new file // name could be cooked up, we return a 0, which means you are // done. // // EXAMPLE // // SEE ALSO // // REVISION HISTORY // // February 14, 1996 2.0A : New release. // char AL_DLL_FAR * AL_PROTO ALWildCardExpander::GetNextFile() /* Tag public function */ { // // mpFfblk/mpOsData is the pointer to my structure used by _dos_findfirst() // and _dos_findnext(). If for some reason this is a null pointer, // I need to quit. The only reason this should be null is a memory // allocation failure. // if ( mpOsData == 0 ) return 0; for ( ; ; ) { // // If the pointer to the next expander is non-zero, it means I am in // the middle of a subdirectory search. If that is the case, I call // the next expander to see if it can come up with a file name. if // it does, we return it. If it doesn't, it means it is done, and // I can delete it and try my luck with the next subdirectory. // if ( mpNextExpander ) { char AL_DLL_FAR *p = mpNextExpander->GetNextFile(); if ( p ) return p; delete mpNextExpander; mpNextExpander = 0; } switch ( mState ) { // // This is where I start, and this is where I end up after completely // processing one of the input wild specs. I get the next name from // the input line here. If there aren't any more names, I can return // 0, meaning the whole thing is done. // case GET_NEXT_WILD_NAME : if ( GetNextWildName() == 0 ) return 0; mWildPathOnly = mFullWildName; mWildPathOnly.StripFileName(); mWildNameOnly = mFullWildName; mWildNameOnly.StripPath(); mState = GET_FIRST_FILE_NAME; break; // // Once I have a file name, I start parsing using _dos_findfirst(). // If that doesn't return a name, I have struck out on my first swing. // if that is the case, I either move on to start searching subdirectories, // or go back and look for another name from the input line. On the // other hand, if I get a name, I return it to the caller. // case GET_FIRST_FILE_NAME : if ( _dos_findfirst( mFullWildName, 0, mpOsData->f ) ) { if ( miTraverseFlag ) mState = GET_FIRST_DIRECTORY; else mState = GET_NEXT_WILD_NAME; break; } mState = GET_NEXT_FILE_NAME; mResultFileName = ALName( mWildPathOnly + mpOsData->f->name ); return mResultFileName; // // This state is identical to GET_FIRST_FILE_NAME, except it has to // use _dos_findnext() instead of _dos_findfirst() // case GET_NEXT_FILE_NAME : if ( _dos_findnext( mpOsData->f ) ) { if ( miTraverseFlag ) mState = GET_FIRST_DIRECTORY; else mState = GET_NEXT_WILD_NAME; break; } mResultFileName = mWildPathOnly + mpOsData->f->name; return mResultFileName; // // After getting all of the file names that a wildspec expands into, // we can start searching subdirectories, if needed. Unlike with NT, // we can set our search up to look for directories only. that means // we don't have to check the status of the file returned from _dos_findxxxx(). // However, we always do have to check to make sure it isn't one of the // two bogus directory entries, "." or "..". // // If we score here, we create a new ALWildCardExpander, and put him to // work. If we strike out, time to go back and get our next input // file name. // case GET_FIRST_DIRECTORY : if ( _dos_findfirst( mWildPathOnly + "*.*", _A_SUBDIR, mpOsData->f ) ) { mState = GET_NEXT_WILD_NAME; break; } mState = GET_NEXT_DIRECTORY; if ( mpOsData->f->attrib & _A_SUBDIR ) { if ( strcmp( mpOsData->f->name, ".." ) == 0 ) break; if ( strcmp( mpOsData->f->name, "." ) == 0 ) break; mpNextExpander = new ALWildCardExpander( mWildPathOnly + mpOsData->f->name + "\\" + (char *) mWildNameOnly, 1, mCase ); } break; // // This is just like GET_FIRST_DIRECTORY, except it gets to call // _dos_findnext() instead of _dos_findfirst(). // case GET_NEXT_DIRECTORY : if ( _dos_findnext( mpOsData->f ) ) { mState = GET_NEXT_WILD_NAME; break; } if ( mpOsData->f->attrib & _A_SUBDIR ) { if ( strcmp( mpOsData->f->name, ".." ) == 0 ) break; if ( strcmp( mpOsData->f->name, "." ) == 0 ) break; mpNextExpander = new ALWildCardExpander( mWildPathOnly + mpOsData->f->name + "\\" + (char *) mWildNameOnly, 1 ); } break; default : return 0; } } #if defined( AL_MICROSOFT ) && ( AL_MICROSOFT < 800 ) return 0; //MSC 7.0 thinks I need this return path. No way to get here! #endif }