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:
parent
fb1d2edf7e
commit
6964cd2c8e
|
@ -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 == '*') {
|
||||
|
|
Loading…
Reference in New Issue