From 83c76b6c610df17e0b9bfd9cd11deb43ebc40411 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Tue, 19 Feb 2019 10:50:01 +0100 Subject: [PATCH] common/mlpcre: add offset flag for PCRE.matches This way it is possible to change where the matching start, instead of always assuming it is the beginning. (cherry picked from commit 0ed2e5c14a302d15fd3b75ee2c1cb808a06cb746) --- common/mlpcre/PCRE.ml | 2 +- common/mlpcre/PCRE.mli | 5 ++++- common/mlpcre/pcre-c.c | 16 +++++++++++++--- common/mlpcre/pcre_tests.ml | 11 ++++++++--- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/common/mlpcre/PCRE.ml b/common/mlpcre/PCRE.ml index b054928f9..33074af1c 100644 --- a/common/mlpcre/PCRE.ml +++ b/common/mlpcre/PCRE.ml @@ -23,7 +23,7 @@ exception Error of string * int type regexp external compile : ?anchored:bool -> ?caseless:bool -> ?dotall:bool -> ?extended:bool -> ?multiline:bool -> string -> regexp = "guestfs_int_pcre_compile_byte" "guestfs_int_pcre_compile" -external matches : regexp -> string -> bool = "guestfs_int_pcre_matches" +external matches : ?offset:int -> regexp -> string -> bool = "guestfs_int_pcre_matches" external sub : int -> string = "guestfs_int_pcre_sub" external subi : int -> int * int = "guestfs_int_pcre_subi" diff --git a/common/mlpcre/PCRE.mli b/common/mlpcre/PCRE.mli index eacb6fd90..e10d512fc 100644 --- a/common/mlpcre/PCRE.mli +++ b/common/mlpcre/PCRE.mli @@ -62,7 +62,7 @@ val compile : ?anchored:bool -> ?caseless:bool -> ?dotall:bool -> ?extended:bool See pcreapi(3) for details of what they do. All flags default to false. *) -val matches : regexp -> string -> bool +val matches : ?offset:int -> regexp -> string -> bool (** Test whether the regular expression matches the string. This returns true if the regexp matches or false otherwise. @@ -71,6 +71,9 @@ val matches : regexp -> string -> bool or the thread/program exits. You can call {!sub} to return these substrings. + The [?offset] flag is used to change the start of the search, + which by default is at the beginning of the string (position 0). + This can raise {!Error} if PCRE returns an error. *) val sub : int -> string diff --git a/common/mlpcre/pcre-c.c b/common/mlpcre/pcre-c.c index 7dbba5857..ec3a6f00d 100644 --- a/common/mlpcre/pcre-c.c +++ b/common/mlpcre/pcre-c.c @@ -133,6 +133,15 @@ is_Some_true (value v) Bool_val (Field (v, 0)) /* Some true */; } +static int +Optint_val (value intv, int defval) +{ + if (intv == Val_int (0)) /* None */ + return defval; + else /* Some int */ + return Int_val (Field (intv, 0)); +} + value guestfs_int_pcre_compile (value anchoredv, value caselessv, value dotallv, value extendedv, value multilinev, @@ -177,9 +186,9 @@ guestfs_int_pcre_compile_byte (value *argv, int argn) } value -guestfs_int_pcre_matches (value rev, value strv) +guestfs_int_pcre_matches (value offsetv, value rev, value strv) { - CAMLparam2 (rev, strv); + CAMLparam3 (offsetv, rev, strv); pcre *re = Regexp_val (rev); struct last_match *m, *oldm; size_t len = caml_string_length (strv); @@ -217,7 +226,8 @@ guestfs_int_pcre_matches (value rev, value strv) caml_raise_out_of_memory (); } - m->r = pcre_exec (re, NULL, m->subject, len, 0, 0, m->vec, veclen); + m->r = pcre_exec (re, NULL, m->subject, len, Optint_val (offsetv, 0), 0, + m->vec, veclen); if (m->r < 0 && m->r != PCRE_ERROR_NOMATCH) { int ret = m->r; free_last_match (m); diff --git a/common/mlpcre/pcre_tests.ml b/common/mlpcre/pcre_tests.ml index 346019c40..3e5981107 100644 --- a/common/mlpcre/pcre_tests.ml +++ b/common/mlpcre/pcre_tests.ml @@ -30,9 +30,9 @@ let compile ?(anchored = false) ?(caseless = false) patt; PCRE.compile ~anchored ~caseless ~dotall ~extended ~multiline patt -let matches re str = - eprintf "PCRE.matches %s ->%!" str; - let r = PCRE.matches re str in +let matches ?(offset = 0) re str = + eprintf "PCRE.matches %s, %d ->%!" str offset; + let r = PCRE.matches ~offset re str in eprintf " %b\n%!" r; r @@ -103,6 +103,11 @@ let () = assert (subi 1 = (2, 3)); assert (subi 2 = (3, 3)); + assert (matches ~offset:5 re0 "aaabcabc" = true); + assert (sub 0 = "ab"); + + assert (matches ~offset:5 re0 "aaabcbaac" = false); + assert (replace re0 "dd" "abcabcaabccca" = "ddcabcaabccca"); assert (replace ~global:true re0 "dd" "abcabcaabccca" = "ddcddcddccca"); -- 2.18.4