perf tools: Enhance glob string matching
Enhance strglobmatch() for supporting character classes([CHARS], complementation and ranges are also supported) and escaped special characters (\*, \? etc). Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: systemtap <systemtap@sources.redhat.com> Cc: DLE <dle-develop@lists.sourceforge.net> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Mike Galbraith <efault@gmx.de> LKML-Reference: <20100105224724.19431.56271.stgit@dhcp-100-2-132.bos.redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
fb1d2edf7e
commit
6964cd2c8e
@@ -227,16 +227,73 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Glob expression pattern matching */
|
/* Character class matching */
|
||||||
|
static bool __match_charclass(const char *pat, char c, const char **npat)
|
||||||
|
{
|
||||||
|
bool complement = false, ret = true;
|
||||||
|
|
||||||
|
if (*pat == '!') {
|
||||||
|
complement = true;
|
||||||
|
pat++;
|
||||||
|
}
|
||||||
|
if (*pat++ == c) /* First character is special */
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
while (*pat && *pat != ']') { /* Matching */
|
||||||
|
if (*pat == '-' && *(pat + 1) != ']') { /* Range */
|
||||||
|
if (*(pat - 1) <= c && c <= *(pat + 1))
|
||||||
|
goto end;
|
||||||
|
if (*(pat - 1) > *(pat + 1))
|
||||||
|
goto error;
|
||||||
|
pat += 2;
|
||||||
|
} else if (*pat++ == c)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (!*pat)
|
||||||
|
goto error;
|
||||||
|
ret = false;
|
||||||
|
|
||||||
|
end:
|
||||||
|
while (*pat && *pat != ']') /* Searching closing */
|
||||||
|
pat++;
|
||||||
|
if (!*pat)
|
||||||
|
goto error;
|
||||||
|
*npat = pat + 1;
|
||||||
|
return complement ? !ret : ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* strglobmatch - glob expression pattern matching
|
||||||
|
* @str: the target string to match
|
||||||
|
* @pat: the pattern string to match
|
||||||
|
*
|
||||||
|
* This returns true if the @str matches @pat. @pat can includes wildcards
|
||||||
|
* ('*','?') and character classes ([CHARS], complementation and ranges are
|
||||||
|
* also supported). Also, this supports escape character ('\') to use special
|
||||||
|
* characters as normal character.
|
||||||
|
*
|
||||||
|
* Note: if @pat syntax is broken, this always returns false.
|
||||||
|
*/
|
||||||
bool strglobmatch(const char *str, const char *pat)
|
bool strglobmatch(const char *str, const char *pat)
|
||||||
{
|
{
|
||||||
while (*str && *pat && *pat != '*') {
|
while (*str && *pat && *pat != '*') {
|
||||||
if (*pat == '?') {
|
if (*pat == '?') { /* Matches any single character */
|
||||||
str++;
|
str++;
|
||||||
pat++;
|
pat++;
|
||||||
} else
|
continue;
|
||||||
if (*str++ != *pat++)
|
} else if (*pat == '[') /* Character classes/Ranges */
|
||||||
|
if (__match_charclass(pat + 1, *str, &pat)) {
|
||||||
|
str++;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
else if (*pat == '\\') /* Escaped char match as normal char */
|
||||||
|
pat++;
|
||||||
|
if (*str++ != *pat++)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
/* Check wild card */
|
/* Check wild card */
|
||||||
if (*pat == '*') {
|
if (*pat == '*') {
|
||||||
|
Reference in New Issue
Block a user