home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zoo21-2.zip / source / nextfile.c < prev    next >
C/C++ Source or Header  |  1991-07-14  |  8KB  |  209 lines

  1. #ifndef LINT
  2. static char sccsid[]="@(#) nextfile.c 2.2 87/12/26 12:23:43";
  3. #endif /* LINT */
  4.  
  5. #include "options.h"
  6. /*
  7. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  8. */
  9. /*
  10. Functions to collect filenames from command line etc.  Nextfile() is
  11. used by both Atoz and Zoo.  Wildcard expansion by nextfile() is specific to
  12. MS-DOS and this implementation is specific to Microsoft C.  If the symbol
  13. PORTABLE is defined, nextfile() becomes effectively a no-op that will return
  14. the original filespec the first time and NULL subsequently.
  15. */
  16.  
  17. #define  FMAX  3        /* Number of different filename patterns */
  18.  
  19. #ifndef    OK_STDIO
  20. #include <stdio.h>
  21. #define    OK_STDIO
  22. #endif
  23. #include "various.h"
  24. #include "zoo.h"        /* solely to define PATHSIZE */
  25.  
  26. #ifdef PORTABLE
  27. #ifndef SPECNEXT
  28. /* If portable version, nextfile() is effectively a no-op and any wildcard
  29. expansion must be done by the runtime system before the command line
  30. is received by this program
  31. */
  32. char *nextfile (what, filespec, fileset)
  33. int what;                        /* whether to initialize or match      */
  34. register char *filespec;         /* filespec to match if initializing   */
  35. register int fileset;            /* which set of files                  */
  36. {
  37.    static int first_time [FMAX+1];
  38.    static char saved_fspec [FMAX+1][PATHSIZE];  /* our own copy of filespec */
  39.  
  40.    if (what == 0) {
  41.       strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
  42.       first_time[fileset] = 1;
  43.       return NULL;
  44.    }
  45.  
  46.    if (first_time[fileset]) {
  47.       first_time[fileset] = 0;
  48.       return saved_fspec[fileset];
  49.    } else {
  50.       return NULL;
  51.    }
  52. }
  53. #endif /* SPECNEXT */
  54. #else
  55. /* if not PORTABLE  then */
  56.  
  57. #ifndef OS2 /* the OS/2 version sits in os2.c to cleanly separate all
  58.                OS-dependent code in one module */
  59. #include <dir.h>
  60. #include <dos.h>
  61. #include "assert.h"     /* macro definition:  assert() macro            */
  62.  
  63. void fcbpath PARMS((struct ffblk *, char *, char *));
  64.  
  65.  
  66. /*******************/
  67. /*
  68. nextfile() returns the name of the next source file matching a filespec.
  69.  
  70. INPUT
  71.    what: A flag specifying what to do.  If "what" is 0, nextfile()
  72.       initializes itself.  If "what" is 1, nextfile() returns the next
  73.       matching filename.
  74.    filespec:  The filespec, usually containing wildcard characters, that
  75.       specifies which files are needed.  If "what" is 0, filespec must be
  76.       the filespec for which matching filenames are needed.  If "what" is 1,
  77.       nextfile() does not use "filespec" and "filespec" should be NULL to
  78.       avoid an assertion error during debugging.
  79.    fileset:  nextfile() can keep track of more than one set of filespecs.
  80.       The fileset specifies which filespec is being matched and therefore
  81.       which set of files is being considered.  "fileset" can be in the
  82.       range 0:FMAX.  Initialization of one fileset does not affect the
  83.       other filesets.
  84.  
  85. OUTPUT
  86.    IF what == 0 THEN
  87.       return value is NULL
  88.    ELSE IF what == 1 THEN
  89.       IF a matching filename is found THEN
  90.          return value is pointer to matching filename including supplied path
  91.       ELSE
  92.          IF at least one file matched previously but no more match THEN
  93.             return value is NULL
  94.          ELSE IF supplied filespec never matched any filename THEN
  95.             IF this is the first call with what == 1 THEN
  96.                return value is pointer to original filespec
  97.             ELSE
  98.                return value is NULL
  99.             END IF
  100.          END IF
  101.       END IF
  102.    END IF
  103.  
  104. NOTE
  105.  
  106.    Initialization done when "what"=0 is not dependent on the correctness
  107.    of the supplied filespec but simply initializes internal variables
  108.    and makes a local copy of the supplied filespec.  If the supplied
  109.    filespec was illegal, the only effect is that the first time that
  110.    nextfile() is called with "what"=1, it will return the original
  111.    filespec instead of a matching filename.  That the filespec was
  112.    illegal will become obvious when the caller attempts to open the
  113.    returned filename for input/output and the open attempt fails.
  114.  
  115. USAGE HINTS
  116.  
  117. nextfile() can be used in the following manner:
  118.  
  119.       char *filespec;                  -- will point to filespec
  120.       char *this_file;                 -- will point to matching filename
  121.       filespec = parse_command_line(); -- may contain wildcards
  122.       FILE *stream;
  123.  
  124.       nextfile (0, filespec, 0);          -- initialize fileset 0
  125.       while ((this_file = nextfile(1, (char *) NULL, 0)) != NULL) {
  126.          stream = fopen (this_file, "whatever");
  127.          if (stream == NULL)
  128.             printf ("could not open %s\n", this_file);
  129.          else
  130.             perform_operations (stream);
  131.       }
  132. */
  133.  
  134. char *nextfile (what, filespec, fileset)
  135. int what;                        /* whether to initialize or match      */
  136. register char *filespec;         /* filespec to match if initializing   */
  137. register int fileset;            /* which set of files                  */
  138. {
  139.    static struct ffblk ffblk[FMAX+1];
  140.    static int first_time [FMAX+1];
  141.    static char pathholder [FMAX+1][PATHSIZE]; /* holds a pathname to return */
  142.    static char saved_fspec [FMAX+1][PATHSIZE];/* our own copy of filespec   */
  143.     int ffretval;    /* return value from findfirst() or findnext() */
  144.  
  145.    assert(fileset >= 0 && fileset <= FMAX);
  146.    if (what == 0) {
  147.       assert(filespec != NULL);
  148.       strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
  149.       first_time[fileset] = 1;
  150.       return (NULL);
  151.    }
  152.  
  153.    assert(what == 1);
  154.    assert(filespec == NULL);
  155.    assert(first_time[fileset] == 0 || first_time[fileset] == 1);
  156.  
  157.    if (first_time[fileset])              /* first time -- initialize etc. */
  158.         ffretval = findfirst(saved_fspec[fileset], &ffblk[fileset],  0);
  159.    else
  160.         ffretval = findnext(&ffblk[fileset]);
  161.  
  162.    if (ffretval != 0) {            /* if error status                  */
  163.       if (first_time[fileset]) {       /*   if file never matched then     */
  164.          first_time[fileset] = 0;
  165.          return (saved_fspec[fileset]);/*      return original filespec    */
  166.       } else {                         /*   else                           */
  167.          first_time[fileset] = 0;      /*                                  */
  168.          return (NULL);                /*      return (NULL) for no more   */
  169.       }
  170.    } else {                                        /* a file matched */
  171.       first_time[fileset] = 0;
  172.       /* add path info  */
  173.       fcbpath (&ffblk[fileset], saved_fspec[fileset], pathholder[fileset]);
  174.       return (pathholder[fileset]);                /* matching path  */
  175.    }
  176. } /* nextfile */
  177.  
  178. /*******************/
  179. /*
  180. fcbpath() accepts a pointer to an ffblk structure, a character pointer
  181. to a pathname that may contain wildcards, and a character pointer to a
  182. buffer.  Copies into buffer the path prefix from the pathname and the
  183. filename prefix from the ffblk so that it forms a complete path.
  184. */
  185.  
  186. void fcbpath (ffblk, old_path, new_path)
  187. struct ffblk *ffblk;
  188. char *old_path;
  189. register char *new_path;
  190. {
  191.    register int i;
  192.    int length, start_pos;
  193.  
  194.    strcpy(new_path, old_path);               /* copy the whole thing first */
  195.    length = strlen(new_path);
  196.    i = length - 1;                           /* i points to end of path */
  197.    while (i >= 0 && new_path[i] != '/' && new_path[i] != '\\' && new_path[i] != ':')
  198.       i--;
  199.    /* either we found a "/", "\", or ":", or we reached the beginning of
  200.       the name.  In any case, i points to the last character of the
  201.       path part. */
  202.    start_pos = i + 1;
  203.    for (i = 0; i < 13; i++)
  204.       new_path[start_pos+i] = ffblk->ff_name[i];
  205.    new_path[start_pos+13] = '\0';
  206. }
  207. #endif /* PORTABLE */
  208. #endif /* OS2 */
  209.