Listing 2 Directory search utility

/* ------------------------------------------------------------
     
     char * SearchWild (const char * wpath, int & ftf)
     
     Search a directory\file path containing wildcards.
     Return each matching file, one file per call.
     Both the directory path and file name may contain
     multiple wildcards, e.g. D:\AA*\...\*BB\CC*.E??
     
     *        matches zero or more characters
     ?        matches one character
     ...      matches zero or more directories
     *...     matches one or more directories
     A*...    matches one or more, beginning with 'A'
     
     wpath:   search path, with optional wildcards
     d:\dir1\dir2\...   fully qualified
     \dir1\dir2\...     use current disk
     dir1\dir2\...      use current directory
     
     ftf:     must be 1 to initiate a new search,
              do not alter for subsequent calls
     
     return value:
       pointer to returned file name (d:\path\file)
       or NULL if no more files found

*/

#include <windows.h>

#define  DIRECTORY  FILE_ATTRIBUTE_DIRECTORY
#define  maxlev     20          /* max. directory levels */
#define  maxp       _MAX_PATH   /* max. pathname\filename length */
#define  maxp4     maxp + 4

#define  RETURN(nn,mm)  { reent[lev] = nn; --lev; return mm; }

char * SearchWild(const char * wpath, int & ftf)


{
   static HANDLE           ffh[maxlev];
   static WIN32_FIND_DATA  ffdata[maxlev];
   
   static int   lev = -1, reent[maxlev];
   static int   fstat[maxlev], ftf2[maxlev];
   static char  rpath[maxp4];
   static char  wpath1[maxlev][maxp4],
              wpath2[maxlev][maxp4],
              wpath3[maxlev][maxp4];
   
   int    stat, ii, jj;
   char   * pF, * pF1, * pF2, * pF3;
   
   if (++lev >= maxlev) goto exceed_maxlev; /* track level
                                        of reentrancy */
   
   if (ftf) ftf = 0; /* 1st time flag  */
   
   else switch (reent[lev]) /* re-entry, resume processing */
   {                        /* in current search context */
     case 1: goto Reentl;
     case 2: goto Reent2;
     case 3: goto Reent3;
     case 4: goto Reent4;
     default: FatalAppExit(0,"reent bug");
   }
   ii = strlen(wpath);                   /* check wpath arg. */
   if (ii >= maxp) goto path_toolong;
   
   /* get current D:\DIRECTORY... */
   
   stat = GetCurrentDirectory(maxp.wpathl[lev]);
   
   if (! stat) goto no_curr_dirk;

/*  if caller path begins "\" use curr. disk + caller path*/
   if (wpath[0] == '\\')
      strcpy(wpath1[lev]+2,wpath);
   
   else if (wpath[2] == '\\')          /*  if caller path
                                     begins "d:\" */
      strcpy(wpath1[lev],wpath);      /*  use caller path only */
   
   else                                /*  else use current
                                     directory */
   
   {                                   /* + "\" + caller path  */
     
     ii = strlen(wpath1[lev]) + strlen(wpath) + 1;
     if (ii >= maxp) goto path_toolong;
     strcat(wpath1[lev],"\\");
     strcat(wpath1[lev],wpath);
   }
   
   pF = wpath1[lev];
   while (pF = strstr(pF,"...\\"))   /*  replace any "xxx...\"  */
   {                                 /*         with "xxx\...\" */
      
      if (pF[-1] != '\\')
      {
         for (ii = strlen(pF); ii; ii--) pF[ii+l] = pF[ii];
         pF[0] = '\\';
      }
      pF += 4;
   }
   
   pF1 = Strchr(wpath1[lev], '*');   /*find 1st wild char. in path */
   pF2 = strchr(wpath1[lev],'?');
   pF3 = strchr(wpath1[lev], "\\...\\");
   pf = wpath1[lev] + maxp;
   if (pf1) pF = pF1;
   if (pF2 && (pf2 < pF)) pf = pf2;
   if (pF3 && (pF3 < pF)) pF = pF3;
   
   if (pF < strrchr(wpath1[lev],'\\'))
     goto wild_dirk;         /* wild char. is in a directory */

/*  no wild directories exist - wild filename possible */
   
   /* search files using wpath1 */
   
   ffh[lev] = FindFirstFile(wpathl[lev],&ffdata[lev]);
   if (ffh[lev] == INVALID_HANDLE_VALUE) RETURN(0,0)
   stat = fstat[lev] = 1;
Reent1:
   if (fstat[lev] == 2)
      stat = FindNextFile(ffh[lev].&ffdata[lev]);
   fstat[lev] = 2;
   if (! stat) RETURN(0,0)
   if (strcmp(ffdata[lev].cFileName,".") == 0)
     goto Reent1;              /* ignore "." and ".." directories */
   if (strcmp(ffdata[lev].cFileName,"..") == 0) goto Reentl;
   pF = strrchr(wpath1[lev],'\\');      /* last"\'in search path*/
   ii = strlen(ffdata[lev].cFileName);
   jj = pF - wpath1[lev] + 1;
   if (ii + jj > maxp) goto path_toolong;
   strncpy(rpath,wpath1[lev],jj);      /* build directory\filename*/
   strcpy(rpath+jj,ffdata[lev].cFileName);
   RETURN(1,rpath)                   /* return, re-enter at Reent1 */

/* directory has wild characters */

wild_dirk;
   if (pF[0] == '\\') goto wild_dots0;  /* found "\...\" */

/* 1st wild directory contains '*' or '?' */
   
   strcpy(wpath2[lev],wpath1[lev]);     /*  wpath2 = wpath1 thru
                                     wild dirk  */
   pF = wpath2[lev] + (pF - wpath1[lev]);
   while (pF[0] != '\\') pF++;          /*  eliminate final '\' */
   pF[0] = 0;
   ffh[lev] =
     FindFirstFile(wpath2[lev],&ffdata[lev]); /* search using wpath2 */
   
   if (ffh[lev] == INVALID_HANDLE_VALUE) RETURN(0,0)
   stat = fstat[lev] = 1;
Loop2;
   if (fstat[lev] == 2) stat = FindNextFile(ffh[lev],&ffdata[lev];
   fstat[lev] = 2;
   if (! stat) RETURN(0,0)
   if (!(ffdata[lev].dwfileAttributes & DIRECTORY))
     goto Loop2;     /* ignore non-directories */
   if (strcmp(ffdata[lev].cFileName,".") == 0)
     goto Loop2;           /* ignore "." and ".." directories */
   if (strcmp(ffdata[lev].cFileName,"..") == 0) goto Loop2;
   strcpy(wpath3[lev],wpath2[lev]);
   pF = strrchr(wpath3[Lev],'\\') + 1; /* wpath3 = wpath1
                                    with specific */
   ii = strlen(ffdata[lev].cFileName); /* dirk in place of
                                    wild dirk */
   ii += pF - wpath3[lev];
   if (ii > maxp) goto path_too long;
   strcpy(pF,ffdata[lev].cFileName);
   pF = wpath1[lev] + (pF - wpath3[lev]);
   pF = strchr(pF,'\\');
   jj =strlen(pF);
   if (ii + jj > maxp) goto path_toolong;
   strcpy(wpath3[lev]+ii,pF);
   ftf2[lev] = 1;
Reent2:
   pF = SearchWild(wpath3[lev],ftf2[lev]); /*  recursive search
                                        next level */
   if (! pF) goto Loop2;
   RETURN(2,rpath)                 /* return, re-enter at Reent2 */

/*  1st wild directory is "\...\" */

wild_dots0:
   strcpy(wpath2[lev],wpath1[lev]);        /*  wpath2 = wpath1 */
   pF = strstr(wpath2[lev],"\\...\\");
   for (ii = 0; pF[ii]; ii++)
     pF[ii+1] = pF[ii+5];                  /*  repl.  "\...\"
                                        with "\" */
   ftf2[lev] = 1;
Reent3:
   pF = SearchWild(wpath2[lev],ftf2[lev]); /*  recursive search
                                        next level */
   if (! pF) goto wild_dots1;
   RETURN(3,rpath)                 /*  return, re-enter at Reent3 */

wild_dots1:
   strcpy(wpath2[lev],wpath1[lev]);        /*  wpath2 = wpath1 */
   pF = strstr(wpath2[lev], "\\...\\");
   for (ii = strlen(pF); ii; ii--)
     pF[ii+2] = pF[ii];                 /*  repl. "\...\"
                                      with "\*\...\" */
   strncpy(pF, "\\*",2);
   ftf2[lev] = 1;
Reent4:
   pF = SearchWild(wpath2[lev],ftf2[lev]); /*  recursive search
                                        next levl */
   if (! pF) RETURN(0,0)
   RETURN(4,rpath)                /* return, re-enter at Reent4 */

/* fatal error exits */

exceed_maxlev:
   FatalAppExit(0,"SearchWild: exceed max directory levels");

no_curr_dirk:
   FatalAppExit(0, "SearchWild: GetCurrentDirectory() failed");

path_toolong:
   FatalAppExit(0, "SearchWild: exceed max path length");
   return 0;                      /* dummy, required by compiler */
}

/* End of File */