aboutsummaryrefslogtreecommitdiff
path: root/match.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2021-09-23 17:53:17 -0700
committerBruce Hill <bruce@bruce-hill.com>2021-09-23 17:53:17 -0700
commitfddba4c54f3ce21e711cc2cd931ce5c4cad660b9 (patch)
tree4a5941889ea19f5554f5f62f4d04f46d23e272e2 /match.c
parent04eb92153f04930b348f85120255c5715ec55b6f (diff)
parent6ab22ad6a90b96f159a0d78499a49fd62989cb15 (diff)
Merge branch 'master' into fileless_matches
Diffstat (limited to 'match.c')
-rw-r--r--match.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/match.c b/match.c
index 1ae2c53..29db8c6 100644
--- a/match.c
+++ b/match.c
@@ -267,22 +267,23 @@ static match_t *_next_match(match_context_t *ctx, const char *str, pat_t *pat, p
pat_t *first = first_pat(ctx->defs, pat);
// Performance optimization: if the pattern starts with a string literal,
- // we can just rely on the highly optimized strstr()/strcasestr()
- // implementations to skip past areas where we know we won't find a match.
- if (!skip && first->type == BP_STRING) {
- for (size_t i = 0; i < first->min_matchlen; i++)
- if (first->args.string[i] == '\0')
- goto pattern_search;
- char *tmp = strndup(first->args.string, first->min_matchlen);
- char *found = (ctx->ignorecase ? strcasestr : strstr)(str, tmp);
- if (found)
- str = found;
- else
- str += strlen(str); // Use += strlen here instead of ctx->end to handle files with NULL bytes
- free(tmp);
- }
-
- pattern_search:
+ // we can just rely on the highly optimized memmem() implementation to skip
+ // past areas where we know we won't find a match.
+ if (!skip && first->type == BP_STRING && first->min_matchlen > 0) {
+ if (ctx->ignorecase) {
+ char c1 = first->args.string[0];
+ char *upper = memchr(str, toupper(c1), (size_t)(str - ctx->end));
+ char *lower = isalpha(c1) ? memchr(str, tolower(c1), (size_t)(str - ctx->end)) : NULL;
+ if (upper && lower)
+ str = upper < lower ? upper : lower;
+ else if (upper) str = upper;
+ else if (lower) str = lower;
+ } else {
+ char *found = memmem(str, (size_t)(ctx->end - str), first->args.string, first->min_matchlen);
+ str = found ? found : ctx->end;
+ }
+ }
+
if (str > ctx->end) return NULL;
do {
@@ -353,7 +354,7 @@ static match_t *match(match_context_t *ctx, const char *str, pat_t *pat)
}
case BP_STRING: {
if (&str[pat->min_matchlen] > ctx->end) return NULL;
- if (pat->min_matchlen > 0 && (ctx->ignorecase ? memicmp : memcmp)(str, pat->args.string, pat->min_matchlen) != 0)
+ if (pat->min_matchlen > 0 && (ctx->ignorecase ? strncasecmp : strncmp)(str, pat->args.string, pat->min_matchlen) != 0)
return NULL;
return new_match(ctx->defs, pat, str, str + pat->min_matchlen, NULL);
}