#include "arclib.h"
#pragma hdrstop
#include <stdlib.h>
#ifdef __BORLANDC__
#include <dir.h>
#endif
#include "wildcard.h"
#ifdef AL_UNIX
#include <sys/stat.h>
#endif
#if defined( AL_BUILDING_DLL )
void AL_DLL_FAR * AL_PROTO ALWildCardExpander::operator new( size_t size )
{
return ::new char[ size ];
}
#endif
AL_PROTO ALWildCardExpander::ALWildCardExpander(
const char AL_DLL_FAR *file_list,
int traverse_flag ,
ALCase name_case )
: mCase( name_case ),
mResultFileName( "", name_case )
{
mInputLine = file_list;
mState = GET_NEXT_WILD_NAME;
mpNextExpander = 0;
miTraverseFlag = traverse_flag;
#if defined( AL_UNIX )
mpDirectory = 0;
#elif defined( AL_WIN32S )
mFindFileHandle = INVALID_HANDLE_VALUE;
#else
mpFfblk = new find_t;
#endif
}
AL_PROTO ALWildCardExpander::~ALWildCardExpander()
{
if ( mpNextExpander )
delete mpNextExpander;
#if defined( AL_UNIX )
if ( mpDirectory )
closedir( mpDirectory );
#elif defined( AL_WIN32S )
if ( mFindFileHandle != INVALID_HANDLE_VALUE )
FindClose( mFindFileHandle );
#else
if ( mpFfblk )
delete mpFfblk;
#endif
}
#ifdef AL_UNIX
#ifndef _MAX_PATH
#define _MAX_PATH 255
#endif
#endif
int AL_PROTO ALWildCardExpander::GetNextWildName()
{
char wild_spec[ _MAX_PATH ];
int i = 0;
char *p = mInputLine;
for ( ; ; p++ ) {
int c = *p;
if ( c != ' ' && c != ',' && c != '\t' )
break;
}
for ( ; ; p++ ) {
int c = *p;
if ( c == ' ' || c == ',' || c == '\t' || c == '\0' )
break;
wild_spec[ i++ ] = (char) c;
if ( i >= ( _MAX_PATH - 2 ) )
return 0;
}
wild_spec[ i++ ] = '\0';
if ( i <= 1 )
return 0;
mFullWildName = wild_spec;
mInputLine = p;
return 1;
}
#if defined( AL_UNIX )
char AL_DLL_FAR * AL_PROTO ALWildCardExpander::GetNextFile()
{
struct dirent *entry;
struct stat buf;
ALName *temp;
for ( ; ; ) {
if ( mpNextExpander ) {
char *p = mpNextExpander->GetNextFile();
if ( p )
return p; delete mpNextExpander; mpNextExpander = 0;
}
switch ( mState ) {
case GET_NEXT_WILD_NAME :
if ( GetNextWildName() == 0 )
return 0;
mWildPathOnly = mFullWildName;
mWildPathOnly.StripFileName();
mWildNameOnly = mFullWildName;
mWildNameOnly.StripPath();
mState = GET_FIRST_FILE_NAME;
break;
case GET_FIRST_FILE_NAME :
mpDirectory = opendir( mWildPathOnly );
if ( mpDirectory == 0 ) {
if ( miTraverseFlag )
mState = GET_FIRST_DIRECTORY;
else
mState = GET_NEXT_WILD_NAME;
break;
}
mState = GET_NEXT_FILE_NAME;
break;
case GET_NEXT_FILE_NAME :
entry = readdir( mpDirectory );
if ( entry == 0 ) {
closedir( mpDirectory );
mpDirectory = 0;
if ( miTraverseFlag )
mState = GET_FIRST_DIRECTORY;
else
mState = GET_NEXT_WILD_NAME;
break;
}
mResultFileName = ALName( mWildPathOnly + entry->d_name );
stat( mResultFileName, &buf );
if ( S_ISDIR( buf.st_mode ) )
break;
if ( ALName( entry->d_name ).WildCardMatch( (const char *) mWildNameOnly ) == 0 )
break;
return mResultFileName;
case GET_FIRST_DIRECTORY :
mpDirectory = opendir( mWildPathOnly + "." );
if ( mpDirectory == 0 ) {
mState = GET_NEXT_WILD_NAME;
break;
}
mState = GET_NEXT_DIRECTORY;
break;
case GET_NEXT_DIRECTORY :
entry = readdir( mpDirectory );
if ( entry == 0 ) {
closedir( mpDirectory );
mState = GET_NEXT_WILD_NAME;
break;
}
temp = new ALName( mWildPathOnly + entry->d_name + "/" );
stat( (char *) *temp, &buf );
if ( S_ISDIR( buf.st_mode ) ) {
if ( strcmp( entry->d_name, ".." ) == 0 )
break;
if ( strcmp( entry->d_name, "." ) == 0 )
break;
*temp = mWildPathOnly + entry->d_name + "/" + (char *) mWildNameOnly;
mpNextExpander = new ALWildCardExpander( (char *) *temp, 1, mCase );
}
delete temp;
break;
default :
return 0;
}
}
}
#elif defined( AL_WIN32S )
char AL_DLL_FAR * AL_PROTO ALWildCardExpander::GetNextFile()
{
for ( ; ; ) {
if ( mpNextExpander ) {
char *p = mpNextExpander->GetNextFile();
if ( p )
return p; delete mpNextExpander; mpNextExpander = 0;
}
switch ( mState ) {
case GET_NEXT_WILD_NAME :
if ( GetNextWildName() == 0 )
return 0;
mWildPathOnly = mFullWildName;
mWildPathOnly.StripFileName();
mWildNameOnly = mFullWildName;
mWildNameOnly.StripPath();
mState = GET_FIRST_FILE_NAME;
break;
case GET_FIRST_FILE_NAME :
mFindFileHandle = FindFirstFile( mFullWildName, &mFindFileData );
if ( mFindFileHandle == INVALID_HANDLE_VALUE ) {
if ( miTraverseFlag )
mState = GET_FIRST_DIRECTORY;
else
mState = GET_NEXT_WILD_NAME;
break;
}
mState = GET_NEXT_FILE_NAME;
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
break;
mResultFileName = ALName( mWildPathOnly + mFindFileData.cFileName );
return mResultFileName;
case GET_NEXT_FILE_NAME :
if ( !FindNextFile( mFindFileHandle, &mFindFileData ) ) {
FindClose( mFindFileHandle );
mFindFileHandle = INVALID_HANDLE_VALUE;
if ( miTraverseFlag )
mState = GET_FIRST_DIRECTORY;
else
mState = GET_NEXT_WILD_NAME;
break;
}
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
break;
mResultFileName = ALName( mWildPathOnly + mFindFileData.cFileName );
return mResultFileName;
case GET_FIRST_DIRECTORY :
mFindFileHandle = FindFirstFile( mWildPathOnly + "*.*", &mFindFileData );
if ( mFindFileHandle == INVALID_HANDLE_VALUE ) {
mState = GET_NEXT_WILD_NAME;
break;
}
mState = GET_NEXT_DIRECTORY;
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
if ( strcmp( mFindFileData.cFileName, ".." ) == 0 )
break;
if ( strcmp( mFindFileData.cFileName, "." ) == 0 )
break;
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mFindFileData.cFileName + "\\" + (char *) mWildNameOnly, 1, mCase );
}
break;
case GET_NEXT_DIRECTORY :
if ( !FindNextFile( mFindFileHandle, &mFindFileData ) ) {
FindClose( mFindFileHandle );
mFindFileHandle = INVALID_HANDLE_VALUE;
mState = GET_NEXT_WILD_NAME;
break;
}
if ( mFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
if ( strcmp( mFindFileData.cFileName, ".." ) == 0 )
break;
if ( strcmp( mFindFileData.cFileName, "." ) == 0 )
break;
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mFindFileData.cFileName + "\\" + (char *) mWildNameOnly, 1 );
}
break;
default :
return 0;
}
}
}
#else
char AL_DLL_FAR * AL_PROTO ALWildCardExpander::GetNextFile()
{
if ( mpFfblk == 0 )
return 0;
for ( ; ; ) {
if ( mpNextExpander ) {
char *p = mpNextExpander->GetNextFile();
if ( p )
return p;
delete mpNextExpander;
mpNextExpander = 0;
}
switch ( mState ) {
case GET_NEXT_WILD_NAME :
if ( GetNextWildName() == 0 )
return 0;
mWildPathOnly = mFullWildName;
mWildPathOnly.StripFileName();
mWildNameOnly = mFullWildName;
mWildNameOnly.StripPath();
mState = GET_FIRST_FILE_NAME;
break;
case GET_FIRST_FILE_NAME :
if ( _dos_findfirst( mFullWildName, 0, mpFfblk ) ) {
if ( miTraverseFlag )
mState = GET_FIRST_DIRECTORY;
else
mState = GET_NEXT_WILD_NAME;
break;
}
mState = GET_NEXT_FILE_NAME;
mResultFileName = ALName( mWildPathOnly + mpFfblk->name );
return mResultFileName;
case GET_NEXT_FILE_NAME :
if ( _dos_findnext( mpFfblk ) ) {
if ( miTraverseFlag )
mState = GET_FIRST_DIRECTORY;
else
mState = GET_NEXT_WILD_NAME;
break;
}
mResultFileName = mWildPathOnly + mpFfblk->name;
return mResultFileName;
case GET_FIRST_DIRECTORY :
if ( _dos_findfirst( mWildPathOnly + "*.*", _A_SUBDIR, mpFfblk ) ) {
mState = GET_NEXT_WILD_NAME;
break;
}
mState = GET_NEXT_DIRECTORY;
if ( mpFfblk->attrib & _A_SUBDIR ) {
if ( strcmp( mpFfblk->name, ".." ) == 0 )
break;
if ( strcmp( mpFfblk->name, "." ) == 0 )
break;
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mpFfblk->name + "\\" + (char *) mWildNameOnly, 1, mCase );
}
break;
case GET_NEXT_DIRECTORY :
if ( _dos_findnext( mpFfblk ) ) {
mState = GET_NEXT_WILD_NAME;
break;
}
if ( mpFfblk->attrib & _A_SUBDIR ) {
if ( strcmp( mpFfblk->name, ".." ) == 0 )
break;
if ( strcmp( mpFfblk->name, "." ) == 0 )
break;
mpNextExpander = new ALWildCardExpander( mWildPathOnly + mpFfblk->name + "\\" + (char *) mWildNameOnly, 1 );
}
break;
default :
return 0;
}
}
#if defined( AL_MICROSOFT ) && ( AL_MICROSOFT < 800 )
return 0; #endif
}
#endif