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:
Masami Hiramatsu 2010-01-05 17:47:24 -05:00 committed by Ingo Molnar
parent fb1d2edf7e
commit 6964cd2c8e
1 changed files with 61 additions and 4 deletions

View File

@ -227,16 +227,73 @@ fail:
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)
{
while (*str && *pat && *pat != '*') {
if (*pat == '?') {
if (*pat == '?') { /* Matches any single character */
str++;
pat++;
} else
if (*str++ != *pat++)
continue;
} else if (*pat == '[') /* Character classes/Ranges */
if (__match_charclass(pat + 1, *str, &pat)) {
str++;
continue;
} else
return false;
else if (*pat == '\\') /* Escaped char match as normal char */
pat++;
if (*str++ != *pat++)
return false;
}
/* Check wild card */
if (*pat == '*') {