This also involved enhancing/fixing the test so that parse_size has
test coverage.
---
dib/Makefile.am | 3 ++
get-kernel/Makefile.am | 3 ++
mllib/Makefile.am | 6 +++
mllib/common_utils.ml | 107 +++++++++++++++++++-------------------------
mllib/common_utils_tests.ml | 10 ++++-
resize/Makefile.am | 3 ++
sparsify/Makefile.am | 3 ++
7 files changed, 72 insertions(+), 63 deletions(-)
diff --git a/dib/Makefile.am b/dib/Makefile.am
index d5fc4e48d..fda074b45 100644
--- a/dib/Makefile.am
+++ b/dib/Makefile.am
@@ -85,6 +85,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/ocaml \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mlutils \
+ -I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/mllib
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -109,6 +110,7 @@ OCAMLLINKFLAGS = \
mlstdutils.$(MLARCHIVE) \
mlguestfs.$(MLARCHIVE) \
mlcutils.$(MLARCHIVE) \
+ mlpcre.$(MLARCHIVE) \
mllib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
@@ -116,6 +118,7 @@ virt_dib_DEPENDENCIES = \
$(OBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
../common/mlutils/mlcutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
../mllib/mllib.$(MLARCHIVE) \
$(top_srcdir)/ocaml-link.sh
virt_dib_LINK = \
diff --git a/get-kernel/Makefile.am b/get-kernel/Makefile.am
index 8c194df36..f833f35f4 100644
--- a/get-kernel/Makefile.am
+++ b/get-kernel/Makefile.am
@@ -68,6 +68,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/ocaml \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mlutils \
+ -I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/mllib
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -91,6 +92,7 @@ endif
OCAMLLINKFLAGS = \
mlstdutils.$(MLARCHIVE) \
mlguestfs.$(MLARCHIVE) \
+ mlpcre.$(MLARCHIVE) \
mlcutils.$(MLARCHIVE) \
mllib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
@@ -99,6 +101,7 @@ virt_get_kernel_DEPENDENCIES = \
$(OBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
../common/mlutils/mlcutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
../mllib/mllib.$(MLARCHIVE) \
$(top_srcdir)/ocaml-link.sh
virt_get_kernel_LINK = \
diff --git a/mllib/Makefile.am b/mllib/Makefile.am
index 2f6d2043a..3f2af3c61 100644
--- a/mllib/Makefile.am
+++ b/mllib/Makefile.am
@@ -86,6 +86,7 @@ libmllib_a_CPPFLAGS = \
-I$(top_srcdir)/common/utils \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/common/options \
+ -I$(top_srcdir)/common/mlpcre \
-I$(top_srcdir)/common/mlxml \
-I$(top_srcdir)/common/mlstdutils \
-I$(top_srcdir)/common/mlutils
@@ -106,6 +107,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/lib/.libs \
-I $(top_builddir)/gnulib/lib/.libs \
-I $(top_builddir)/ocaml \
+ -I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/common/mlxml \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mlutils \
@@ -189,12 +191,14 @@ endif
OCAMLLINKFLAGS = \
mlstdutils.$(MLARCHIVE) \
mlcutils.$(MLARCHIVE) \
+ mlpcre.$(MLARCHIVE) \
mlguestfs.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
common_utils_tests_DEPENDENCIES = \
$(common_utils_tests_THEOBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
$(MLLIB_CMA) \
$(top_srcdir)/ocaml-link.sh
common_utils_tests_LINK = \
@@ -206,6 +210,7 @@ common_utils_tests_LINK = \
getopt_tests_DEPENDENCIES = \
$(getopt_tests_THEOBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
$(MLLIB_CMA) \
$(top_srcdir)/ocaml-link.sh
getopt_tests_LINK = \
@@ -217,6 +222,7 @@ getopt_tests_LINK = \
JSON_tests_DEPENDENCIES = \
$(JSON_tests_THEOBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
$(MLLIB_CMA) \
$(top_srcdir)/ocaml-link.sh
JSON_tests_LINK = \
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 597128967..3355365c6 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -155,73 +155,56 @@ let virt_tools_data_dir =
) in
fun () -> Lazy.force dir
+(* Used by parse_size and parse_resize below. *)
+let const_re = PCRE.compile "^([.0-9]+)([bKMG])$"
+let plus_const_re = PCRE.compile "^\\+([.0-9]+)([bKMG])$"
+let minus_const_re = PCRE.compile "^-([.0-9]+)([bKMG])$"
+let percent_re = PCRE.compile "^([.0-9]+)%$"
+let plus_percent_re = PCRE.compile "^\\+([.0-9]+)%$"
+let minus_percent_re = PCRE.compile "^-([.0-9]+)%$"
+let size_scaled f = function
+ | "b" -> Int64.of_float f
+ | "K" -> Int64.of_float (f *. 1024.)
+ | "M" -> Int64.of_float (f *. 1024. *. 1024.)
+ | "G" -> Int64.of_float (f *. 1024. *. 1024. *. 1024.)
+ | _ -> assert false
+
(* Parse a size field, eg. "10G". *)
-let parse_size =
- let const_re = Str.regexp "^\\([.0-9]+\\)\\([bKMG]\\)$" in
- fun field ->
- let matches rex = Str.string_match rex field 0 in
- let sub i = Str.matched_group i field in
- let size_scaled f = function
- | "b" -> Int64.of_float f
- | "K" -> Int64.of_float (f *. 1024.)
- | "M" -> Int64.of_float (f *. 1024. *. 1024.)
- | "G" -> Int64.of_float (f *. 1024. *. 1024. *. 1024.)
- | _ -> assert false
- in
-
- if matches const_re then (
- size_scaled (float_of_string (sub 1)) (sub 2)
- )
- else
- error "%s: cannot parse size field" field
+let parse_size field =
+ if PCRE.matches const_re field then
+ size_scaled (float_of_string (PCRE.sub 1)) (PCRE.sub 2)
+ else
+ error "%s: cannot parse size field" field
(* Parse a size field, eg. "10G", "+20%" etc. Used particularly by
* virt-resize --resize and --resize-force options.
*)
-let parse_resize =
- let const_re = Str.regexp "^\\([.0-9]+\\)\\([bKMG]\\)$"
- and plus_const_re = Str.regexp "^\\+\\([.0-9]+\\)\\([bKMG]\\)$"
- and minus_const_re = Str.regexp "^-\\([.0-9]+\\)\\([bKMG]\\)$"
- and percent_re = Str.regexp "^\\([.0-9]+\\)%$"
- and plus_percent_re = Str.regexp "^\\+\\([.0-9]+\\)%$"
- and minus_percent_re = Str.regexp "^-\\([.0-9]+\\)%$"
- in
- fun oldsize field ->
- let matches rex = Str.string_match rex field 0 in
- let sub i = Str.matched_group i field in
- let size_scaled f = function
- | "b" -> Int64.of_float f
- | "K" -> Int64.of_float (f *. 1024.)
- | "M" -> Int64.of_float (f *. 1024. *. 1024.)
- | "G" -> Int64.of_float (f *. 1024. *. 1024. *. 1024.)
- | _ -> assert false
- in
-
- if matches const_re then (
- size_scaled (float_of_string (sub 1)) (sub 2)
- )
- else if matches plus_const_re then (
- let incr = size_scaled (float_of_string (sub 1)) (sub 2) in
- oldsize +^ incr
- )
- else if matches minus_const_re then (
- let incr = size_scaled (float_of_string (sub 1)) (sub 2) in
- oldsize -^ incr
- )
- else if matches percent_re then (
- let percent = Int64.of_float (10. *. float_of_string (sub 1)) in
- oldsize *^ percent /^ 1000L
- )
- else if matches plus_percent_re then (
- let percent = Int64.of_float (10. *. float_of_string (sub 1)) in
- oldsize +^ oldsize *^ percent /^ 1000L
- )
- else if matches minus_percent_re then (
- let percent = Int64.of_float (10. *. float_of_string (sub 1)) in
- oldsize -^ oldsize *^ percent /^ 1000L
- )
- else
- error "%s: cannot parse resize field" field
+let parse_resize oldsize field =
+ if PCRE.matches const_re field then (
+ size_scaled (float_of_string (PCRE.sub 1)) (PCRE.sub 2)
+ )
+ else if PCRE.matches plus_const_re field then (
+ let incr = size_scaled (float_of_string (PCRE.sub 1)) (PCRE.sub 2) in
+ oldsize +^ incr
+ )
+ else if PCRE.matches minus_const_re field then (
+ let incr = size_scaled (float_of_string (PCRE.sub 1)) (PCRE.sub 2) in
+ oldsize -^ incr
+ )
+ else if PCRE.matches percent_re field then (
+ let percent = Int64.of_float (10. *. float_of_string (PCRE.sub 1)) in
+ oldsize *^ percent /^ 1000L
+ )
+ else if PCRE.matches plus_percent_re field then (
+ let percent = Int64.of_float (10. *. float_of_string (PCRE.sub 1)) in
+ oldsize +^ oldsize *^ percent /^ 1000L
+ )
+ else if PCRE.matches minus_percent_re field then (
+ let percent = Int64.of_float (10. *. float_of_string (PCRE.sub 1)) in
+ oldsize -^ oldsize *^ percent /^ 1000L
+ )
+ else
+ error "%s: cannot parse resize field" field
let human_size i =
let sign, i = if i < 0L then "-", Int64.neg i else "", i in
diff --git a/mllib/common_utils_tests.ml b/mllib/common_utils_tests.ml
index ee8a60463..f7a4eafd1 100644
--- a/mllib/common_utils_tests.ml
+++ b/mllib/common_utils_tests.ml
@@ -29,8 +29,16 @@ let assert_equal_int = assert_equal ~printer:(fun x -> string_of_int
x)
let assert_equal_int64 = assert_equal ~printer:(fun x -> Int64.to_string x)
let assert_equal_intlist = assert_equal ~printer:(fun x -> "(" ^
(String.concat ";" (List.map string_of_int x)) ^ ")")
-(* Test Common_utils.parse_size. *)
+(* Test Common_utils.parse_size and Common_utils.parse_resize. *)
let test_parse_resize ctx =
+ assert_equal_int64 1_L (parse_size "1b");
+ assert_equal_int64 10_L (parse_size "10b");
+ assert_equal_int64 1024_L (parse_size "1K");
+ assert_equal_int64 102400_L (parse_size "100K");
+ (* Fractions are always rounded down. *)
+ assert_equal_int64 1153433_L (parse_size "1.1M");
+ assert_equal_int64 1202590842_L (parse_size "1.12G");
+
(* For absolute sizes, oldsize is ignored. *)
assert_equal_int64 100_L (parse_resize 100_L "100b");
assert_equal_int64 100_L (parse_resize 1000_L "100b");
diff --git a/resize/Makefile.am b/resize/Makefile.am
index df73af4a4..035bfb9fe 100644
--- a/resize/Makefile.am
+++ b/resize/Makefile.am
@@ -65,6 +65,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mlprogress \
-I $(top_builddir)/common/mlutils \
+ -I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/mllib
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -90,6 +91,7 @@ OCAMLLINKFLAGS = \
mlstdutils.$(MLARCHIVE) \
mlguestfs.$(MLARCHIVE) \
mlprogress.$(MLARCHIVE) \
+ mlpcre.$(MLARCHIVE) \
mlcutils.$(MLARCHIVE) \
mllib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
@@ -98,6 +100,7 @@ virt_resize_DEPENDENCIES = \
$(OBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
../common/mlutils/mlcutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
../mllib/mllib.$(MLARCHIVE) \
$(top_srcdir)/ocaml-link.sh
virt_resize_LINK = \
diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am
index 3b4ea3420..427d35670 100644
--- a/sparsify/Makefile.am
+++ b/sparsify/Makefile.am
@@ -73,6 +73,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mlprogress \
-I $(top_builddir)/common/mlutils \
+ -I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/mllib
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -98,6 +99,7 @@ OCAMLLINKFLAGS = \
mlstdutils.$(MLARCHIVE) \
mlguestfs.$(MLARCHIVE) \
mlprogress.$(MLARCHIVE) \
+ mlpcre.$(MLARCHIVE) \
mlcutils.$(MLARCHIVE) \
mllib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
@@ -106,6 +108,7 @@ virt_sparsify_DEPENDENCIES = \
$(OBJECTS) \
../common/mlstdutils/mlstdutils.$(MLARCHIVE) \
../common/mlutils/mlcutils.$(MLARCHIVE) \
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
../mllib/mllib.$(MLARCHIVE) \
$(top_srcdir)/ocaml-link.sh
virt_sparsify_LINK = \
--
2.13.2