[Libguestfs] [PATCH v2 1/3] common/mlpcre: add offset flag for PCRE.matches
Richard W.M. Jones
rjones at redhat.com
Tue Apr 2 07:39:47 UTC 2019
On Fri, Mar 29, 2019 at 05:02:36PM +0100, Pino Toscano wrote:
> 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");
>
This is fine now, ACK.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
More information about the Libguestfs
mailing list