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 >
C/C++ Source or Header  |  1991-06-09  |  4KB  |  162 lines

  1. /*    scan directory for filenames matching wildcard
  2.  *  (c) Copyright 1991 by Ben Eng, All Rights Reserved
  3.  *
  4.  *    scdir() must be called until it returns NULL
  5.  *    or else scdir_abort() must be called to free up resources
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/execbase.h>
  10. #include <graphics/gfxbase.h>
  11. #include <dos/dos.h>
  12. #include <dos/dosextens.h>
  13. #include <dos/dosasl.h>
  14. #include <clib/dos_protos.h>
  15. #include <string.h>
  16.  
  17. extern struct GfxBase *GfxBase;
  18. static struct AnchorPath AnPath;
  19. static char *oldwild = NULL;
  20. static LONG failure = 0;
  21. static char *result = NULL;
  22.  
  23. #include <stdlib.h>
  24.  
  25. void
  26. scdir_abort( void )
  27. {
  28.     if( result ) {
  29.         free( result ); result = NULL;
  30.     }
  31.     if( oldwild ) {
  32.         free( oldwild ); oldwild = NULL;
  33.         if( !failure && GfxBase->LibNode.lib_Version >= 36L )
  34.             MatchEnd( &AnPath );
  35.         failure = -1;
  36.     }
  37. }
  38.  
  39. #if 0
  40. /* uncomment this routine if extern basename() does not return a
  41.  * pointer in the same string as pathname
  42.  */
  43. static char *
  44. basename( char *pathname )
  45. {
  46.     char *ptr, *filename;
  47.  
  48.     for( filename = ptr = pathname; *ptr; ptr++ )
  49.         if( *ptr == '/'        /* directory delimiter */
  50.             || *ptr == ':'    /* device delimiter */
  51.             ) filename = ptr+1;
  52.     return( filename );
  53. }
  54. #else
  55. extern char *basename( char *);
  56. #endif
  57.  
  58. static char *
  59. scdir_result( char *wild, char *name )
  60. {
  61.     long size;
  62.  
  63.     if( result ) {
  64.         free( result ); result = NULL;
  65.     }
  66.     if( name ) {
  67.         size = strlen( wild ) + strlen( name ) + 1;
  68.         if( result = (char *)malloc( size )) {
  69.             strcpy( result,    wild );
  70.             strcpy( basename( result ), name );
  71.             return( result );
  72.         }
  73.            if( GfxBase->LibNode.lib_Version >= 36L )
  74.             MatchEnd( &AnPath );
  75.     }
  76.     return( NULL );
  77. }
  78.  
  79. /*
  80. *    NAME
  81. *        scdir -- scans a directory for filenames matching Amiga wildcard
  82. *
  83. *    SYNOPSIS
  84. *        filename = scdir( wildcard )
  85. *
  86. *        char *scdir( const char *scdir )
  87. *
  88. *    FUNCTION
  89. *        This function returns a single filename that matches the AmigaDOS
  90. *        wildcard.  Consecutive calls with the same wildcard will result
  91. *        in the next filename that matches the wildcard.  This function
  92. *        should be called with the same wildcard until all matching
  93. *        filenames are exhausted, at which time NULL is returned.
  94. *
  95. *    INPUTS
  96. *        wildcard - the full pathname with wildcard to be matched
  97. *
  98. *    RESULT
  99. *
  100. *        filename - the next filename matching the wildcard or
  101. *            NULL if there are no more matches found or
  102. *            NULL if an error occurred
  103. *
  104. *   BUGS
  105. *        Resources are not properly freed if scdir_abort() is never called
  106. *        or scdir() is not called until a NULL is returned.  That is why
  107. *        if scdir() is used, the caller should perform an
  108. *        atexit(scdir_abort), to ensure that resources are always freed.
  109. *
  110. *   SEE ALSO
  111. *        scdir_abort()
  112. *
  113. */
  114.  
  115. char *
  116. scdir( const char *wild )
  117. {
  118.     int diff = 0;
  119.  
  120.     if( oldwild ) {
  121.         diff = strcmp( oldwild, wild );
  122.         if( !diff && failure ) return( scdir_result( wild,  NULL ));
  123.     }
  124.     if( GfxBase->LibNode.lib_Version < 36L ) {
  125.         BPTR lock;
  126.  
  127.         lock = Lock( wild, MODE_OLDFILE );
  128.         if( lock ) UnLock( lock );
  129.         if( oldwild ) free( oldwild );
  130.         oldwild = strdup( wild );
  131.         if( result ) free( result );
  132.         result = strdup( wild );
  133.         failure = -1;
  134.         return( result );
  135.     }
  136.     if( !oldwild || diff ) {
  137.         if( oldwild ) free( oldwild );
  138.         oldwild = strdup( wild );
  139.  
  140.         AnPath.ap_BreakBits = SIGBREAKF_CTRL_C; /* Break on these bits    */
  141.  
  142.         failure = MatchFirst( wild, &AnPath);
  143.  
  144.         if( !failure && AnPath.ap_Info.fib_DirEntryType <= 0 ) {
  145.             return( scdir_result( wild, AnPath.ap_Info.fib_FileName ));
  146.         }
  147.     }
  148.  
  149.     /* same wildcard as before */
  150.     while( !failure ) {
  151.         if( failure = MatchNext( &AnPath )) break;
  152.         if( AnPath.ap_Info.fib_DirEntryType <= 0 ) {
  153.             return( scdir_result( wild, AnPath.ap_Info.fib_FileName ));
  154.         }
  155.     }
  156.     /* failure */
  157.     /* This absolutely, positively must be called, all of the time. */
  158.        MatchEnd( &AnPath );
  159.     return( scdir_result( wild, NULL ));
  160. }
  161.  
  162.