[master] 0eb6916a8 vre: Optionally capture groups in a txt array

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Aug 30 12:25:08 UTC 2021


commit 0eb6916a8df50d5910c16a2c5dfe9cf664362b23
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Tue Aug 3 10:57:40 2021 +0200

    vre: Optionally capture groups in a txt array

diff --git a/lib/libvarnish/vre.c b/lib/libvarnish/vre.c
index e2efdcbc8..065563641 100644
--- a/lib/libvarnish/vre.c
+++ b/lib/libvarnish/vre.c
@@ -182,11 +182,14 @@ VRE_export(const vre_t *code, size_t *sz)
 }
 
 static int
-vre_match(const vre_t *code, const char *subject, size_t length, size_t offset,
-    int options, pcre2_match_data **datap)
+vre_capture(const vre_t *code, const char *subject, size_t length,
+    size_t offset, int options, txt *groups, size_t *count,
+    pcre2_match_data **datap)
 {
 	pcre2_match_data *data;
 	pcre2_code *re;
+	PCRE2_SIZE *ovector;
+	size_t nov, g;
 	int matches;
 
 	re = VRE_unpack(code);
@@ -199,9 +202,24 @@ vre_match(const vre_t *code, const char *subject, size_t length, size_t offset,
 		AN(data);
 	}
 
-	matches =  pcre2_match(re, (PCRE2_SPTR)subject, length, offset,
+	matches = pcre2_match(re, (PCRE2_SPTR)subject, length, offset,
 	    options, data, code->re_ctx);
 
+	if (groups != NULL) {
+		AN(count);
+		AN(*count);
+		ovector = pcre2_get_ovector_pointer(data);
+		nov = pcre2_get_ovector_count(data);
+		if (nov > *count)
+			nov = *count;
+		for (g = 0; g < nov; g++) {
+			groups->b = subject + ovector[2 * g];
+			groups->e = subject + ovector[2 * g + 1];
+			groups++;
+		}
+		*count = nov;
+	}
+
 	if (datap != NULL && matches > VRE_ERROR_NOMATCH)
 		*datap = data;
 	else
@@ -221,7 +239,8 @@ VRE_match(const vre_t *code, const char *subject, size_t length,
 	if (length == 0)
 		length = PCRE2_ZERO_TERMINATED;
 	vre_limit(code, lim);
-	return (vre_match(code, subject, length, 0, options, NULL));
+	return (vre_capture(code, subject, length, 0, options,
+	    NULL, NULL, NULL));
 }
 
 int
@@ -242,7 +261,8 @@ VRE_sub(const vre_t *code, const char *subject, const char *replacement,
 	AN(replacement);
 
 	vre_limit(code, lim);
-	i = vre_match(code, subject, PCRE2_ZERO_TERMINATED, offset, 0, &data);
+	i = vre_capture(code, subject, PCRE2_ZERO_TERMINATED, offset, 0,
+	    NULL, NULL, &data);
 
 	if (i <= VRE_ERROR_NOMATCH)
 		return (i);
@@ -274,8 +294,8 @@ VRE_sub(const vre_t *code, const char *subject, const char *replacement,
 		offset = ovector[1];
 		if (!all)
 			break;
-		i = vre_match(code, subject, PCRE2_ZERO_TERMINATED, offset,
-		    PCRE2_NOTEMPTY, &data);
+		i = vre_capture(code, subject, PCRE2_ZERO_TERMINATED, offset,
+		    PCRE2_NOTEMPTY, NULL, NULL, &data);
 		if (i < VRE_ERROR_NOMATCH)
 			return (i);
 	} while (i != VRE_ERROR_NOMATCH);


More information about the varnish-commit mailing list