aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/string.c')
-rw-r--r--tools/perf/util/string.c96
1 files changed, 91 insertions, 5 deletions
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 5352d7dccc61..a175949ed216 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -227,16 +227,73 @@ fail:
227 return NULL; 227 return NULL;
228} 228}
229 229
230/* Glob expression pattern matching */ 230/* Character class matching */
231bool strglobmatch(const char *str, const char *pat) 231static bool __match_charclass(const char *pat, char c, const char **npat)
232{
233 bool complement = false, ret = true;
234
235 if (*pat == '!') {
236 complement = true;
237 pat++;
238 }
239 if (*pat++ == c) /* First character is special */
240 goto end;
241
242 while (*pat && *pat != ']') { /* Matching */
243 if (*pat == '-' && *(pat + 1) != ']') { /* Range */
244 if (*(pat - 1) <= c && c <= *(pat + 1))
245 goto end;
246 if (*(pat - 1) > *(pat + 1))
247 goto error;
248 pat += 2;
249 } else if (*pat++ == c)
250 goto end;
251 }
252 if (!*pat)
253 goto error;
254 ret = false;
255
256end:
257 while (*pat && *pat != ']') /* Searching closing */
258 pat++;
259 if (!*pat)
260 goto error;
261 *npat = pat + 1;
262 return complement ? !ret : ret;
263
264error:
265 return false;
266}
267
268/* Glob/lazy pattern matching */
269static bool __match_glob(const char *str, const char *pat, bool ignore_space)
232{ 270{
233 while (*str && *pat && *pat != '*') { 271 while (*str && *pat && *pat != '*') {
234 if (*pat == '?') { 272 if (ignore_space) {
273 /* Ignore spaces for lazy matching */
274 if (isspace(*str)) {
275 str++;
276 continue;
277 }
278 if (isspace(*pat)) {
279 pat++;
280 continue;
281 }
282 }
283 if (*pat == '?') { /* Matches any single character */
235 str++; 284 str++;
236 pat++; 285 pat++;
237 } else 286 continue;
238 if (*str++ != *pat++) 287 } else if (*pat == '[') /* Character classes/Ranges */
288 if (__match_charclass(pat + 1, *str, &pat)) {
289 str++;
290 continue;
291 } else
239 return false; 292 return false;
293 else if (*pat == '\\') /* Escaped char match as normal char */
294 pat++;
295 if (*str++ != *pat++)
296 return false;
240 } 297 }
241 /* Check wild card */ 298 /* Check wild card */
242 if (*pat == '*') { 299 if (*pat == '*') {
@@ -251,3 +308,32 @@ bool strglobmatch(const char *str, const char *pat)
251 return !*str && !*pat; 308 return !*str && !*pat;
252} 309}
253 310
311/**
312 * strglobmatch - glob expression pattern matching
313 * @str: the target string to match
314 * @pat: the pattern string to match
315 *
316 * This returns true if the @str matches @pat. @pat can includes wildcards
317 * ('*','?') and character classes ([CHARS], complementation and ranges are
318 * also supported). Also, this supports escape character ('\') to use special
319 * characters as normal character.
320 *
321 * Note: if @pat syntax is broken, this always returns false.
322 */
323bool strglobmatch(const char *str, const char *pat)
324{
325 return __match_glob(str, pat, false);
326}
327
328/**
329 * strlazymatch - matching pattern strings lazily with glob pattern
330 * @str: the target string to match
331 * @pat: the pattern string to match
332 *
333 * This is similar to strglobmatch, except this ignores spaces in
334 * the target string.
335 */
336bool strlazymatch(const char *str, const char *pat)
337{
338 return __match_glob(str, pat, true);
339}