home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / wildf113.arj / WILDFILE.C < prev    next >
C/C++ Source or Header  |  1991-03-31  |  9KB  |  346 lines

  1. /*
  2.  EPSHeader
  3.  
  4.    File: wildfile.c
  5.    Author: J. Kercheval
  6.    Created: Thu, 03/14/1991  21:49:02
  7. */
  8. /*
  9.  EPSRevision History
  10.  
  11.    J. Kercheval  Sat, 03/16/1991  15:48:38  add and use FileInfo struct
  12.    J. Kercheval  Sat, 03/16/1991  20:30:52  add status byte and '.' checking
  13.    J. Kercheval  Sat, 03/16/1991  22:50:42  _FA_NORMAL files unique, similar to _FA_READONLY behavior
  14.    J. Kercheval  Thu, 03/28/1991  21:23:37  move DOT_LAST to find_firstfile
  15.    J. Kercheval  Sun, 03/31/1991  14:31:15  change '/' to '\\' in path
  16. */
  17.  
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #include "wildfile.h"
  22. #include "filmatch.h"
  23.  
  24. #ifndef __TURBOC__
  25. # define findfirst(n, a, s) _dos_findfirst(n, s, a)
  26. # define findnext _dos_findnext
  27. #endif
  28.  
  29. #define DOT_LAST 0x01   /* set status byte if last char in pattern is '.' */
  30.  
  31. void splitpath( FileInfo *ff );
  32.  
  33.  
  34. /*----------------------------------------------------------------------------
  35. *
  36. *   Start of find_firstfile()
  37. *
  38. ----------------------------------------------------------------------------*/
  39.  
  40. BOOLEAN find_firstfile( FileInfo *ff )
  41. {
  42.     char path[MAXPATH+1];           /* found file and path */\
  43.     char *c;                        /* temporary pointer variable */
  44.  
  45.     int error_return;               /* error return from is_valid_pattern */
  46.  
  47.     BOOLEAN found;                  /* looping flag */
  48.     BOOLEAN dot_found;              /* '.' character checking */
  49.  
  50.     /* empty strings are bummers, aren't they? */
  51.     if ( !*(ff->file_pattern) ) {
  52.         return FALSE;
  53.     }
  54.  
  55.     /* convert to upper case */
  56.     c = ff->file_pattern;
  57.     while ( *c ) {
  58.         *c = (char) toupper(*c);
  59.  
  60.         /* if the last pattern char is '.' then set status byte correctly */
  61.         if ( *c == '.' )
  62.             ff->status |= DOT_LAST;
  63.         else
  64.             ff->status &= ~DOT_LAST;
  65.  
  66.         c++;
  67.     }
  68.  
  69.     /* check for valid pattern string */
  70.     if ( !is_valid_pattern(ff->file_pattern,&error_return) ) {
  71.         return FALSE;
  72.     }
  73.  
  74.     /* copy the path portion of the pattern to file_path */
  75.     splitpath( ff );
  76.  
  77.     /* create the search path */
  78.     strcpy(path,ff->file_path);
  79.     strcat(path,"*.*");
  80.  
  81.     /* check that the search path will not be too long */
  82.     if ( strlen(path) > MAXPATH ) {
  83.         return FALSE;
  84.     }
  85.  
  86.     /* obtain the first file conforming to path */
  87.     if ( findfirst(path, &(ff->file), (ff->file_attributes) & ~_FA_NORMAL) ) {
  88.         return(FALSE);
  89.     }
  90.  
  91.     /* if the file name is empty we want it not */
  92.     if ( !*(ff->file.name) ) {
  93.         return(FALSE);
  94.     }
  95.  
  96.     /* init looping variable */
  97.     found = FALSE;
  98.  
  99.     /* Build path and file name needed for validation */
  100.     strcpy(path,ff->file_path);
  101.     strcat(path,ff->file.name);
  102.  
  103.     /* Check for '.' if required */
  104.     if ( ff->status & DOT_LAST ) {
  105.  
  106.         /* init looping variables */
  107.         dot_found = FALSE;
  108.         c = ff->file.name;
  109.  
  110.         /* see if file has extension and give it '.' if not */
  111.         while ( *c ) {
  112.             if ( *c == '.' )
  113.                 dot_found = TRUE;
  114.             c++;
  115.         }
  116.         if ( !dot_found )
  117.             strcat(path,".");
  118.     }
  119.  
  120.     /* Verify name and attribute wanted for files */
  121.     if ( match(ff->file_pattern,path) ) {
  122.  
  123.         if ( !ff->file.attributes ) {
  124.             if ( ff->file_attributes & _FA_NORMAL ) {
  125.                 found = TRUE;
  126.             }
  127.         }
  128.         else {
  129.             if ( ff->file_attributes & ff->file.attributes ) {
  130.                 found = TRUE;
  131.             }
  132.         }
  133.     }
  134.  
  135.     while ( !found ) {
  136.  
  137.         /* obtain the next file comforming to path */
  138.         if ( findnext(&(ff->file)) ) {
  139.             return(FALSE);
  140.         }
  141.  
  142.         /* if the file name is empty we want it not */
  143.         if ( !*(ff->file.name) ) {
  144.             return(FALSE);
  145.         }
  146.  
  147.         /* Build path and file name needed for validation */
  148.         strcpy(path,ff->file_path);
  149.         strcat(path,ff->file.name);
  150.  
  151.         /* Check for '.' if required */
  152.         if ( ff->status & DOT_LAST ) {
  153.  
  154.             /* init looping variables */
  155.             dot_found = FALSE;
  156.             c = ff->file.name;
  157.  
  158.             /* see if file has extension and give it '.' if not */
  159.             while ( *c ) {
  160.                 if ( *c == '.' )
  161.                     dot_found = TRUE;
  162.                 c++;
  163.             }
  164.             if ( !dot_found )
  165.                 strcat(path,".");
  166.         }
  167.  
  168.         /* Verify name and attribute wanted for files */
  169.         if ( match(ff->file_pattern, path) ) {
  170.  
  171.             if ( !ff->file.attributes ) {
  172.                 if ( ff->file_attributes & _FA_NORMAL ) {
  173.                     found = TRUE;
  174.                 }
  175.             }
  176.             else {
  177.                 if ( ff->file_attributes & ff->file.attributes ) {
  178.                     found = TRUE;
  179.                 }
  180.             }
  181.         }
  182.     }
  183.  
  184.     return(TRUE);
  185. }
  186.  
  187.  
  188. /*----------------------------------------------------------------------------
  189. *
  190. *   Start of splitpath()
  191. *       This is a helper function to isolate the pattern from the path.
  192. *       The parameter r gets the path portion of the pattern string p.
  193. *
  194. ----------------------------------------------------------------------------*/
  195.  
  196. void splitpath( FileInfo *ff )
  197. {
  198.     char *last_slash, *c, oldchar;
  199.  
  200.     /* init last_slash and c */
  201.     c = last_slash = ff->file_pattern;
  202.     last_slash--;
  203.  
  204.     /* loop through and find the beginning of the pattern or end of string */
  205.     while ( *c && *c != '[' && *c != '*' && *c != '?' ) {
  206.  
  207.         /* change '/' to '\' */
  208.         if ( *c == '/' ) {
  209.             *c = '\\';
  210.         }
  211.         
  212.         /* if c is a '\' then remember where it is */
  213.         if ( *c == '\\' ) {
  214.             last_slash = c;
  215.         }
  216.  
  217.         /* move to next char in pattern */
  218.         c++;
  219.     }
  220.  
  221.     /* move to next char beyond '\' or to beginning of string*/
  222.     last_slash++;
  223.  
  224.     /* store character and make it end of string for now */
  225.     oldchar = *last_slash;
  226.     *last_slash = '\0';
  227.  
  228.     /* copy the beginning of the path to return value */
  229.     strcpy(ff->file_path, ff->file_pattern);
  230.  
  231.     /* restore character */
  232.     *last_slash = oldchar;
  233. }
  234.  
  235.  
  236. /*----------------------------------------------------------------------------
  237. *
  238. *   Start of find_nextfile()
  239. *
  240. ----------------------------------------------------------------------------*/
  241.  
  242. BOOLEAN find_nextfile( FileInfo *ff )
  243. {
  244.     char path[MAXPATH+1];   /* full filename and path for pattern checking */
  245.     char *c;                /* tempory pointer variable */
  246.  
  247.     BOOLEAN found;          /* looping flag */
  248.     BOOLEAN dot_found;      /* '.' character checking */
  249.  
  250.     found = FALSE;
  251.  
  252.     while ( !found ) {
  253.  
  254.         /* obtain the next file comforming to path */
  255.         if ( findnext(&(ff->file)) ) {
  256.             return(FALSE);
  257.         }
  258.  
  259.         /* if the file name is empty we want it not */
  260.         if ( !*(ff->file.name) ) {
  261.             return(FALSE);
  262.         }
  263.  
  264.         /* Build path and file name needed for validation */
  265.         strcpy(path,ff->file_path);
  266.         strcat(path,ff->file.name);
  267.  
  268.         /* Check for '.' if required */
  269.         if ( ff->status & DOT_LAST ) {
  270.  
  271.             /* init looping variables */
  272.             dot_found = FALSE;
  273.             c = ff->file.name;
  274.  
  275.             /* see if file has extension and give it '.' if not */
  276.             while ( *c ) {
  277.                 if ( *c == '.' )
  278.                     dot_found = TRUE;
  279.                 c++;
  280.             }
  281.             if ( !dot_found )
  282.                 strcat(path,".");
  283.         }
  284.  
  285.         /* Verify name and attribute wanted for files */
  286.         if ( match(ff->file_pattern, path) ) {
  287.  
  288.             if ( !ff->file.attributes ) {
  289.                 if ( ff->file_attributes & _FA_NORMAL ) {
  290.                     found = TRUE;
  291.                 }
  292.             }
  293.             else {
  294.                 if ( ff->file_attributes & ff->file.attributes ) {
  295.                     found = TRUE;
  296.                 }
  297.             }
  298.         }
  299.     }
  300.  
  301.     return(TRUE);
  302. }
  303.  
  304.  
  305. #ifdef TEST
  306.  
  307.     /*
  308.     * The test loop expects the first input parameter on the command line
  309.     * to be the attributes desired in hex format (ie. 0x3f) and the
  310.     * following parameters to be the search path/file name.  Will output
  311.     * the names of all files which match the attributes wanted and the
  312.     * search path/file names.
  313.     */
  314.  
  315.     #include <stdio.h>
  316.  
  317.     int main(int argc, char *argv[])
  318.     {
  319.         FileInfo ff;
  320.  
  321.         unsigned int  tmp;
  322.  
  323.         /* parse the attribute from the command line */
  324.         sscanf(argv[1],"%x",&tmp);
  325.         ff.file_attributes = (unsigned char) tmp;
  326.  
  327.         /* trace down the argument list until all file specs are parsed */
  328.         argc--; argv++;
  329.         argc--; argv++;
  330.         while ( argc>0 ) {
  331.             strcpy(ff.file_pattern,*argv);
  332.  
  333.             if ( find_firstfile(&ff) ) {
  334.                 printf("File: %s%s\n",ff.file_path,ff.file.name);
  335.             }
  336.  
  337.             while ( find_nextfile(&ff) ) {
  338.                 printf("File: %s%s\n",ff.file_path,ff.file.name);
  339.             }
  340.             argc--; argv++;
  341.         }
  342.         return(0);
  343.     }
  344.  
  345. #endif
  346.