home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / archiver / rblharc / wild.c < prev   
C/C++ Source or Header  |  1993-07-08  |  7KB  |  261 lines

  1. /*
  2.  * expansion of lharc's filename handling
  3.  * Robert Stabl April 1990
  4.  * 
  5.  * see copyright notice below
  6.  *
  7.  * Wild card expansion
  8.  *
  9.  * $Id: wild.c,v 1.3 1991/06/05 13:55:14 bammi Exp $
  10.  *
  11.  * $Log: wild.c,v $
  12.  * Revision 1.3  1991/06/05  13:55:14  bammi
  13.  * minor patches
  14.  *
  15.  * Revision 1.2  1990/12/16  14:02:16  bammi
  16.  * cleanup
  17.  *
  18.  * Revision 1.1  90/08/30  16:52:57  bammi
  19.  * after asm
  20.  * 
  21.  * Revision 1.4  89/02/20  20:03:40  dclemans
  22.  * Add RCS identifiers
  23.  * 
  24.  */
  25. #include <stdio.h>
  26. #ifdef atarist
  27. #include <stdlib.h>
  28. #endif
  29. #include <sys/types.h>
  30. #ifndef USG
  31. #include <sys/dir.h>
  32. #else
  33. #include <dirent.h>
  34. #endif  /* USG */
  35.  
  36. #define ESCAPE_CHAR    '\\'
  37. #define DIR_SEPARATOR    '/'
  38. #define WILDCARDS       "*?["
  39.  
  40. #define new_string(a)    (char *)malloc((size_t)(a))
  41.  
  42. /**** Start of "glob" package ****/
  43. /* This software is copyright (c) 1986 by Stichting Mathematisch Centrum.
  44.  * You may use, modify and copy it, provided this notice is present in all
  45.  * copies, modified or unmodified, and provided you don't make money for it.
  46.  *
  47.  * Written 86-jun-28 by Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>
  48.  * Stripped down for local use, more portability by Dave Clemans
  49.  */
  50.  
  51. /* Pattern matching function for filenames */
  52. /* Each occurrence of the * pattern causes a recursion level */
  53.  
  54. #define EOS '\0'
  55.  
  56. #define BOOL int
  57. #define NO 0
  58. #define YES 1
  59.  
  60. #define M_ALL '\001'        /* * */
  61. #define M_ONE '\002'        /* ? */
  62. #define M_SET '\003'        /* [ */
  63. #define M_CMP '\004'        /* ^ */
  64. #define M_RNG '\005'        /* - */
  65. #define M_END '\006'        /* ] */
  66.  
  67. static BOOL match(name, pat)
  68.     char *name;
  69.     char *pat;
  70. {
  71.     register char c, k;
  72.     BOOL ok,cmp;
  73.  
  74.     for (c = *pat++; c != EOS; c = *pat++) {
  75.         switch (c) {
  76.  
  77.         case M_ONE:
  78.             if (*name++ == EOS)
  79.                 return NO;
  80.             break;
  81.  
  82.         case M_ALL:
  83.             if (*pat == EOS)
  84.                 return YES;
  85.             for (; *name != EOS; ++name) {
  86.                 if (match(name, pat))
  87.                     return YES;
  88.             }
  89.             return NO;
  90.  
  91.         case M_SET:
  92.             cmp= NO;
  93.             ok= NO;
  94.             k= *name++;
  95.             while ((c= *pat++) != M_END) {
  96.                 if (c == M_CMP)
  97.                     cmp= YES;
  98.                 else if (*pat == M_RNG) {
  99.                     if (c <= k && k <= pat[1])
  100.                         ok= YES;
  101.                     pat += 2;
  102.                 }
  103.                 else if (c == k)
  104.                     ok= YES;
  105.             }
  106.             if (!cmp && !ok)
  107.                 return NO;
  108.             if (cmp && ok)
  109.                 return NO;
  110.             break;
  111.  
  112.         default:
  113.             if (*name++ != c)
  114.                 return NO;
  115.             break;
  116.  
  117.         }
  118.     }
  119.     return *name == EOS;
  120. }
  121. /**** End of "glob" package ****/
  122.  
  123. char *wild_compile(pattern,upcase)
  124. char *pattern;
  125. int upcase;
  126. {
  127.     register char *compiled;
  128.     register char *in,*out;
  129.  
  130.     compiled = (char *)malloc((size_t)(strlen(pattern)+1));
  131.     if (compiled == (char *)NULL)
  132.     {   /* enough memory? */
  133.         fprintf(stderr,"Not enough memory\n");
  134.         return (char *)NULL;
  135.     }
  136.     out = compiled;
  137.     for (in = pattern; *in; in++)
  138.     {   /* copy, "compiling" the pattern */
  139.         switch (*in)
  140.         {   /* a "special" character? */
  141.             case '\'':
  142.                 in++;
  143.                 while (*in && *in != '\'')
  144.                     *out++ = *in++;
  145.                 if (*in != '\'')
  146.                     break;
  147.                 break;
  148.             case '"':
  149.                 in++;
  150.                 while (*in && *in != '"')
  151.                 {   /* scan the string */
  152.                     if (*in == ESCAPE_CHAR)
  153.                     {   /* embedded escape char? */
  154.                         in++;
  155.                         if (*in == '\0')
  156.                             break;
  157.                     }
  158.                     *out++ = *in++;
  159.                 }
  160.                 if (*in != '"')
  161.                     break;
  162.                 break;
  163.             case ESCAPE_CHAR:
  164.                 in++;
  165.                 if (*in == '\0')
  166.                     break;
  167.                 *out++ = *in;
  168.                 break;
  169.             case '*':
  170.                 *out++ = M_ALL;
  171.                 break;
  172.             case '?':
  173.                 *out++ = M_ONE;
  174.                 break;
  175.             case '[':
  176.                 *out++ = M_SET;
  177.                 in++;
  178.                 while (*in && *in != ']')
  179.                 {   /* scan the set */
  180.                     if (*in == '-' &&
  181.                        (in[-1] == '[' || (in[-1] == '^' && in[-2] == '[')))
  182.                         *out++ = '-';
  183.                     else if (*in == '-')
  184.                         *out++ = M_RNG;
  185.                     else if (*in == '^' && in[-1] == '[')
  186.                         *out++ = M_CMP;
  187.                     else if (*in == '^')
  188.                         *out++ = '^';
  189.                     else if (*in == ESCAPE_CHAR && in[1] != '\0')
  190.                         *out++ = *++in;
  191.                     else if (*in == ESCAPE_CHAR)
  192.                         *out++ = ESCAPE_CHAR;
  193.                     else *out++ = *in;
  194.                     in++;
  195.                 }
  196.                 if (*in != ']')
  197.                 {   /* if error found */
  198.                     fprintf(stderr,"incomplete character class: missing ']'\n");
  199.                     free(compiled);
  200.                     return (char *)NULL;
  201.                 }
  202.                 *out++ = M_END;
  203.                 break;
  204.             default:
  205.                 *out++ = *in;
  206.                 break;
  207.         }
  208.         if (*in == '\0')
  209.             break;
  210.     }
  211. #ifdef  GEMDOS
  212.     *out = '\0';
  213.     for (out = compiled; *out; out++)
  214.     {   /* fixups for mono-case matching */
  215.         if (!upcase)
  216.             continue;
  217.         if (islower(*out))
  218.             *out = _toupper(*out);
  219.     }
  220. #endif  /* GEMDOS */
  221.     *out = '\0';
  222.  
  223.     /* finally done, return compiled string */
  224.     return compiled;
  225. }   /* end of wild_compile */
  226.  
  227. int wild_match(string,pattern)
  228. char *string;
  229. char *pattern;
  230. {
  231.     register char *compiled;
  232.     int rc;
  233.  
  234.     if (string == NULL || pattern == NULL)
  235.      {
  236.       return 0;
  237.      }
  238.     compiled = wild_compile(pattern,0);
  239.     if (compiled == (char *)NULL)
  240.     {   /* any errors? message already printed */
  241.         return 0;
  242.     }
  243.     rc = match(string,compiled);
  244.     free(compiled);
  245.     return rc;
  246. }   /* end of wild_match */
  247.  
  248. #ifdef TEST
  249. int main(void)
  250. {
  251.  char string[100];
  252.  char pattern[100];
  253.  
  254.  printf("pattern> "); fflush(stdout); gets(pattern);
  255.  printf("string> "); fflush(stdout); gets(string);
  256.  
  257.  printf("wild_match(%s, %s) = %d\n",string, pattern, wild_match(string, pattern));
  258.  return(0);
  259. #endif
  260.