This may be helpful when we just want to match a part of "text". nwildmatch can be used for this purpose. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- wildmatch.c | 43 +++++++++++++++++++++++++------------------ wildmatch.h | 11 +++++++++-- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/wildmatch.c b/wildmatch.c index 7192bdc..939bac8 100644 --- a/wildmatch.c +++ b/wildmatch.c @@ -52,7 +52,8 @@ typedef unsigned char uchar; #define ISXDIGIT(c) (ISASCII(c) && isxdigit(c)) /* Match pattern "p" against "text" */ -static int dowild(const uchar *p, const uchar *text, unsigned int flags) +static int dowild(const uchar *p, const uchar *text, + const uchar *textend, unsigned int flags) { uchar p_ch; const uchar *pattern = p; @@ -60,8 +61,13 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) for ( ; (p_ch = *p) != '\0'; text++, p++) { int matched, match_slash, negated; uchar t_ch, prev_ch; - if ((t_ch = *text) == '\0' && p_ch != '*') - return WM_ABORT_ALL; + if (text >= textend) { + if (p_ch != '*') + return WM_ABORT_ALL; + else + t_ch = '\0'; + } else + t_ch = *text; if ((flags & WM_CASEFOLD) && ISUPPER(t_ch)) t_ch = tolower(t_ch); if ((flags & WM_CASEFOLD) && ISUPPER(p_ch)) @@ -101,7 +107,7 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) * both foo/bar and foo/a/bar. */ if (p[0] == '/' && - dowild(p + 1, text, flags) == WM_MATCH) + dowild(p + 1, text, textend, flags) == WM_MATCH) return WM_MATCH; match_slash = 1; } else @@ -113,8 +119,9 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) /* Trailing "**" matches everything. Trailing "*" matches * only if there are no more slash characters. */ if (!match_slash) { - if (strchr((char*)text, '/') != NULL) - return WM_NOMATCH; + for (;text < textend; text++) + if (*text == '/') + return WM_NOMATCH; } return WM_MATCH; } else if (!match_slash && *p == '/') { @@ -123,16 +130,15 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) * with WM_PATHNAME matches the next * directory */ - const char *slash = strchr((char*)text, '/'); - if (!slash) + for (;text < textend; text++) + if (*text == '/') + break; + if (text == textend) return WM_NOMATCH; - text = (const uchar*)slash; /* the slash is consumed by the top-level for loop */ break; } - while (1) { - if (t_ch == '\0') - break; + while (text < textend) { /* * Try to advance faster when an asterisk is * followed by a literal. We know in this case @@ -145,18 +151,18 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) p_ch = *p; if ((flags & WM_CASEFOLD) && ISUPPER(p_ch)) p_ch = tolower(p_ch); - while ((t_ch = *text) != '\0' && + while (text < textend && (match_slash || t_ch != '/')) { if ((flags & WM_CASEFOLD) && ISUPPER(t_ch)) t_ch = tolower(t_ch); if (t_ch == p_ch) break; - text++; + t_ch = ++text < textend ? *text : '\0'; } if (t_ch != p_ch) return WM_NOMATCH; } - if ((matched = dowild(p, text, flags)) != WM_NOMATCH) { + if ((matched = dowild(p, text, textend, flags)) != WM_NOMATCH) { if (!match_slash || matched != WM_ABORT_TO_STARSTAR) return matched; } else if (!match_slash && t_ch == '/') @@ -261,12 +267,13 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) } } - return *text ? WM_NOMATCH : WM_MATCH; + return text < textend ? WM_NOMATCH : WM_MATCH; } /* Match the "pattern" against the "text" string. */ -int wildmatch(const char *pattern, const char *text, +int nwildmatch(const char *pattern, const char *text, int textlen, unsigned int flags, struct wildopts *wo) { - return dowild((const uchar*)pattern, (const uchar*)text, flags); + return dowild((const uchar*)pattern, (const uchar*)text, + (const uchar*)text + textlen, flags); } diff --git a/wildmatch.h b/wildmatch.h index 4090c8f..cdd7544 100644 --- a/wildmatch.h +++ b/wildmatch.h @@ -12,7 +12,14 @@ struct wildopts; -int wildmatch(const char *pattern, const char *text, - unsigned int flags, +int nwildmatch(const char *pattern, const char *text, + int len, unsigned int flags, struct wildopts *wo); + +/* Match the "pattern" against the "text" string. */ +static inline int wildmatch(const char *pattern, const char *text, + unsigned int flags, struct wildopts *wo) +{ + return nwildmatch(pattern, text, strlen(text), flags, wo); +} #endif -- 1.8.2.82.gc24b958 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html