2 * Copyright 1994 Christopher Seiwald. All rights reserved.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * glob.c - match a string against a simple pattern
10 * Understands the following patterns:
12 * * any number of characters
13 * ? any single character
14 * [a-z] any single character in the range a-z
15 * [^a-z] any single character not in the range a-z
20 * glob() - match a string against a simple pattern
24 * globchars() - build a bitlist to check for character group match
26 * 11/04/02 (seiwald) - const-ing for string literals
31 # define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) )
32 # define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */
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 do { if (!*c
++) return 1; } while (here
== c
|| *c
!= ']') ;
53 /* build character class bitlist */
54 globchars(here
, c
, bitlist
);
55 if (!CHECK_BIT(bitlist
, *(unsigned char *)s
)) return 1;
61 /* Try to match the rest of the pattern in a recursive call.
62 If the match fails we'll back up chars, retrying. */
65 /* A fast path for the last token in a pattern */
66 r
= *c
?glob(c
, s
):*s
?-1:0;
68 else if (r
< 0) return 1;
73 /* Force literal match of next char. */
74 if (!*c
|| *s
++ != *c
++) return 1;
77 if (*s
++ != c
[-1]) return 1;
85 * globchars() - build a bitlist to check for character group match
87 static void globchars (const char *s
, const char *e
, char *b
) {
91 memset(b
, '\0', BITLISTSIZE
);
92 if (*s
== '^') neg
++, s
++;
94 if (s
+2 < e
&& s
[1] == '-') {
95 for (c
= s
[0]; c
<= s
[2]; c
++) b
[c
/8] |= (1<<(c
%8));
104 for( c
= 0; c
< BITLISTSIZE
; c
++) b
[c
] ^= 0377;
107 /* Don't include \0 in either $[chars] or $[^chars] */