home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / g / gtak212.zip / 1.10 / wildmat.c < prev   
C/C++ Source or Header  |  1992-09-02  |  5KB  |  174 lines

  1. /*****************************************************************************
  2.  * $Id: wildmat.c,v 1.2 1992/09/02 20:09:01 ak Exp $
  3.  *****************************************************************************
  4.  * $Log: wildmat.c,v $
  5.  * Revision 1.2  1992/09/02  20:09:01  ak
  6.  * Version AK200
  7.  * - Tape access
  8.  * - Quick file access
  9.  * - OS/2 extended attributes
  10.  * - Some OS/2 fixes
  11.  * - Some fixes of Kai Uwe Rommel
  12.  *
  13.  * Revision 1.1.1.1  1992/09/02  19:23:11  ak
  14.  * Original GNU Tar 1.10 with some filenames changed for FAT compatibility.
  15.  *
  16.  * Revision 1.1  1992/09/02  19:23:09  ak
  17.  * Initial revision
  18.  *
  19.  *****************************************************************************/
  20.  
  21. static char *rcsid = "$Id: wildmat.c,v 1.2 1992/09/02 20:09:01 ak Exp $";
  22.  
  23. /* Wildcard matching routines.
  24.    Copyright (C) 1988 Free Software Foundation
  25.  
  26. This file is part of GNU Tar.
  27.  
  28. GNU Tar is free software; you can redistribute it and/or modify
  29. it under the terms of the GNU General Public License as published by
  30. the Free Software Foundation; either version 1, or (at your option)
  31. any later version.
  32.  
  33. GNU Tar is distributed in the hope that it will be useful,
  34. but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36. GNU General Public License for more details.
  37.  
  38. You should have received a copy of the GNU General Public License
  39. along with GNU Tar; see the file COPYING.  If not, write to
  40. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  41.  
  42. /*
  43.  * @(#)wildmat.c 1.3 87/11/06
  44.  *
  45. From: rs@mirror.TMC.COM (Rich Salz)
  46. Newsgroups: net.sources
  47. Subject: Small shell-style pattern matcher
  48. Message-ID: <596@mirror.TMC.COM>
  49. Date: 27 Nov 86 00:06:40 GMT
  50.  
  51. There have been several regular-expression subroutines and one or two
  52. filename-globbing routines in mod.sources.  They handle lots of
  53. complicated patterns.  This small piece of code handles the *?[]\
  54. wildcard characters the way the standard Unix(tm) shells do, with the
  55. addition that "[^.....]" is an inverse character class -- it matches
  56. any character not in the range ".....".  Read the comments for more
  57. info.
  58.  
  59. For my application, I had first ripped off a copy of the "glob" routine
  60. from within the find source, but that code is bad news:  it recurses
  61. on every character in the pattern.  I'm putting this replacement in the
  62. public domain.  It's small, tight, and iterative.  Compile with -DTEST
  63. to get a test driver.  After you're convinced it works, install in
  64. whatever way is appropriate for you.
  65.  
  66. I would like to hear of bugs, but am not interested in additions; if I
  67. were, I'd use the code I mentioned above.
  68. */
  69. /*
  70. **  Do shell-style pattern matching for ?, \, [], and * characters.
  71. **  Might not be robust in face of malformed patterns; e.g., "foo[a-"
  72. **  could cause a segmentation violation.
  73. **
  74. **  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
  75. */
  76.  
  77. /*
  78.  * Modified 6Nov87 by John Gilmore (hoptoad!gnu) to return a "match"
  79.  * if the pattern is immediately followed by a "/", as well as \0.
  80.  * This matches what "tar" does for matching whole subdirectories.
  81.  *
  82.  * The "*" code could be sped up by only recursing one level instead
  83.  * of two for each trial pattern, perhaps, and not recursing at all
  84.  * if a literal match of the next 2 chars would fail.
  85.  */
  86. #define TRUE        1
  87. #define FALSE        0
  88.  
  89.  
  90. static int
  91. Star(s, p)
  92.     register char    *s;
  93.     register char    *p;
  94. {
  95.     while (wildmat(s, p) == FALSE)
  96.     if (*++s == '\0')
  97.         return(FALSE);
  98.     return(TRUE);
  99. }
  100.  
  101.  
  102. int
  103. wildmat(s, p)
  104.     register char    *s;
  105.     register char    *p;
  106. {
  107.     register int      last;
  108.     register int      matched;
  109.     register int      reverse;
  110.  
  111.     for ( ; *p; s++, p++)
  112.     switch (*p) {
  113.         case '\\':
  114.         /* Literal match with following character; fall through. */
  115.         p++;
  116.         default:
  117.         if (*s != *p)
  118.             return(FALSE);
  119.         continue;
  120.         case '?':
  121.         /* Match anything. */
  122.         if (*s == '\0')
  123.             return(FALSE);
  124.         continue;
  125.         case '*':
  126.         /* Trailing star matches everything. */
  127.         return(*++p ? Star(s, p) : TRUE);
  128.         case '[':
  129.         /* [^....] means inverse character class. */
  130.         if (reverse = p[1] == '^')
  131.             p++;
  132.         for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
  133.             /* This next line requires a good C compiler. */
  134.             if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
  135.             matched = TRUE;
  136.         if (matched == reverse)
  137.             return(FALSE);
  138.         continue;
  139.     }
  140.  
  141.     /* For "tar" use, matches that end at a slash also work. --hoptoad!gnu */
  142.     return(*s == '\0' || *s == '/');
  143. }
  144.  
  145.  
  146. #ifdef    TEST
  147. #include <stdio.h>
  148.  
  149. extern char    *gets();
  150.  
  151.  
  152. main()
  153. {
  154.     char     pattern[80];
  155.     char     text[80];
  156.  
  157.     while (TRUE) {
  158.     printf("Enter pattern:  ");
  159.     if (gets(pattern) == NULL)
  160.         break;
  161.     while (TRUE) {
  162.         printf("Enter text:  ");
  163.         if (gets(text) == NULL)
  164.         exit(0);
  165.         if (text[0] == '\0')
  166.         /* Blank line; go back and get a new pattern. */
  167.         break;
  168.         printf("      %d\n", wildmat(text, pattern));
  169.     }
  170.     }
  171.     exit(0);
  172. }
  173. #endif    /* TEST */
  174.