aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-06-07 14:22:42 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-06-07 14:22:42 -0400
commit0e9f324955f5ce30e6eb7e735aadea0852547ca4 (patch)
tree2dc30d1816f2bfab953cf682fc7546b21f7102e4
parent6d0e4fd1d2bf69b2c36fbda72ebb6b427348318d (diff)
Add optimization for .."literal"
-rw-r--r--match.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/match.c b/match.c
index 1ecee6d..f05089f 100644
--- a/match.c
+++ b/match.c
@@ -446,6 +446,22 @@ static bp_match_t *match(match_ctx_t *ctx, const char *str, bp_pat_t *pat)
return m;
}
+ // Optimization: for simple cases like `.."foo"` we can speed things up
+ // by skipping ahead to strstr(str, "foo")
+ if (!skip) {
+ bp_pat_t *prereq = get_prerequisite(ctx, target);
+ if (prereq->type == BP_STRING && prereq->min_matchlen > 0) {
+ char *found = ctx->ignorecase ?
+ strcasestr(str, When(prereq, BP_STRING)->string)
+ : memmem(str, (size_t)(ctx->end - str), When(prereq, BP_STRING)->string, prereq->min_matchlen);
+ str = found ? found : ctx->end;
+ } else if (prereq->type == BP_END_OF_FILE) {
+ str = ctx->end;
+ } else if (prereq->type == BP_END_OF_LINE) {
+ str += strcspn(str, "\n\r");
+ }
+ }
+
size_t child_cap = 0, nchildren = 0;
for (const char *prev = NULL; prev < str; ) {
prev = str;