crblib/walker.c
/***

normal WalkDir processes directories, then steps into them

this version processes all directories, then steps back from the deepest

this is needed by Delete

**/
normal WalkDir processes directories, then steps into them
this version processes all directories, then steps back from the deepest

this is needed by Delete
normal WalkDir processes directories then steps into them this version processes all directories then steps back from the deepest this is needed by Delete
bool WalkDir_DeepFirst(char *StartPath,bool RecurseFlag,bool DoDirs,
	FileFuncType FileFunc,DirStartFuncType DirStartFunc,DirDoneFuncType DirDoneFunc)
{
struct WalkState *CurState,*GotState;
DIR * DFD;
bool Ok = 1;
char WasInDir[1024];
bool KeepGoing=1;
if ( !getcwd(WasInDir,1024) )
	return(0);
if ( ! HaveExitTrap ) if ( atexit(WalkerExit) == 0 ) HaveExitTrap = 1;
ExitResetDir = WasInDir;
if ( (CurState = malloc(sizeof(struct WalkState))) == NULL )
	return(0);
CurState->Next = NULL;
CurState->NestLevel = -1;
CurState->WalkerFlag = 0;
if ( !StartPath )
	{
	strcpy(CurState->Path,WasInDir);
	}
else
	{
	int err = chdir(StartPath);
	if ( err != 0 )
		return 0;
	if ( !getcwd(CurState->Path,1024) )
		{ free(CurState); return(0); }
	}
if ( RecurseFlag)
	{
	struct WalkState * ListHead = CurState;
	do
		{
		GotState = ListHead;
		while(GotState && GotState->WalkerFlag ) GotState = GotState->Next;
		if ( GotState )
			{
			if ( KeepGoing )
				{
				if ( DFD = opendir(GotState->Path) )
					{
					if ( chdir(GotState->Path) == 0 )
						{
						if ( KeepGoing )
							KeepGoing = WalkCurDir(DFD,GotState->Path,GotState->NestLevel,
														1,0,NULL,&ListHead);
						}
					else
						Ok = 0;
					closedir(DFD);
					}
				}
			GotState->WalkerFlag = 1;
			}
		} while ( GotState );
	CurState = ListHead;
	}
while( CurState )
	{
	GotState = CurState;
	CurState = CurState->Next;
	if ( KeepGoing )
		{
		if ( DFD = opendir(GotState->Path) )
			{
			if ( chdir(GotState->Path) == 0 )
				{
				if ( DirStartFunc && KeepGoing ) 
					KeepGoing = (*DirStartFunc)(GotState->Path,GotState->NestLevel);
				CatPaths(GotState->Path,"");
				if ( KeepGoing )
					KeepGoing = WalkCurDir(DFD,GotState->Path,GotState->NestLevel,
												RecurseFlag,DoDirs,FileFunc,&CurState);
				if ( KeepGoing && DirDoneFunc )
					KeepGoing = (*DirDoneFunc)(GotState->Path,GotState->NestLevel);
				closedir(DFD); DFD = NULL;
				}
			else Ok = 0;
			if ( DFD) closedir(DFD);
			}
		else
			{
			if ( chdir(GotState->Path) == 0 )
				{
				if ( DirStartFunc && KeepGoing )
					KeepGoing = (*DirStartFunc)(GotState->Path,GotState->NestLevel);
				if ( KeepGoing && DirDoneFunc )
					KeepGoing = (*DirDoneFunc)(GotState->Path,GotState->NestLevel);
				}
			}
		}
	free(GotState);
	}
{
int err = chdir(WasInDir);
assert( err == 0 );
}
ExitResetDir = NULL;
return(Ok);
}
bool WalkDir_DeepFirst ( char * StartPath , bool RecurseFlag , bool DoDirs , FileFuncType FileFunc , DirStartFuncType DirStartFunc , DirDoneFuncType DirDoneFunc ) { struct WalkState * CurState , * GotState ; DIR * DFD ; bool Ok = 1 ; char WasInDir [ 1024 ] ; bool KeepGoing = 1 ; if ( ! getcwd ( WasInDir , 1024 ) ) return ( 0 ) ; if ( ! HaveExitTrap ) if ( atexit ( WalkerExit ) == 0 ) HaveExitTrap = 1 ; ExitResetDir = WasInDir ; if ( ( CurState = malloc ( sizeof ( struct WalkState ) ) ) == NULL ) return ( 0 ) ; CurState -> Next = NULL ; CurState -> NestLevel = -1 ; CurState -> WalkerFlag = 0 ; if ( ! StartPath ) { strcpy ( CurState -> Path , WasInDir ) ; } else { int err = chdir ( StartPath ) ; if ( err != 0 ) return 0 ; if ( ! getcwd ( CurState -> Path , 1024 ) ) { free ( CurState ) ; return ( 0 ) ; } } if ( RecurseFlag ) { struct WalkState * ListHead = CurState ; do { GotState = ListHead ; while ( GotState && GotState -> WalkerFlag ) GotState = GotState -> Next ; if ( GotState ) { if ( KeepGoing ) { if ( DFD = opendir ( GotState -> Path ) ) { if ( chdir ( GotState -> Path ) == 0 ) { if ( KeepGoing ) KeepGoing = WalkCurDir ( DFD , GotState -> Path , GotState -> NestLevel , 1 , 0 , NULL , & ListHead ) ; } else Ok = 0 ; closedir ( DFD ) ; } } GotState -> WalkerFlag = 1 ; } } while ( GotState ) ; CurState = ListHead ; } while ( CurState ) { GotState = CurState ; CurState = CurState -> Next ; if ( KeepGoing ) { if ( DFD = opendir ( GotState -> Path ) ) { if ( chdir ( GotState -> Path ) == 0 ) { if ( DirStartFunc && KeepGoing ) KeepGoing = ( * DirStartFunc ) ( GotState -> Path , GotState -> NestLevel ) ; CatPaths ( GotState -> Path , " " ) ; if ( KeepGoing ) KeepGoing = WalkCurDir ( DFD , GotState -> Path , GotState -> NestLevel , RecurseFlag , DoDirs , FileFunc , & CurState ) ; if ( KeepGoing && DirDoneFunc ) KeepGoing = ( * DirDoneFunc ) ( GotState -> Path , GotState -> NestLevel ) ; closedir ( DFD ) ; DFD = NULL ; } else Ok = 0 ; if ( DFD ) closedir ( DFD ) ; } else { if ( chdir ( GotState -> Path ) == 0 ) { if ( DirStartFunc && KeepGoing ) KeepGoing = ( * DirStartFunc ) ( GotState -> Path , GotState -> NestLevel ) ; if ( KeepGoing && DirDoneFunc ) KeepGoing = ( * DirDoneFunc ) ( GotState -> Path , GotState -> NestLevel ) ; } } } free ( GotState ) ; } { int err = chdir ( WasInDir ) ; assert ( err == 0 ) ; } ExitResetDir = NULL ; return ( Ok ) ; }
normal WalkDir processes directories, then steps into them
this version processes all directories, then steps back from the deepest
normal WalkDir processes directories then steps into them this version processes all directories then steps back from the deepest