2 * Copyright 1994 Christopher Seiwald. All rights reserved.
4 * This file is part of Jam - see jam.c for Copyright information.
7 * glob.c - match a string against a simple pattern
9 * Understands the following patterns:
11 * * any number of characters
12 * ? any single character
13 * [a-z] any single character in the range a-z
14 * [^a-z] any single character not in the range a-z
19 * glob() - match a string against a simple pattern
23 * globchars() - build a bitlist to check for character group match
25 * 11/04/02 (seiwald) - const-ing for string literals
29 #define CHECK_BIT(tab, bit) (tab[(bit)/8]&(1<<((bit)%8)))
30 /* bytes used for [chars] in compiled expr */
31 #define BITLISTSIZE 16
34 static void globchars (const char *s
, const char *e
, char *b
);
38 * glob() - match a string against a simple pattern
40 int glob (const char *c
, const char *s
) {
41 char bitlist
[BITLISTSIZE
];
46 case '\0': return *s
?-1:0;
47 case '?': if (!*s
++) return 1; break;
49 /* scan for matching ] */
51 /* k8: allow []...] and [^]...] */
55 do { if (!*c
++) return 1; } while (here
== c
|| *c
!= ']') ;
57 /* build character class bitlist */
58 globchars(here
, c
, bitlist
);
59 if (!CHECK_BIT(bitlist
, *(unsigned char *)s
)) return 1;
65 /* try to match the rest of the pattern in a recursive call */
66 /* if the match fails we'll back up chars, retrying */
69 /* a fast path for the last token in a pattern */
70 r
= *c
?glob(c
, s
):*s
?-1:0;
77 /* force literal match of next char */
78 if (!*c
|| *s
++ != *c
++) return 1;
81 if (*s
++ != c
[-1]) return 1;
89 * globchars() - build a bitlist to check for character group match
91 static void globchars (const char *s
, const char *e
, char *b
) {
95 memset(b
, '\0', BITLISTSIZE
);
96 if (*s
== '^') ++neg
, ++s
;
98 if (s
+2 < e
&& s
[1] == '-') {
99 for (c
= s
[0]; c
<= s
[2]; ++c
) b
[c
/8] |= (1<<(c
%8));
103 b
[c
/8] |= (1<<(c
%8));
106 if (neg
) for (c
= 0; c
< BITLISTSIZE
; ++c
) b
[c
] ^= 0377;
107 /* don't include \0 in either $[chars] or $[^chars] */