home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / zoo141_c.lzh / NEEDED.C < prev    next >
C/C++ Source or Header  |  1987-02-07  |  6KB  |  192 lines

  1. /* needed.c */
  2. /*
  3. Copyright (C) 1986 Rahul Dhesi -- All rights reserved
  4. */
  5. #include "options.h"
  6. /* Accepts a filename from an archive and returns 1 if a command-line
  7.    argument filename matches it.  Otherwise returns 0. Returns
  8.    1 if no arguments were supplied (so by default, all files will
  9.    be extracted */
  10.  
  11. #include "zoo.h"
  12.  
  13. #ifdef NEEDCTYP
  14. #include <ctype.h>              /* for tolower() */
  15. #endif
  16.  
  17. #include <stdio.h>               /* solely to define NULL */
  18. #include "various.h"
  19. #include "zoofns.h"
  20. #include "debug.h"
  21.  
  22. extern int next_arg;          /* filenames start at this position */
  23. extern int arg_count;         /* count of arguments supplied to program */
  24. extern char **arg_vector;     /* vector of arguments supplied to program */
  25. /* Uses FIRST_ARG in zoo.h, so must be recompiled when switching
  26.    between Ooz and Zoo */
  27.  
  28. int needed(pathname)
  29. char *pathname;
  30. {
  31.    register int i;
  32.    register char *arg;
  33.    char *justname;
  34.  
  35.    if (arg_count <= FIRST_ARG)         /* no filenames supplied */
  36.       return (1);                   /* so all files are needed */
  37.    /* count backwards and stop if '+' is encountered */
  38.    for (i = arg_count-1;  i >= next_arg; i--) {
  39.       arg = arg_vector[i];
  40. #ifdef FOLD
  41.       strlwr(pathname); strlwr(arg);
  42. #endif
  43.       if (strcmp(arg,"+") == 0)
  44.          return (0);
  45.  
  46.       /* If the argument contains a slash, the match fails if the
  47.          path prefixes don't match */
  48.       if (strchr(arg, *PATH_CH) != NULL) {      /* found slash */
  49.          char *p;
  50.          char arg_prefix[PATHSIZE];
  51.          char path_prefix[PATHSIZE];
  52.          strcpy(arg_prefix,arg);
  53.          strcpy(path_prefix,pathname);
  54.  
  55.          p = findlast(arg_prefix, PATH_CH);
  56.          if (p != NULL)
  57.             *p = '\0';
  58.  
  59.          p = findlast(path_prefix, PATH_CH);
  60.          if (p != NULL)
  61.             *p = '\0';
  62.  
  63. #ifdef DEBUG
  64.       printf("match:  prefix compare between [%s] and [%s]\n",
  65.                   path_prefix, arg_prefix);
  66. #endif
  67.  
  68.          if (!match_half(path_prefix, arg_prefix)) {
  69. #ifdef DEBUG
  70.       printf ("match:  prefix match failed\n");
  71. #endif
  72.             continue;                     /* no match this time in loop */
  73.          }
  74.  
  75.  
  76.       }
  77.  
  78.       /*
  79.       We reach here either if the pattern had no slashes, or if it
  80.       had a slash but the path prefixes matched.  Now we test to see 
  81.       if the filename parts match.
  82.       */
  83.  
  84.       if (match (pathname, arg))       /* match with dot special */
  85.          return (1);
  86.       /* 
  87.       if supplied pattern contains "**", then do a full match also 
  88.       */
  89.       if (index(arg,"**") != -1 && match_half(nameptr(pathname),arg))
  90.          return (1);
  91.  
  92. #ifdef DEBUG
  93.       printf("needed:  matching [%s] and [%s]\n", arg, pathname);
  94. #endif
  95.  
  96.       /* try for a character range */
  97.       justname = nameptr(pathname);
  98.       if (match_half (arg, "?-?")) { /* character range given */
  99.          if (arg[0] <= *justname && arg[2] >= *justname)
  100.             return (1);
  101.       }
  102.    }
  103.    return (0);
  104.  
  105. } /* needed */
  106.  
  107. /********************/
  108. /*
  109. match() compares a name with a pattern, with EXT_CH treated specially.
  110. EXT_CH is assumed to separate a filename from its extension.  Both are
  111. matched separately.
  112. */
  113. int match(name, pattern)            /* compare names including * and ? */
  114. register char *name, *pattern;
  115. {
  116.    /* will hold half the name */
  117.    char half1[LFNAMESIZE], half2[LFNAMESIZE]; 
  118.    rootname (name, half1);          /* get root name minus extension */
  119.    rootname (pattern, half2);
  120.  
  121.    debug ((printf ("match:  root names are [%s] and [%s].\n", half1, half2)))
  122.  
  123.    if (!match_half (half1, half2))     /* if roots don't match */
  124.       return (0);                      /* ... then names don't match */
  125.  
  126.    extension (name, half1);            /* get extension */
  127.    extension (pattern, half2);
  128.  
  129.    debug((printf ("match:  extensions are [%s] and [%s].\n", half1, half2)))
  130.  
  131.    /* if name's extension is null, we force it to also match pattern if 
  132.    pattern's extension contains only "*" characters.  Thus "*.*" will
  133.    match filenames without extensions too */
  134.    if (*half1 == '\0')  {              /* if null extension */
  135.       char *p = half2;
  136.       debug((printf ("match:  extension is null.\n")))
  137.       while (*p == '*')
  138.          p++;
  139.       if (*p == '\0')               /* if pattern is only *, success */
  140.          return (1);
  141.    }
  142.  
  143.    debug((printf ("name's extension = [%s].\n", half1)))
  144.    debug((printf ("pattern's extension = [%s].\n", half2)))
  145.    return (match_half (half1, half2));
  146. }
  147.  
  148. /***********************/
  149. /*
  150. match_half() compares a pattern with a string.  Wildcards accepted in
  151. the pattern are:  "*" for zero or more arbitrary characters;  "?"
  152. for any one characters.  Unlike the MS-DOS wildcard match, "*" is
  153. correctly handled even if it isn't at the end of the pattern. ".'
  154. is not special.
  155.  
  156. Originally written by Jeff Damens of Columbia University Center for
  157. Computing Activities.  Taken from the source code for C-Kermit version
  158. 4C.
  159. */
  160.  
  161. int match_half (string, pattern) 
  162. register char *string, *pattern;
  163. {
  164.    char *psave,*ssave;        /* back up pointers for failure */
  165.    psave = ssave = NULL;
  166.    while (1) {
  167. #ifdef IGNORECASE
  168.       for (; 
  169.          tolower(*pattern) == tolower(*string); 
  170.          pattern++,string++                        )  /* skip first */
  171. #else
  172.       for (; *pattern == *string; pattern++,string++)  /* skip first */
  173. #endif /* IGNORECASE */
  174.  
  175.          if (*string == '\0') 
  176.             return(1);                          /* end of strings, succeed */
  177.       if (*string != '\0' && *pattern == '?') {
  178.          pattern++;                             /* '?', let it match */
  179.          string++;
  180.       } else if (*pattern == '*') {             /* '*' ... */
  181.          psave = ++pattern;                     /* remember where we saw it */
  182.          ssave = string;                        /* let it match 0 chars */
  183.       } else if (ssave != NULL && *ssave != '\0') {   /* if not at end  */
  184.          /* ...have seen a star */
  185.          string = ++ssave;                      /* skip 1 char from string */
  186.          pattern = psave;                       /* and back up pattern */
  187.       } else 
  188.          return(0);                             /* otherwise just fail */
  189.    }
  190. }
  191.  
  192.