home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d523
/
bmake.lha
/
BMake
/
source.lzh
/
ben
/
scdir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-09
|
4KB
|
162 lines
/* scan directory for filenames matching wildcard
* (c) Copyright 1991 by Ben Eng, All Rights Reserved
*
* scdir() must be called until it returns NULL
* or else scdir_abort() must be called to free up resources
*/
#include <exec/types.h>
#include <exec/execbase.h>
#include <graphics/gfxbase.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/dosasl.h>
#include <clib/dos_protos.h>
#include <string.h>
extern struct GfxBase *GfxBase;
static struct AnchorPath AnPath;
static char *oldwild = NULL;
static LONG failure = 0;
static char *result = NULL;
#include <stdlib.h>
void
scdir_abort( void )
{
if( result ) {
free( result ); result = NULL;
}
if( oldwild ) {
free( oldwild ); oldwild = NULL;
if( !failure && GfxBase->LibNode.lib_Version >= 36L )
MatchEnd( &AnPath );
failure = -1;
}
}
#if 0
/* uncomment this routine if extern basename() does not return a
* pointer in the same string as pathname
*/
static char *
basename( char *pathname )
{
char *ptr, *filename;
for( filename = ptr = pathname; *ptr; ptr++ )
if( *ptr == '/' /* directory delimiter */
|| *ptr == ':' /* device delimiter */
) filename = ptr+1;
return( filename );
}
#else
extern char *basename( char *);
#endif
static char *
scdir_result( char *wild, char *name )
{
long size;
if( result ) {
free( result ); result = NULL;
}
if( name ) {
size = strlen( wild ) + strlen( name ) + 1;
if( result = (char *)malloc( size )) {
strcpy( result, wild );
strcpy( basename( result ), name );
return( result );
}
if( GfxBase->LibNode.lib_Version >= 36L )
MatchEnd( &AnPath );
}
return( NULL );
}
/*
* NAME
* scdir -- scans a directory for filenames matching Amiga wildcard
*
* SYNOPSIS
* filename = scdir( wildcard )
*
* char *scdir( const char *scdir )
*
* FUNCTION
* This function returns a single filename that matches the AmigaDOS
* wildcard. Consecutive calls with the same wildcard will result
* in the next filename that matches the wildcard. This function
* should be called with the same wildcard until all matching
* filenames are exhausted, at which time NULL is returned.
*
* INPUTS
* wildcard - the full pathname with wildcard to be matched
*
* RESULT
*
* filename - the next filename matching the wildcard or
* NULL if there are no more matches found or
* NULL if an error occurred
*
* BUGS
* Resources are not properly freed if scdir_abort() is never called
* or scdir() is not called until a NULL is returned. That is why
* if scdir() is used, the caller should perform an
* atexit(scdir_abort), to ensure that resources are always freed.
*
* SEE ALSO
* scdir_abort()
*
*/
char *
scdir( const char *wild )
{
int diff = 0;
if( oldwild ) {
diff = strcmp( oldwild, wild );
if( !diff && failure ) return( scdir_result( wild, NULL ));
}
if( GfxBase->LibNode.lib_Version < 36L ) {
BPTR lock;
lock = Lock( wild, MODE_OLDFILE );
if( lock ) UnLock( lock );
if( oldwild ) free( oldwild );
oldwild = strdup( wild );
if( result ) free( result );
result = strdup( wild );
failure = -1;
return( result );
}
if( !oldwild || diff ) {
if( oldwild ) free( oldwild );
oldwild = strdup( wild );
AnPath.ap_BreakBits = SIGBREAKF_CTRL_C; /* Break on these bits */
failure = MatchFirst( wild, &AnPath);
if( !failure && AnPath.ap_Info.fib_DirEntryType <= 0 ) {
return( scdir_result( wild, AnPath.ap_Info.fib_FileName ));
}
}
/* same wildcard as before */
while( !failure ) {
if( failure = MatchNext( &AnPath )) break;
if( AnPath.ap_Info.fib_DirEntryType <= 0 ) {
return( scdir_result( wild, AnPath.ap_Info.fib_FileName ));
}
}
/* failure */
/* This absolutely, positively must be called, all of the time. */
MatchEnd( &AnPath );
return( scdir_result( wild, NULL ));
}