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 <pclo...@gmail.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to