[Libguestfs] [PATCH v2 1/3] common/mlpcre: add offset flag for PCRE.matches

Pino Toscano ptoscano at redhat.com
Fri Mar 29 16:02:36 UTC 2019


This way it is possible to change where the matching start, instead of
always assuming it is the beginning.
---
 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 0762a8341..be054a004 100644
--- a/common/mlpcre/pcre-c.c
+++ b/common/mlpcre/pcre-c.c
@@ -121,6 +121,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,
@@ -165,9 +174,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);
@@ -205,7 +214,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.20.1




More information about the Libguestfs mailing list