diff options
Diffstat (limited to 'tools/perf/util/string.c')
-rw-r--r-- | tools/perf/util/string.c | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 5352d7dccc61..c397d4f6f748 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 */ |
231 | static 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 | |||
256 | end: | ||
257 | while (*pat && *pat != ']') /* Searching closing */ | ||
258 | pat++; | ||
259 | if (!*pat) | ||
260 | goto error; | ||
261 | *npat = pat + 1; | ||
262 | return complement ? !ret : ret; | ||
263 | |||
264 | error: | ||
265 | return false; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * strglobmatch - glob expression pattern matching | ||
270 | * @str: the target string to match | ||
271 | * @pat: the pattern string to match | ||
272 | * | ||
273 | * This returns true if the @str matches @pat. @pat can includes wildcards | ||
274 | * ('*','?') and character classes ([CHARS], complementation and ranges are | ||
275 | * also supported). Also, this supports escape character ('\') to use special | ||
276 | * characters as normal character. | ||
277 | * | ||
278 | * Note: if @pat syntax is broken, this always returns false. | ||
279 | */ | ||
231 | bool strglobmatch(const char *str, const char *pat) | 280 | bool strglobmatch(const char *str, const char *pat) |
232 | { | 281 | { |
233 | while (*str && *pat && *pat != '*') { | 282 | while (*str && *pat && *pat != '*') { |
234 | if (*pat == '?') { | 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 == '*') { |