From: Michael Jeanson Date: Wed, 7 Apr 2021 00:17:04 +0000 (-0400) Subject: Move string-utils.h to 'src/common/' X-Git-Tag: v2.13.0-rc1~113 X-Git-Url: http://git.liburcu.org/?a=commitdiff_plain;h=b8aa6f43348c4eaf4b266a772a623110e7fd9198;p=lttng-ust.git Move string-utils.h to 'src/common/' Change-Id: I2c56997580f40728d60701b7e899af8bc8f4bd57 Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- diff --git a/src/common/Makefile.am b/src/common/Makefile.am index f89dd1c3..f5345041 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -145,6 +145,8 @@ libcommon_la_SOURCES = \ getenv.h \ logging.c \ logging.h \ + strutils.c \ + strutils.h \ patient.c libcommon_la_LIBADD = \ diff --git a/src/common/strutils.c b/src/common/strutils.c new file mode 100644 index 00000000..fadfe495 --- /dev/null +++ b/src/common/strutils.c @@ -0,0 +1,322 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2017 Philippe Proulx + */ + +#define _LGPL_SOURCE +#include +#include +#include +#include + +#include "common/strutils.h" + +enum star_glob_pattern_type_flags { + STAR_GLOB_PATTERN_TYPE_FLAG_NONE = 0, + STAR_GLOB_PATTERN_TYPE_FLAG_PATTERN = 1, + STAR_GLOB_PATTERN_TYPE_FLAG_END_ONLY = 2, +}; + +static +enum star_glob_pattern_type_flags strutils_test_glob_pattern(const char *pattern) +{ + enum star_glob_pattern_type_flags ret = + STAR_GLOB_PATTERN_TYPE_FLAG_NONE; + const char *p; + + assert(pattern); + + for (p = pattern; *p != '\0'; p++) { + switch (*p) { + case '*': + ret = STAR_GLOB_PATTERN_TYPE_FLAG_PATTERN; + + if (p[1] == '\0') { + ret |= STAR_GLOB_PATTERN_TYPE_FLAG_END_ONLY; + } + + goto end; + case '\\': + p++; + + if (*p == '\0') { + goto end; + } + break; + default: + break; + } + } + +end: + return ret; +} + +/* + * Returns true if `pattern` is a star-only globbing pattern, that is, + * it contains at least one non-escaped `*`. + */ +bool strutils_is_star_glob_pattern(const char *pattern) +{ + return strutils_test_glob_pattern(pattern) & + STAR_GLOB_PATTERN_TYPE_FLAG_PATTERN; +} + +/* + * Returns true if `pattern` is a globbing pattern with a globbing, + * non-escaped star only at its very end. + */ +bool strutils_is_star_at_the_end_only_glob_pattern(const char *pattern) +{ + return strutils_test_glob_pattern(pattern) & + STAR_GLOB_PATTERN_TYPE_FLAG_END_ONLY; +} + +static inline +bool at_end_of_pattern(const char *p, const char *pattern, size_t pattern_len) +{ + return (p - pattern) == pattern_len || *p == '\0'; +} + +/* + * Globbing matching function with the star feature only (`?` and + * character sets are not supported). This matches `candidate` (plain + * string) against `pattern`. A literal star can be escaped with `\` in + * `pattern`. + * + * `pattern_len` or `candidate_len` can be greater than the actual + * string length of `pattern` or `candidate` if the string is + * null-terminated. + */ +bool strutils_star_glob_match(const char *pattern, size_t pattern_len, + const char *candidate, size_t candidate_len) { + const char *retry_c = candidate, *retry_p = pattern, *c, *p; + bool got_a_star = false; + +retry: + c = retry_c; + p = retry_p; + + /* + * The concept here is to retry a match in the specific case + * where we already got a star. The retry position for the + * pattern is just after the most recent star, and the retry + * position for the candidate is the character following the + * last try's first character. + * + * Example: + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^^ + * pattern: hi*every*one + * ^^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^^ + * pattern: hi*every*one + * ^^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^^ + * pattern: hi*every*one + * ^^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ MISMATCH + * + * candidate: hi ev every onyx one + * ^ + * pattern: hi*every*one + * ^ + * + * candidate: hi ev every onyx one + * ^^ + * pattern: hi*every*one + * ^^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ + * + * candidate: hi ev every onyx one + * ^ ^ + * pattern: hi*every*one + * ^ ^ SUCCESS + */ + while ((c - candidate) < candidate_len && *c != '\0') { + assert(*c); + + if (at_end_of_pattern(p, pattern, pattern_len)) { + goto end_of_pattern; + } + + switch (*p) { + case '*': + got_a_star = true; + + /* + * Our first try starts at the current candidate + * character and after the star in the pattern. + */ + retry_c = c; + retry_p = p + 1; + + if (at_end_of_pattern(retry_p, pattern, pattern_len)) { + /* + * Star at the end of the pattern at + * this point: automatic match. + */ + return true; + } + + goto retry; + case '\\': + /* Go to escaped character. */ + p++; /* Fallthrough */ + + /* + * Fall through the default case which will + * compare the escaped character now. + */ + default: + if (at_end_of_pattern(p, pattern, pattern_len) || + *c != *p) { +end_of_pattern: + /* Character mismatch OR end of pattern. */ + if (!got_a_star) { + /* + * We didn't get any star yet, + * so this first mismatch + * automatically makes the whole + * test fail. + */ + return false; + } + + /* + * Next try: next candidate character, + * original pattern character (following + * the most recent star). + */ + retry_c++; + goto retry; + } + break; + } + + /* Next pattern and candidate characters. */ + c++; + p++; + } + + /* + * We checked every candidate character and we're still in a + * success state: the only pattern character allowed to remain + * is a star. + */ + if (at_end_of_pattern(p, pattern, pattern_len)) { + return true; + } + + p++; + return p[-1] == '*' && at_end_of_pattern(p, pattern, pattern_len); +} diff --git a/src/common/strutils.h b/src/common/strutils.h new file mode 100644 index 00000000..a2ee531a --- /dev/null +++ b/src/common/strutils.h @@ -0,0 +1,23 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2017 Philippe Proulx + */ + +#ifndef _STRING_UTILS_H +#define _STRING_UTILS_H + +#include +#include + +bool strutils_is_star_glob_pattern(const char *pattern) + __attribute__((visibility("hidden"))); + +bool strutils_is_star_at_the_end_only_glob_pattern(const char *pattern) + __attribute__((visibility("hidden"))); + +bool strutils_star_glob_match(const char *pattern, size_t pattern_len, + const char *candidate, size_t candidate_len) + __attribute__((visibility("hidden"))); + +#endif /* _STRING_UTILS_H */ diff --git a/src/lib/lttng-ust/Makefile.am b/src/lib/lttng-ust/Makefile.am index 4bd39a3c..55be93f6 100644 --- a/src/lib/lttng-ust/Makefile.am +++ b/src/lib/lttng-ust/Makefile.am @@ -82,8 +82,6 @@ liblttng_ust_runtime_la_SOURCES = \ lttng-ust-tracef-provider.h \ tracelog.c \ lttng-ust-tracelog-provider.h \ - string-utils.c \ - string-utils.h \ event-notifier-notification.c \ rculfhash.c \ rculfhash.h \ diff --git a/src/lib/lttng-ust/lttng-bytecode-interpreter.c b/src/lib/lttng-ust/lttng-bytecode-interpreter.c index c5f75629..e28e113a 100644 --- a/src/lib/lttng-ust/lttng-bytecode-interpreter.c +++ b/src/lib/lttng-ust/lttng-bytecode-interpreter.c @@ -17,7 +17,7 @@ #include "lib/lttng-ust/events.h" #include "lttng-bytecode.h" -#include "string-utils.h" +#include "common/strutils.h" /* diff --git a/src/lib/lttng-ust/lttng-bytecode-validator.c b/src/lib/lttng-ust/lttng-bytecode-validator.c index 9f127f78..1a3649c1 100644 --- a/src/lib/lttng-ust/lttng-bytecode-validator.c +++ b/src/lib/lttng-ust/lttng-bytecode-validator.c @@ -15,7 +15,7 @@ #include "lttng-bytecode.h" #include "common/hash.h" -#include "string-utils.h" +#include "common/strutils.h" #include "lib/lttng-ust/events.h" #include "common/macros.h" diff --git a/src/lib/lttng-ust/lttng-events.c b/src/lib/lttng-ust/lttng-events.c index b33d6e1b..bff03a8e 100644 --- a/src/lib/lttng-ust/lttng-events.c +++ b/src/lib/lttng-ust/lttng-events.c @@ -42,7 +42,7 @@ #include "lttng-ust-uuid.h" #include "tracepoint-internal.h" -#include "string-utils.h" +#include "common/strutils.h" #include "lttng-bytecode.h" #include "lttng-tracer.h" #include "lttng-tracer-core.h" diff --git a/src/lib/lttng-ust/lttng-ust-abi.c b/src/lib/lttng-ust/lttng-ust-abi.c index f8e0f5bb..4b876811 100644 --- a/src/lib/lttng-ust/lttng-ust-abi.c +++ b/src/lib/lttng-ust/lttng-ust-abi.c @@ -45,7 +45,7 @@ #include "common/counter/counter.h" #include "tracepoint-internal.h" #include "lttng-tracer.h" -#include "string-utils.h" +#include "common/strutils.h" #include "lib/lttng-ust/events.h" #include "context-internal.h" #include "common/macros.h" diff --git a/src/lib/lttng-ust/string-utils.c b/src/lib/lttng-ust/string-utils.c deleted file mode 100644 index dea2ae3b..00000000 --- a/src/lib/lttng-ust/string-utils.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright (C) 2017 Philippe Proulx - */ - -#define _LGPL_SOURCE -#include -#include -#include -#include - -#include "string-utils.h" - -enum star_glob_pattern_type_flags { - STAR_GLOB_PATTERN_TYPE_FLAG_NONE = 0, - STAR_GLOB_PATTERN_TYPE_FLAG_PATTERN = 1, - STAR_GLOB_PATTERN_TYPE_FLAG_END_ONLY = 2, -}; - -static -enum star_glob_pattern_type_flags strutils_test_glob_pattern(const char *pattern) -{ - enum star_glob_pattern_type_flags ret = - STAR_GLOB_PATTERN_TYPE_FLAG_NONE; - const char *p; - - assert(pattern); - - for (p = pattern; *p != '\0'; p++) { - switch (*p) { - case '*': - ret = STAR_GLOB_PATTERN_TYPE_FLAG_PATTERN; - - if (p[1] == '\0') { - ret |= STAR_GLOB_PATTERN_TYPE_FLAG_END_ONLY; - } - - goto end; - case '\\': - p++; - - if (*p == '\0') { - goto end; - } - break; - default: - break; - } - } - -end: - return ret; -} - -/* - * Returns true if `pattern` is a star-only globbing pattern, that is, - * it contains at least one non-escaped `*`. - */ -bool strutils_is_star_glob_pattern(const char *pattern) -{ - return strutils_test_glob_pattern(pattern) & - STAR_GLOB_PATTERN_TYPE_FLAG_PATTERN; -} - -/* - * Returns true if `pattern` is a globbing pattern with a globbing, - * non-escaped star only at its very end. - */ -bool strutils_is_star_at_the_end_only_glob_pattern(const char *pattern) -{ - return strutils_test_glob_pattern(pattern) & - STAR_GLOB_PATTERN_TYPE_FLAG_END_ONLY; -} - -static inline -bool at_end_of_pattern(const char *p, const char *pattern, size_t pattern_len) -{ - return (p - pattern) == pattern_len || *p == '\0'; -} - -/* - * Globbing matching function with the star feature only (`?` and - * character sets are not supported). This matches `candidate` (plain - * string) against `pattern`. A literal star can be escaped with `\` in - * `pattern`. - * - * `pattern_len` or `candidate_len` can be greater than the actual - * string length of `pattern` or `candidate` if the string is - * null-terminated. - */ -bool strutils_star_glob_match(const char *pattern, size_t pattern_len, - const char *candidate, size_t candidate_len) { - const char *retry_c = candidate, *retry_p = pattern, *c, *p; - bool got_a_star = false; - -retry: - c = retry_c; - p = retry_p; - - /* - * The concept here is to retry a match in the specific case - * where we already got a star. The retry position for the - * pattern is just after the most recent star, and the retry - * position for the candidate is the character following the - * last try's first character. - * - * Example: - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^^ - * pattern: hi*every*one - * ^^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^^ - * pattern: hi*every*one - * ^^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^^ - * pattern: hi*every*one - * ^^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ MISMATCH - * - * candidate: hi ev every onyx one - * ^ - * pattern: hi*every*one - * ^ - * - * candidate: hi ev every onyx one - * ^^ - * pattern: hi*every*one - * ^^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ - * - * candidate: hi ev every onyx one - * ^ ^ - * pattern: hi*every*one - * ^ ^ SUCCESS - */ - while ((c - candidate) < candidate_len && *c != '\0') { - assert(*c); - - if (at_end_of_pattern(p, pattern, pattern_len)) { - goto end_of_pattern; - } - - switch (*p) { - case '*': - got_a_star = true; - - /* - * Our first try starts at the current candidate - * character and after the star in the pattern. - */ - retry_c = c; - retry_p = p + 1; - - if (at_end_of_pattern(retry_p, pattern, pattern_len)) { - /* - * Star at the end of the pattern at - * this point: automatic match. - */ - return true; - } - - goto retry; - case '\\': - /* Go to escaped character. */ - p++; /* Fallthrough */ - - /* - * Fall through the default case which will - * compare the escaped character now. - */ - default: - if (at_end_of_pattern(p, pattern, pattern_len) || - *c != *p) { -end_of_pattern: - /* Character mismatch OR end of pattern. */ - if (!got_a_star) { - /* - * We didn't get any star yet, - * so this first mismatch - * automatically makes the whole - * test fail. - */ - return false; - } - - /* - * Next try: next candidate character, - * original pattern character (following - * the most recent star). - */ - retry_c++; - goto retry; - } - break; - } - - /* Next pattern and candidate characters. */ - c++; - p++; - } - - /* - * We checked every candidate character and we're still in a - * success state: the only pattern character allowed to remain - * is a star. - */ - if (at_end_of_pattern(p, pattern, pattern_len)) { - return true; - } - - p++; - return p[-1] == '*' && at_end_of_pattern(p, pattern, pattern_len); -} diff --git a/src/lib/lttng-ust/string-utils.h b/src/lib/lttng-ust/string-utils.h deleted file mode 100644 index a2ee531a..00000000 --- a/src/lib/lttng-ust/string-utils.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright (C) 2017 Philippe Proulx - */ - -#ifndef _STRING_UTILS_H -#define _STRING_UTILS_H - -#include -#include - -bool strutils_is_star_glob_pattern(const char *pattern) - __attribute__((visibility("hidden"))); - -bool strutils_is_star_at_the_end_only_glob_pattern(const char *pattern) - __attribute__((visibility("hidden"))); - -bool strutils_star_glob_match(const char *pattern, size_t pattern_len, - const char *candidate, size_t candidate_len) - __attribute__((visibility("hidden"))); - -#endif /* _STRING_UTILS_H */