Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More efficient breakString #177

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions src/ocamlutil/pretty.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,36 @@ type doc =
| Unmark

(* Break a string at \n *)
let rec breakString (acc: doc) (str: string) : doc =
(* Printf.printf "breaking string %s\n" str; *)
match (try Some (String.index str '\n') with Not_found -> None) with
| None -> if acc = Nil then Text str else CText (acc, str)
| Some r ->
(* Printf.printf "r=%d\n" r; *)
let len = String.length str in
if r > 0 then begin
(* Printf.printf "Taking %s\n" (String.sub str 0 r); *)
let acc' = Concat(CText (acc, String.sub str 0 r), Line) in
if r = len - 1 then (* The last one *)
acc'
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
else begin
(* Printf.printf "Continuing with %s\n" (String.sub str (r + 1) (len - r - 1)); *)
breakString acc'
(String.sub str (r + 1) (len - r - 1))
end
end else (* The first is a newline *)
breakString (Concat(acc, Line))
(String.sub str (r + 1) (len - r - 1))
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
(* Replaces an earlier implementation that relied on repeatedly calling sub, with one inspired by the standard library *)
let breakString s =
let r = ref Nil in
let j = ref (String.length s) in
for i = String.length s - 1 downto 0 do
if String.unsafe_get s i = '\n' then begin
let text = String.sub s (i + 1) (!j - i - 1) in
(if text = "" then
if !r = Nil then
r := Line
else
r := Concat(Line, !r)
else
if !r = Nil then
r := Concat(Line, Text text)
else
r := Concat(Line, Concat(Text text, !r))
);
j := i
end
done;
let text = String.sub s 0 !j in
if text = "" then
!r
else
Concat(Text text, !r)


let nil = Nil
let text s = breakString nil s
let text s = breakString s
let num i = text (string_of_int i)
let num64 i = text (Int64.to_string i)
let real f = text (string_of_float f)
Expand Down Expand Up @@ -591,7 +597,7 @@ let print_with_state ~width f =
topAlignAbsCol := old_topAlignAbsCol;
breakAllMode := old_breakAllMode
in

match f () with
| r ->
finally ();
Expand Down Expand Up @@ -705,7 +711,7 @@ let gprintf (finish : doc -> 'b)
else
s
in
collect (breakString acc str) (succ j))
collect (Concat(acc, breakString str)) (succ j))
| 'c' ->
Obj.magic(fun c ->
collect (dctext1 acc (String.make 1 c)) (succ j))
Expand Down
Loading