123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- Copyright (C) 1997-2001 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include "../wolfiphone.h"
- /* Like glob_match, but match PATTERN against any final segment of TEXT. */
- static int glob_match_after_star( char *pattern, char *text )
- {
- register char *p = pattern, *t = text;
- register char c, c1;
- while( (c = *p++) == '?' || c == '*' )
- {
- if( c == '?' && *t++ == '\0' )
- {
- return 0;
- }
- }
- if( c == '\0' )
- {
- return 1;
- }
- if( c == '\\' )
- {
- c1 = *p;
- }
- else
- {
- c1 = c;
- }
- while( 1 )
- {
- if( (c == '[' || *t == c1) && glob_match( p - 1, t ) )
- {
- return 1;
- }
- if( *t++ == '\0' )
- {
- return 0;
- }
- }
- }
- /* Return nonzero if PATTERN has any special globbing chars in it. */
- static int glob_pattern_p( char *pattern )
- {
- register char *p = pattern;
- register char c;
- int open = 0;
- while( (c = *p++) != '\0' )
- {
- switch( c )
- {
- case '?':
- case '*':
- return 1;
- case '[': /* Only accept an open brace if there is a close */
- open++; /* brace to match it. Bracket expressions must be */
- continue; /* complete, according to Posix.2 */
- case ']':
- if( open )
- {
- return 1;
- }
- continue;
- case '\\':
- if( *p++ == '\0' )
- {
- return 0;
- }
- }
- }
- return 0;
- }
- /* Match the pattern PATTERN against the string TEXT;
- return 1 if it matches, 0 otherwise.
- A match means the entire string TEXT is used up in matching.
- In the pattern string, `*' matches any sequence of characters,
- `?' matches any character, [SET] matches any character in the specified set,
- [!SET] matches any character not in the specified set.
- A set is composed of characters or ranges; a range looks like
- character hyphen character (as in 0-9 or A-Z).
- [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
- Any other character in the pattern must be matched exactly.
- To suppress the special syntactic significance of any of `[]*?!-\',
- and match the character exactly, precede it with a `\'.
- */
- int glob_match(char *pattern, char *text)
- {
- register char *p = pattern, *t = text;
- register char c;
- while ((c = *p++) != '\0')
- switch (c) {
- case '?':
- if (*t == '\0')
- return 0;
- else
- ++t;
- break;
- case '\\':
- if (*p++ != *t++)
- return 0;
- break;
- case '*':
- return glob_match_after_star(p, t);
- case '[':
- {
- register char c1 = *t++;
- int invert;
- if (!c1)
- return (0);
- invert = ((*p == '!') || (*p == '^'));
- if (invert)
- p++;
- c = *p++;
- while (1) {
- register char cstart = c, cend = c;
- if (c == '\\') {
- cstart = *p++;
- cend = cstart;
- }
- if (c == '\0')
- return 0;
- c = *p++;
- if (c == '-' && *p != ']') {
- cend = *p++;
- if (cend == '\\')
- cend = *p++;
- if (cend == '\0')
- return 0;
- c = *p++;
- }
- if (c1 >= cstart && c1 <= cend)
- goto match;
- if (c == ']')
- break;
- }
- if (!invert)
- return 0;
- break;
- match:
- /* Skip the rest of the [...] construct that already matched. */
- while (c != ']') {
- if (c == '\0')
- return 0;
- c = *p++;
- if (c == '\0')
- return 0;
- else if (c == '\\')
- ++p;
- }
- if (invert)
- return 0;
- break;
- }
- default:
- if (c != *t++)
- return 0;
- }
- return *t == '\0';
- }
|