t1301-shared-repo: fix forced modes test
[gitweb.git] / diffcore-pickaxe.c
index cfcce315babb0edb7ad7be7f2ab2437aaf41eb9d..d0ef8397008824fb5139680856e3229ecf2c4eb1 100644 (file)
@@ -5,17 +5,17 @@
 #include "diff.h"
 #include "diffcore.h"
 
-#include <regex.h>
-
 static unsigned int contains(struct diff_filespec *one,
                             const char *needle, unsigned long len,
                             regex_t *regexp)
 {
        unsigned int cnt;
-       unsigned long offset, sz;
+       unsigned long sz;
        const char *data;
        if (diff_populate_filespec(one, 0))
                return 0;
+       if (!len)
+               return 0;
 
        sz = one->size;
        data = one->data;
@@ -25,25 +25,26 @@ static unsigned int contains(struct diff_filespec *one,
                regmatch_t regmatch;
                int flags = 0;
 
+               assert(data[sz] == '\0');
                while (*data && !regexec(regexp, data, 1, &regmatch, flags)) {
                        flags |= REG_NOTBOL;
-                       data += regmatch.rm_so;
-                       if (*data) data++;
+                       data += regmatch.rm_eo;
+                       if (*data && regmatch.rm_so == regmatch.rm_eo)
+                               data++;
                        cnt++;
                }
 
        } else { /* Classic exact string match */
-               /* Yes, I've heard of strstr(), but the thing is *data may
-                * not be NUL terminated.  Sue me.
-                */
-               for (offset = 0; offset + len <= sz; offset++) {
-                       /* we count non-overlapping occurrences of needle */
-                       if (!memcmp(needle, data + offset, len)) {
-                               offset += len - 1;
-                               cnt++;
-                       }
+               while (sz) {
+                       const char *found = memmem(data, sz, needle, len);
+                       if (!found)
+                               break;
+                       sz -= found - data + len;
+                       data = found + len;
+                       cnt++;
                }
        }
+       diff_free_filespec_data(one);
        return cnt;
 }
 
@@ -101,7 +102,7 @@ void diffcore_pickaxe(const char *needle, int opts)
                for (i = 0; i < q->nr; i++)
                        diff_free_filepair(q->queue[i]);
        }
-       else 
+       else
                /* Showing only the filepairs that has the needle */
                for (i = 0; i < q->nr; i++) {
                        struct diff_filepair *p = q->queue[i];