[Libguestfs] [PATCH 1/2] mllib: Rewrite text wrapping function so it can handle newlines within the text.

Richard W.M. Jones rjones at redhat.com
Tue Jun 24 15:56:22 UTC 2014


---
 mllib/common_utils.ml  | 48 ++++++++++++++++++++++++++++++++----------------
 mllib/common_utils.mli |  2 +-
 resize/resize.ml       |  4 ++--
 3 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 1ce2abe..e500ea4 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -57,25 +57,41 @@ let le32_of_int i =
   String.unsafe_set s 3 (Char.unsafe_chr (Int64.to_int c3));
   s
 
-let output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done
+type wrap_break_t = WrapEOS | WrapSpace | WrapNL
 
-let wrap ?(chan = stdout) ?(hanging = 0) str =
-  let rec _wrap col str =
-    let n = String.length str in
-    let i = try String.index str ' ' with Not_found -> n in
-    let col =
-      if col+i >= 72 then (
+let rec wrap ?(chan = stdout) ?(indent = 0) str =
+  let len = String.length str in
+  _wrap chan indent 0 0 len str
+
+and _wrap chan indent column i len str =
+  if i < len then (
+    let (j, break) = _wrap_find_next_break i len str in
+    let next_column =
+      if column + (j-i) >= 72 then (
         output_char chan '\n';
-        output_spaces chan hanging;
-        i+hanging+1
-      ) else col+i+1 in
-    output_string chan (String.sub str 0 i);
-    if i < n then (
+        output_spaces chan indent;
+        indent + (j-i) + 1
+      )
+      else column + (j-i) + 1 in
+    output chan str i (j-i);
+    match break with
+    | WrapEOS -> ()
+    | WrapSpace ->
       output_char chan ' ';
-      _wrap col (String.sub str (i+1) (n-(i+1)))
-    )
-  in
-  _wrap 0 str
+      _wrap chan indent next_column (j+1) len str
+    | WrapNL ->
+      output_char chan '\n';
+      output_spaces chan indent;
+      _wrap chan indent indent (j+1) len str
+  )
+
+and _wrap_find_next_break i len str =
+  if i >= len then (len, WrapEOS)
+  else if String.unsafe_get str i = ' ' then (i, WrapSpace)
+  else if String.unsafe_get str i = '\n' then (i, WrapNL)
+  else _wrap_find_next_break (i+1) len str
+
+and output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done
 
 let string_prefix str prefix =
   let n = String.length prefix in
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
index 16b9dee..792c7b5 100644
--- a/mllib/common_utils.mli
+++ b/mllib/common_utils.mli
@@ -31,7 +31,7 @@ val roundup64 : int64 -> int64 -> int64
 val int_of_le32 : string -> int64
 val le32_of_int : int64 -> string
 
-val wrap : ?chan:out_channel -> ?hanging:int -> string -> unit
+val wrap : ?chan:out_channel -> ?indent:int -> string -> unit
 (** Wrap text. *)
 
 val string_prefix : string -> string -> bool
diff --git a/resize/resize.ml b/resize/resize.ml
index dec23b1..7ae8c37 100644
--- a/resize/resize.ml
+++ b/resize/resize.ml
@@ -833,7 +833,7 @@ read the man page virt-resize(1).
                      (expand_content_method p.p_type))
               ) else "" in
 
-        wrap ~hanging:4 (text ^ "\n\n")
+        wrap ~indent:4 (text ^ "\n\n")
     ) partitions;
 
     List.iter (
@@ -852,7 +852,7 @@ read the man page virt-resize(1).
                      (expand_content_method lv.lv_type))
               ) else "" in
 
-            wrap ~hanging:4 (text ^ "\n\n")
+            wrap ~indent:4 (text ^ "\n\n")
     ) lvs;
 
     if surplus > 0L then (
-- 
1.9.0




More information about the Libguestfs mailing list