Added two new optional arguments to nsplit:
* noempty: if set to false empty elements are not stored in the returned
list. The default is to keep the empty elements
* count: specifies how many splits to perform; negative count
(the default) means do as many splits as possible
Added tests for nsplit.
Signed-off-by: Tomáš Golembiovský <tgolembi(a)redhat.com>
---
mllib/common_utils.ml | 12 +++++++++---
mllib/common_utils.mli | 12 ++++++++++--
mllib/common_utils_tests.ml | 26 ++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index f948dce..b6f3046 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -130,15 +130,21 @@ module String = struct
done;
if not !r then s else Bytes.to_string b2
- let rec nsplit sep str =
+ let rec nsplit ?(noempty = true) ?(count = -1) sep str =
let len = length str in
let seplen = length sep in
let i = find str sep in
- if i = -1 then [str]
+ if i = -1 || count = 0 then [str]
else (
let s' = sub str 0 i in
let s'' = sub str (i+seplen) (len-i-seplen) in
- s' :: nsplit sep s''
+ let elem, count =
+ if s' = "" && noempty then
+ [], count
+ else
+ [s'], if count > 0 then count-1 else count
+ in
+ elem @ nsplit ~noempty:noempty ~count:count sep s''
)
let split sep str =
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
index 4a6ddd6..fd0ef49 100644
--- a/mllib/common_utils.mli
+++ b/mllib/common_utils.mli
@@ -80,9 +80,17 @@ module String : sig
[str] with [s2]. *)
val replace_char : string -> char -> char -> string
(** Replace character in string. *)
- val nsplit : string -> string -> string list
+ val nsplit : ?noempty:bool -> ?count:int -> string -> string -> string
list
(** [nsplit sep str] splits [str] into multiple strings at each
- separator [sep]. *)
+ separator [sep].
+
+ If [noempty] is set to true empty elements are not included in the
+ list. By default empty elements are kept.
+
+ If [count] is specified it says how many splits to perform. I.e. the
+ returned array will have at most [count]+1 elements. Negative [count]
+ (the default) means do as many splits as possible.
+ *)
val split : string -> string -> string * string
(** [split sep str] splits [str] at the first occurrence of the
separator [sep], returning the part before and the part after.
diff --git a/mllib/common_utils_tests.ml b/mllib/common_utils_tests.ml
index ee27b93..ef5665f 100644
--- a/mllib/common_utils_tests.ml
+++ b/mllib/common_utils_tests.ml
@@ -109,6 +109,32 @@ let test_string_find ctx =
assert_equal_int (-1) (String.find "" "baz");
assert_equal_int (-1) (String.find "foobar" "baz")
+(* Test Common_utils.String.nsplit *)
+let test_string_nsplit ctx =
+ (* Basic functionality *)
+ assert_equal_stringlist [""] (String.nsplit "," "");
+ assert_equal_stringlist ["A"] (String.nsplit "," "A");
+ assert_equal_stringlist ["A"; "B"] (String.nsplit ","
"A,B");
+ assert_equal_stringlist ["A"; "B"; "C"] (String.nsplit
"," "A,B,C");
+ assert_equal_stringlist ["A"; "B"; "C"; "D"]
(String.nsplit "," "A,B,C,D");
+ assert_equal_stringlist [""; "A"; ""] (String.nsplit
"," ",A,");
+ assert_equal_stringlist ["A"; ""; ""; "B"]
(String.nsplit "," "A,,,B");
+ assert_equal_stringlist ["A"; "B"; "C"; "D"]
(String.nsplit "<>" "A<>B<>C<>D");
+
+ (* noemty option *)
+ assert_equal_stringlist ["A"] (String.nsplit ~noempty:true ","
",A,");
+ assert_equal_stringlist ["A"; "B"] (String.nsplit ~noempty:true
"," "A,,,B");
+
+ (* count option *)
+ assert_equal_stringlist ["A"; "B"; "C"; "D"]
(String.nsplit ~count:(-1) "," "A,B,C,D");
+ assert_equal_stringlist ["A,B,C,D"] (String.nsplit ~count:0 ","
"A,B,C,D");
+ assert_equal_stringlist ["A"; "B,C,D"] (String.nsplit ~count:1
"," "A,B,C,D");
+ assert_equal_stringlist ["A"; "B"; "C,D"] (String.nsplit
~count:2 "," "A,B,C,D");
+ assert_equal_stringlist ["A"; "B"; "C"; "D"]
(String.nsplit ~count:10 "," "A,B,C,D");
+
+ (* count and noempty together *)
+ assert_equal_stringlist ["A"; "B"; "C,D"] (String.nsplit
~noempty:true ~count:2 "," ",,,A,,,,B,,,,C,D")
+
(* Test Common_utils.String.lines_split. *)
let test_string_lines_split ctx =
assert_equal_stringlist [""] (String.lines_split "");
--
2.10.2