2009-02-28 14:41:18 +00:00
|
|
|
/*
|
2010-10-18 07:18:23 +00:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* =======================================================================
|
|
|
|
*
|
|
|
|
* Global string matching
|
|
|
|
*
|
|
|
|
* =======================================================================
|
2012-04-29 13:57:33 +00:00
|
|
|
*/
|
2009-02-28 14:41:18 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2010-10-18 15:17:31 +00:00
|
|
|
#include "header/glob.h"
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-04-29 13:57:33 +00:00
|
|
|
/*
|
|
|
|
* Like glob_match, but match PATTERN against any final segment of TEXT.
|
2010-10-18 07:18:23 +00:00
|
|
|
*/
|
|
|
|
static int
|
2012-06-07 13:40:58 +00:00
|
|
|
glob_match_after_star(char *pattern, char *text)
|
2009-02-28 14:41:18 +00:00
|
|
|
{
|
|
|
|
register char *p = pattern, *t = text;
|
|
|
|
register char c, c1;
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
while ((c = *p++) == '?' || c == '*')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
if ((c == '?') && (*t++ == '\0'))
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 1;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == '\\')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
c1 = *p;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
else
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
c1 = c;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
while (1)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
if (((c == '[') || (*t == c1)) && glob_match(p - 1, t))
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 1;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (*t++ == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Match the pattern PATTERN against the string TEXT;
|
2010-10-18 07:18:23 +00:00
|
|
|
* 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
|
2012-06-07 13:40:58 +00:00
|
|
|
glob_match(char *pattern, char *text)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
|
|
|
register char *p = pattern, *t = text;
|
|
|
|
register char c;
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
while ((c = *p++) != '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
switch (c)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
|
|
|
case '?':
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (*t == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++t;
|
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
break;
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
case '\\':
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (*p++ != *t++)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
break;
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
case '*':
|
2012-06-07 13:40:58 +00:00
|
|
|
return glob_match_after_star(p, t);
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
case '[':
|
2009-02-28 14:41:18 +00:00
|
|
|
{
|
|
|
|
register char c1 = *t++;
|
|
|
|
int invert;
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (!c1)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
invert = ((*p == '!') || (*p == '^'));
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (invert)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
p++;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
|
|
|
c = *p++;
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
while (1)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
register char cstart = c, cend = c;
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == '\\')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
cstart = *p++;
|
|
|
|
cend = cstart;
|
|
|
|
}
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
|
|
|
c = *p++;
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if ((c == '-') && (*p != ']'))
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
cend = *p++;
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (cend == '\\')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
cend = *p++;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (cend == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2009-02-28 14:41:18 +00:00
|
|
|
c = *p++;
|
|
|
|
}
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if ((c1 >= cstart) && (c1 <= cend))
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
goto match;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == ']')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
break;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (!invert)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2009-02-28 14:41:18 +00:00
|
|
|
}
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2009-02-28 14:41:18 +00:00
|
|
|
break;
|
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
match:
|
|
|
|
|
2009-02-28 14:41:18 +00:00
|
|
|
/* Skip the rest of the [...] construct that already matched. */
|
2012-06-07 13:40:58 +00:00
|
|
|
while (c != ']')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2009-02-28 14:41:18 +00:00
|
|
|
c = *p++;
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c == '\0')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2012-06-07 13:40:58 +00:00
|
|
|
else if (c == '\\')
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2009-02-28 14:41:18 +00:00
|
|
|
++p;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
}
|
2010-10-18 07:18:23 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (invert)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
|
|
|
|
2009-02-28 14:41:18 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-10-18 07:18:23 +00:00
|
|
|
default:
|
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
if (c != *t++)
|
2010-10-18 07:18:23 +00:00
|
|
|
{
|
2012-06-07 13:40:58 +00:00
|
|
|
return 0;
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
}
|
2010-10-18 07:18:23 +00:00
|
|
|
}
|
2009-02-28 14:41:18 +00:00
|
|
|
|
2012-06-07 13:40:58 +00:00
|
|
|
return *t == '\0';
|
2009-02-28 14:41:18 +00:00
|
|
|
}
|
2012-06-07 13:40:58 +00:00
|
|
|
|