1 /* Wildcard matching routines.
2 Copyright (C) 1988 Free Software Foundation
4 This file is part of GNU Tar.
6 GNU Tar is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Tar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Tar; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 * @(#)wildmat.c 1.3 87/11/06
23 From: rs@mirror.TMC.COM (Rich Salz)
24 Newsgroups: net.sources
25 Subject: Small shell-style pattern matcher
26 Message-ID: <596@mirror.TMC.COM>
27 Date: 27 Nov 86 00:06:40 GMT
29 There have been several regular-expression subroutines and one or two
30 filename-globbing routines in mod.sources. They handle lots of
31 complicated patterns. This small piece of code handles the *?[]\
32 wildcard characters the way the standard Unix(tm) shells do, with the
33 addition that "[^.....]" is an inverse character class -- it matches
34 any character not in the range ".....". Read the comments for more
37 For my application, I had first ripped off a copy of the "glob" routine
38 from within the find source, but that code is bad news: it recurses
39 on every character in the pattern. I'm putting this replacement in the
40 public domain. It's small, tight, and iterative. Compile with -DTEST
41 to get a test driver. After you're convinced it works, install in
42 whatever way is appropriate for you.
44 I would like to hear of bugs, but am not interested in additions; if I
45 were, I'd use the code I mentioned above.
48 ** Do shell-style pattern matching for ?, \, [], and * characters.
49 ** Might not be robust in face of malformed patterns; e.g., "foo[a-"
50 ** could cause a segmentation violation.
52 ** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
56 * Modified 6Nov87 by John Gilmore (hoptoad!gnu) to return a "match"
57 * if the pattern is immediately followed by a "/", as well as \0.
58 * This matches what "tar" does for matching whole subdirectories.
60 * The "*" code could be sped up by only recursing one level instead
61 * of two for each trial pattern, perhaps, and not recursing at all
62 * if a literal match of the next 2 chars would fail.
73 while (wildmat(s
, p
) == FALSE
)
92 /* Literal match with following character; fall through. */
104 /* Trailing star matches everything. */
105 return(*++p
? Star(s
, p
) : TRUE
);
107 /* [^....] means inverse character class. */
108 if (reverse
= p
[1] == '^')
110 for (last
= 0400, matched
= FALSE
; *++p
&& *p
!= ']'; last
= *p
)
111 /* This next line requires a good C compiler. */
112 if (*p
== '-' ? *s
<= *++p
&& *s
>= last
: *s
== *p
)
114 if (matched
== reverse
)
119 /* For "tar" use, matches that end at a slash also work. --hoptoad!gnu */
120 return(*s
== '\0' || *s
== '/');
136 printf("Enter pattern: ");
137 if (gets(pattern
) == NULL
)
140 printf("Enter text: ");
141 if (gets(text
) == NULL
)
144 /* Blank line; go back and get a new pattern. */
146 printf(" %d\n", wildmat(text
, pattern
));