Char.mem tells you if a byte is a member of a string. String.span and String.cspan are like the C functions strspn and strcspn. --- common/mlstdutils/std_utils.ml | 27 +++++++++++++++++++++++++++ common/mlstdutils/std_utils.mli | 12 ++++++++++++ common/mlstdutils/std_utils_tests.ml | 21 +++++++++++++++++++++ 3 files changed, 60 insertions(+)
diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml index f545c6f7a..a153ceb7f 100644 --- a/common/mlstdutils/std_utils.ml +++ b/common/mlstdutils/std_utils.ml @@ -74,6 +74,15 @@ module Char = struct | 'e' | 'E' -> 14 | 'f' | 'F' -> 15 | _ -> -1 + + let mem c str = + let len = String.length str in + let rec loop i = + if i >= len then false + else if String.unsafe_get str i = c then true + else loop (i+1) + in + loop 0 end module String = struct @@ -246,6 +255,24 @@ module String = struct List.map f (explode str) let spaces n = String.make n ' ' + + let span str accept = + let len = String.length str in + let rec loop i = + if i >= len then len + else if Char.mem (String.unsafe_get str i) accept then loop (i+1) + else i + in + loop 0 + + let cspan str reject = + let len = String.length str in + let rec loop i = + if i >= len then len + else if Char.mem (String.unsafe_get str i) reject then i + else loop (i+1) + in + loop 0 end let (//) = Filename.concat diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli index 686d4193f..b61b9bb02 100644 --- a/common/mlstdutils/std_utils.mli +++ b/common/mlstdutils/std_utils.mli @@ -41,6 +41,9 @@ module Char : sig val hexdigit : char -> int (** Return the value of a hex digit. If the char is not in the set [[0-9a-fA-F]] then this returns [-1]. *) + + val mem : char -> string -> bool + (** [mem c str] returns true if the byte [c] is contained in [str]. *) end (** Override the Char module from stdlib. *) @@ -109,6 +112,15 @@ module String : sig (** Explode string, then map function over the characters. *) val spaces : int -> string (** [spaces n] creates a string of n spaces. *) + val span : string -> string -> int + val cspan : string -> string -> int + (** [span str accept] returns the length in bytes of the initial + segment of [str] which contains only bytes in [accept]. + + [cspan str reject] returns the length in bytes of the initial + segment of [str] which contains only bytes {!i not} in [reject]. + + These work exactly like the C functions [strspn] and [strcspn]. *) end (** Override the String module from stdlib. *) diff --git a/common/mlstdutils/std_utils_tests.ml b/common/mlstdutils/std_utils_tests.ml index 6bc74fb63..2789766c6 100644 --- a/common/mlstdutils/std_utils_tests.ml +++ b/common/mlstdutils/std_utils_tests.ml @@ -50,6 +50,14 @@ and test_swap int_of_x x_of_int i s = assert_equal_int64 i (int_of_x s); assert_equal_string s (x_of_int i) +(* Test Std_utils.Char.mem. *) +let test_char_mem ctx = + assert_bool "Char.mem" (Char.mem 'a' "abc"); + assert_bool "Char.mem" (Char.mem 'b' "abc"); + assert_bool "Char.mem" (Char.mem 'c' "abc"); + assert_bool "Char.mem" (not (Char.mem 'd' "abc")); + assert_bool "Char.mem" (not (Char.mem 'a' "")) + (* Test Std_utils.String.is_prefix. *) let test_string_is_prefix ctx = assert_bool "String.is_prefix,," (String.is_prefix "" ""); @@ -91,16 +99,29 @@ let test_string_lines_split ctx = assert_equal_stringlist ["A\nB"; ""] (String.lines_split "A\\\nB\n"); assert_equal_stringlist ["A\nB\n"] (String.lines_split "A\\\nB\\\n") +(* Test Std_utils.String.span and cspan. *) +let test_string_span ctx = + assert_equal_int 3 (String.span "aaabb" "a"); + assert_equal_int 3 (String.span "aaaba" "a"); + assert_equal_int 3 (String.span "aba" "ab"); + assert_equal_int 0 (String.span "" "ab"); + assert_equal_int 3 (String.cspan "defab" "ab"); + assert_equal_int 3 (String.cspan "defba" "ab"); + assert_equal_int 3 (String.cspan "def" "ab"); + assert_equal_int 0 (String.cspan "" "ab") + (* Suites declaration. *) let suite = "mllib Std_utils" >::: [ "subdirectory" >:: test_subdirectory; "numeric.byteswap" >:: test_byteswap; + "char.mem" >:: test_char_mem; "strings.is_prefix" >:: test_string_is_prefix; "strings.is_suffix" >:: test_string_is_suffix; "strings.find" >:: test_string_find; "strings.lines_split" >:: test_string_lines_split; + "strings.span" >:: test_string_span; ] let () = -- 2.13.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs