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