diff options
Diffstat (limited to 'tools/perf/util/string.c')
| -rw-r--r-- | tools/perf/util/string.c | 96 |
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 */ |
| 231 | bool strglobmatch(const char *str, const char *pat) | 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 | /* Glob/lazy pattern matching */ | ||
| 269 | static 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 | */ | ||
| 323 | bool 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 | */ | ||
| 336 | bool strlazymatch(const char *str, const char *pat) | ||
| 337 | { | ||
| 338 | return __match_glob(str, pat, true); | ||
| 339 | } | ||
