summaryrefslogtreecommitdiffstats
path: root/stdlib/format.ml
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/format.ml')
-rw-r--r--stdlib/format.ml551
1 files changed, 302 insertions, 249 deletions
diff --git a/stdlib/format.ml b/stdlib/format.ml
index 7a46c31ca..161cbd8ce 100644
--- a/stdlib/format.ml
+++ b/stdlib/format.ml
@@ -19,6 +19,11 @@
**************************************************************)
+type size;;
+
+external size_of_int : int -> size = "%identity";;
+external int_of_size : size -> int = "%identity";;
+
(* Tokens are one of the following : *)
type pp_token =
@@ -58,7 +63,9 @@ and tblock = Pp_tbox of int list ref (* Tabulation box *)
elements are tuples (size, token, length), where
size is set when the size of the block is known
len is the declared length of the token. *)
-type pp_queue_elem = {mutable elem_size : int; token : pp_token; length : int};;
+type pp_queue_elem = {
+ mutable elem_size : size; token : pp_token; length : int
+};;
(* Scan stack:
each element is (left_total, queue element) where left_total
@@ -249,7 +256,7 @@ let pp_skip_token state =
match take_queue state.pp_queue with
{elem_size = size; length = len} ->
state.pp_left_total <- state.pp_left_total - len;
- state.pp_space_left <- state.pp_space_left + size;;
+ state.pp_space_left <- state.pp_space_left + int_of_size size;;
(**************************************************************
@@ -379,6 +386,7 @@ let rec advance_left state =
try
match peek_queue state.pp_queue with
{elem_size = size; token = tok; length = len} ->
+ let size = int_of_size size in
if not
(size < 0 &&
(state.pp_right_total - state.pp_left_total < state.pp_space_left))
@@ -393,17 +401,24 @@ let rec advance_left state =
let enqueue_advance state tok = pp_enqueue state tok; advance_left state;;
(* To enqueue a string : try to advance. *)
-let enqueue_string_as state n s =
- enqueue_advance state {elem_size = n; token = Pp_text s; length = n};;
+let make_queue_elem size tok len =
+ {elem_size = size; token = tok; length = len};;
-let enqueue_string state s = enqueue_string_as state (String.length s) s;;
+let enqueue_string_as state size s =
+ let len = int_of_size size in
+ enqueue_advance state (make_queue_elem size (Pp_text s) len);;
+
+let enqueue_string state s =
+ let len = String.length s in
+ enqueue_string_as state (size_of_int len) s;;
(* Routines for scan stack
determine sizes of blocks. *)
(* The scan_stack is never empty. *)
let scan_stack_bottom =
- [Scan_elem (-1, {elem_size = (-1); token = Pp_text ""; length = 0})];;
+ let q_elem = make_queue_elem (size_of_int (-1)) (Pp_text "") 0 in
+ [Scan_elem (-1, q_elem)];;
(* Set size of blocks on scan stack:
if ty = true then size of break is set else size of block is set;
@@ -416,21 +431,23 @@ let clear_scan_stack state = state.pp_scan_stack <- scan_stack_bottom;;
since scan_push is used on breaks and opening of boxes. *)
let set_size state ty =
match state.pp_scan_stack with
- | Scan_elem (left_tot,
- ({elem_size = size; token = tok} as queue_elem)) :: t ->
+ | Scan_elem
+ (left_tot,
+ ({elem_size = size; token = tok} as queue_elem)) :: t ->
+ let size = int_of_size size in
(* test if scan stack contains any data that is not obsolete. *)
if left_tot < state.pp_left_total then clear_scan_stack state else
begin match tok with
| Pp_break (_, _) | Pp_tbreak (_, _) ->
if ty then
begin
- queue_elem.elem_size <- state.pp_right_total + size;
+ queue_elem.elem_size <- size_of_int (state.pp_right_total + size);
state.pp_scan_stack <- t
end
| Pp_begin (_, _) ->
if not ty then
begin
- queue_elem.elem_size <- state.pp_right_total + size;
+ queue_elem.elem_size <- size_of_int (state.pp_right_total + size);
state.pp_scan_stack <- t
end
| _ -> () (* scan_push is only used for breaks and boxes. *)
@@ -450,9 +467,12 @@ let scan_push state b tok =
let pp_open_box_gen state indent br_ty =
state.pp_curr_depth <- state.pp_curr_depth + 1;
if state.pp_curr_depth < state.pp_max_boxes then
- (scan_push state false
- {elem_size = (- state.pp_right_total);
- token = Pp_begin (indent, br_ty); length = 0}) else
+ let elem =
+ make_queue_elem
+ (size_of_int (- state.pp_right_total))
+ (Pp_begin (indent, br_ty))
+ 0 in
+ scan_push state false elem else
if state.pp_curr_depth = state.pp_max_boxes
then enqueue_string state state.pp_ellipsis;;
@@ -465,7 +485,8 @@ let pp_close_box state () =
begin
if state.pp_curr_depth < state.pp_max_boxes then
begin
- pp_enqueue state {elem_size = 0; token = Pp_end; length = 0};
+ pp_enqueue state
+ {elem_size = size_of_int 0; token = Pp_end; length = 0};
set_size state true; set_size state false
end;
state.pp_curr_depth <- state.pp_curr_depth - 1;
@@ -478,12 +499,13 @@ let pp_open_tag state tag_name =
state.pp_print_open_tag tag_name end;
if state.pp_mark_tags then
pp_enqueue state
- {elem_size = 0; token = Pp_open_tag tag_name; length = 0};;
+ {elem_size = size_of_int 0; token = Pp_open_tag tag_name; length = 0};;
(* Close a tag, popping it from the tag stack. *)
let pp_close_tag state () =
if state.pp_mark_tags then
- pp_enqueue state {elem_size = 0; token = Pp_close_tag; length = 0};
+ pp_enqueue state
+ {elem_size = size_of_int 0; token = Pp_close_tag; length = 0};
if state.pp_print_tags then
begin match state.pp_tag_stack with
| tag_name :: tags ->
@@ -546,11 +568,15 @@ let pp_flush_queue state b =
**************************************************************)
(* To format a string. *)
-let pp_print_as state n s =
+let pp_print_as_size state size s =
if state.pp_curr_depth < state.pp_max_boxes
- then enqueue_string_as state n s;;
+ then enqueue_string_as state size s;;
-let pp_print_string state s = pp_print_as state (String.length s) s;;
+let pp_print_as state isize s =
+ pp_print_as_size state (size_of_int isize) s;;
+
+let pp_print_string state s =
+ pp_print_as state (String.length s) s;;
(* To format an integer. *)
let pp_print_int state i = pp_print_string state (string_of_int i);;
@@ -563,7 +589,9 @@ let pp_print_bool state b = pp_print_string state (string_of_bool b);;
(* To format a char. *)
let pp_print_char state c =
- let s = String.create 1 in s.[0] <- c; pp_print_as state 1 s;;
+ let s = String.create 1 in
+ s.[0] <- c;
+ pp_print_as state 1 s;;
(* Opening boxes. *)
let pp_open_hbox state () = pp_open_box_gen state 0 Pp_hbox
@@ -583,12 +611,12 @@ and pp_print_flush state () =
(* To get a newline when one does not want to close the current block. *)
let pp_force_newline state () =
if state.pp_curr_depth < state.pp_max_boxes then
- enqueue_advance state {elem_size = 0; token = Pp_newline; length = 0};;
+ enqueue_advance state (make_queue_elem (size_of_int 0) Pp_newline 0);;
(* To format something if the line has just been broken. *)
let pp_print_if_newline state () =
if state.pp_curr_depth < state.pp_max_boxes then
- enqueue_advance state {elem_size = 0; token = Pp_if_newline; length = 0};;
+ enqueue_advance state (make_queue_elem (size_of_int 0) Pp_if_newline 0);;
(* Breaks: indicate where a block may be broken.
If line is broken then offset is added to the indentation of the current
@@ -596,9 +624,12 @@ let pp_print_if_newline state () =
To do (?) : add a maximum width and offset value. *)
let pp_print_break state width offset =
if state.pp_curr_depth < state.pp_max_boxes then
- scan_push state true
- {elem_size = (- state.pp_right_total); token = Pp_break (width, offset);
- length = width};;
+ let elem =
+ make_queue_elem
+ (size_of_int (- state.pp_right_total))
+ (Pp_break (width, offset))
+ width in
+ scan_push state true elem;;
let pp_print_space state () = pp_print_break state 1 0
and pp_print_cut state () = pp_print_break state 0 0;;
@@ -607,29 +638,35 @@ and pp_print_cut state () = pp_print_break state 0 0;;
let pp_open_tbox state () =
state.pp_curr_depth <- state.pp_curr_depth + 1;
if state.pp_curr_depth < state.pp_max_boxes then
- enqueue_advance state
- {elem_size = 0;
- token = Pp_tbegin (Pp_tbox (ref [])); length = 0};;
+ let elem =
+ make_queue_elem (size_of_int 0) (Pp_tbegin (Pp_tbox (ref []))) 0 in
+ enqueue_advance state elem;;
(* Close a tabulation block. *)
let pp_close_tbox state () =
if state.pp_curr_depth > 1 then begin
if state.pp_curr_depth < state.pp_max_boxes then
- enqueue_advance state {elem_size = 0; token = Pp_tend; length = 0};
- state.pp_curr_depth <- state.pp_curr_depth - 1 end;;
+ let elem = make_queue_elem (size_of_int 0) Pp_tend 0 in
+ enqueue_advance state elem;
+ state.pp_curr_depth <- state.pp_curr_depth - 1 end;;
(* Print a tabulation break. *)
let pp_print_tbreak state width offset =
if state.pp_curr_depth < state.pp_max_boxes then
- scan_push state true
- {elem_size = (- state.pp_right_total); token = Pp_tbreak (width, offset);
- length = width};;
+ let elem =
+ make_queue_elem
+ (size_of_int (- state.pp_right_total))
+ (Pp_tbreak (width, offset))
+ width in
+ scan_push state true elem;;
let pp_print_tab state () = pp_print_tbreak state 0 0;;
let pp_set_tab state () =
- if state.pp_curr_depth < state.pp_max_boxes
- then enqueue_advance state {elem_size = 0; token = Pp_stab; length=0};;
+ if state.pp_curr_depth < state.pp_max_boxes then
+ let elem =
+ make_queue_elem (size_of_int 0) Pp_stab 0 in
+ enqueue_advance state elem;;
(**************************************************************
@@ -719,7 +756,7 @@ let pp_make_formatter f g h i =
(* The initial state of the formatter contains a dummy box. *)
let pp_q = make_queue () in
let sys_tok =
- {elem_size = (- 1); token = Pp_begin (0, Pp_hovbox); length = 0} in
+ make_queue_elem (size_of_int (-1)) (Pp_begin (0, Pp_hovbox)) 0 in
add_queue sys_tok pp_q;
let sys_scan_stack =
(Scan_elem (1, sys_tok)) :: scan_stack_bottom in
@@ -774,10 +811,8 @@ let make_formatter f g =
let formatter_of_out_channel oc =
make_formatter (output oc) (fun () -> flush oc);;
-let unit_out ppf = ();;
-
let formatter_of_buffer b =
- make_formatter (Buffer.add_substring b) unit_out;;
+ make_formatter (Buffer.add_substring b) ignore;;
let stdbuf = Buffer.create 512;;
@@ -897,8 +932,10 @@ let invalid_integer fmt i =
(* Finding an integer out of a sub-string of the format. *)
let format_int_of_string fmt i s =
- try int_of_string s with
- | Failure s -> invalid_integer fmt i;;
+ let sz =
+ try int_of_string s with
+ | Failure s -> invalid_integer fmt i in
+ size_of_int sz;;
(* Getting strings out of buffers. *)
let get_buffer_out b =
@@ -926,6 +963,8 @@ let implode_rev s0 = function
| [] -> s0
| l -> String.concat "" (List.rev (s0 :: l));;
+external format_to_string : ('a, 'b, 'c, 'd) format4 -> string = "%identity";;
+
(* [fprintf_out] is the printf-like function generator: given the
- [str] flag that tells if we are printing into a string,
- the [out] function that has to be called at the end of formatting,
@@ -934,204 +973,216 @@ let implode_rev s0 = function
according to the format.
Regular [fprintf]-like functions of this module are obtained via partial
applications of [fprintf_out]. *)
-let rec fprintf_out str out ppf fmt =
-
- let fmt = string_of_format fmt in
- let limit = String.length fmt in
-
- let print_as = ref None in
-
- let pp_print_as_char c =
- match !print_as with
- | None -> pp_print_char ppf c
- | Some size ->
- pp_print_as ppf size (String.make 1 c);
- print_as := None
- and pp_print_as_string s =
- match !print_as with
- | None -> pp_print_string ppf s
- | Some size ->
- pp_print_as ppf size s;
- print_as := None in
-
- let rec doprn i =
- if i >= limit then Obj.magic (out ppf) else
- match fmt.[i] with
- | '%' ->
- Printf.scan_format fmt i cont_s cont_a cont_t cont_f cont_m
- | '@' ->
- let i = succ i in
- if i >= limit then invalid_format fmt i else
- begin match fmt.[i] with
- | '[' ->
- do_pp_open_box ppf (succ i)
- | ']' ->
- pp_close_box ppf ();
- doprn (succ i)
- | '{' ->
- do_pp_open_tag ppf (succ i)
- | '}' ->
- pp_close_tag ppf ();
- doprn (succ i)
- | ' ' ->
- pp_print_space ppf ();
- doprn (succ i)
- | ',' ->
- pp_print_cut ppf ();
- doprn (succ i)
- | '?' ->
- pp_print_flush ppf ();
- doprn (succ i)
- | '.' ->
- pp_print_newline ppf ();
- doprn (succ i)
- | '\n' ->
- pp_force_newline ppf ();
- doprn (succ i)
- | ';' ->
- do_pp_break ppf (succ i)
- | '<' ->
- let got_size size i =
- print_as := Some size;
- doprn (skip_gt i) in
- get_int (succ i) got_size
- | '@' as c ->
+let mkprintf str get_out =
+ let rec kprintf k fmt =
+ let fmt = format_to_string fmt in
+ let len = String.length fmt in
+
+ let kpr fmt v =
+ let ppf = get_out fmt in
+ let print_as = ref None in
+ let pp_print_as_char c =
+ match !print_as with
+ | None -> pp_print_char ppf c
+ | Some size ->
+ pp_print_as_size ppf size (String.make 1 c);
+ print_as := None
+ and pp_print_as_string s =
+ match !print_as with
+ | None -> pp_print_string ppf s
+ | Some size ->
+ pp_print_as_size ppf size s;
+ print_as := None in
+
+ let rec doprn n i =
+ if i >= len then Obj.magic (k ppf) else
+ match fmt.[i] with
+ | '%' ->
+ Printf.scan_format fmt v n i cont_s cont_a cont_t cont_f cont_m
+ | '@' ->
+ let i = succ i in
+ if i >= len then invalid_format fmt i else
+ begin match fmt.[i] with
+ | '[' ->
+ do_pp_open_box ppf n (succ i)
+ | ']' ->
+ pp_close_box ppf ();
+ doprn n (succ i)
+ | '{' ->
+ do_pp_open_tag ppf n (succ i)
+ | '}' ->
+ pp_close_tag ppf ();
+ doprn n (succ i)
+ | ' ' ->
+ pp_print_space ppf ();
+ doprn n (succ i)
+ | ',' ->
+ pp_print_cut ppf ();
+ doprn n (succ i)
+ | '?' ->
+ pp_print_flush ppf ();
+ doprn n (succ i)
+ | '.' ->
+ pp_print_newline ppf ();
+ doprn n (succ i)
+ | '\n' ->
+ pp_force_newline ppf ();
+ doprn n (succ i)
+ | ';' ->
+ do_pp_break ppf n (succ i)
+ | '<' ->
+ let got_size size n i =
+ print_as := Some size;
+ doprn n (skip_gt i) in
+ get_int n (succ i) got_size
+ | '@' as c ->
+ pp_print_as_char c;
+ doprn n (succ i)
+ | c -> invalid_format fmt i
+ end
+ | c ->
pp_print_as_char c;
- doprn (succ i)
- | c -> invalid_format fmt i
- end
- | c ->
- pp_print_as_char c;
- doprn (succ i)
-
- and cont_s s i =
- pp_print_as_string s; doprn i
- and cont_a printer arg i =
- if str then
- pp_print_as_string ((Obj.magic printer : unit -> _ -> string) () arg)
- else
- printer ppf arg;
- doprn i
- and cont_t printer i =
- if str then
- pp_print_as_string ((Obj.magic printer : unit -> string) ())
- else
- printer ppf;
- doprn i
- and cont_f i =
- pp_print_flush ppf (); doprn i
-
- and cont_m sfmt i =
- fprintf_out str (fun ppf -> Obj.magic doprn i) ppf sfmt
-
- and get_int i c =
- if i >= limit then invalid_integer fmt i else
- match fmt.[i] with
- | ' ' -> get_int (succ i) c
- | '%' ->
- let cont_s s i = c (format_int_of_string fmt i s) i
- and cont_a printer arg i = invalid_integer fmt i
- and cont_t printer i = invalid_integer fmt i
- and cont_f i = invalid_integer fmt i in
- Printf.scan_format fmt i cont_s cont_a cont_t cont_f cont_m
- | _ ->
- let rec get j =
- if j >= limit then invalid_integer fmt j else
- match fmt.[j] with
- | '0' .. '9' | '-' -> get (succ j)
+ doprn n (succ i)
+
+ and cont_s n s i =
+ pp_print_as_string s; doprn n i
+ and cont_a n printer arg i =
+ if str then
+ pp_print_as_string ((Obj.magic printer : unit -> _ -> string) () arg)
+ else
+ printer ppf arg;
+ doprn n i
+ and cont_t n printer i =
+ if str then
+ pp_print_as_string ((Obj.magic printer : unit -> string) ())
+ else
+ printer ppf;
+ doprn n i
+ and cont_f n i =
+ pp_print_flush ppf (); doprn n i
+
+ and cont_m n sfmt i =
+ kprintf (Obj.magic (fun _ -> doprn n i)) sfmt
+
+ and get_int n i c =
+ if i >= len then invalid_integer fmt i else
+ match fmt.[i] with
+ | ' ' -> get_int n (succ i) c
+ | '%' ->
+ let cont_s n s i = c (format_int_of_string fmt i s) n i
+ and cont_a n printer arg i = invalid_integer fmt i
+ and cont_t n printer i = invalid_integer fmt i
+ and cont_f n i = invalid_integer fmt i
+ and cont_m n sfmt i = invalid_integer fmt i in
+ Printf.scan_format fmt v n i cont_s cont_a cont_t cont_f cont_m
| _ ->
- if j = i then c 0 j else
- c (format_int_of_string fmt j (String.sub fmt i (j - i))) j in
- get i
-
- and skip_gt i =
- if i >= limit then invalid_format fmt i else
- match fmt.[i] with
- | ' ' -> skip_gt (succ i)
- | '>' -> succ i
- | _ -> invalid_format fmt i
-
- and get_box_kind i =
- if i >= limit then Pp_box, i else
- match fmt.[i] with
- | 'h' ->
- let i = succ i in
- if i >= limit then Pp_hbox, i else
- begin match fmt.[i] with
- | 'o' ->
- let i = succ i in
- if i >= limit then format_invalid_arg "bad box format" fmt i else
- begin match fmt.[i] with
- | 'v' -> Pp_hovbox, succ i
- | c ->
- format_invalid_arg
- ("bad box name ho" ^ String.make 1 c) fmt i end
- | 'v' -> Pp_hvbox, succ i
- | c -> Pp_hbox, i
- end
- | 'b' -> Pp_box, succ i
- | 'v' -> Pp_vbox, succ i
- | _ -> Pp_box, i
-
- and get_tag_name i c =
- let rec get accu i j =
- if j >= limit
- then c (implode_rev (String.sub fmt i (j - i)) accu) j else
- match fmt.[j] with
- | '>' -> c (implode_rev (String.sub fmt i (j - i)) accu) j
- | '%' ->
- let s0 = String.sub fmt i (j - i) in
- let cont_s s i = get (s :: s0 :: accu) i i
- and cont_a printer arg i =
- let s =
- if str then (Obj.magic printer : unit -> _ -> string) () arg
- else exstring printer arg in
- get (s :: s0 :: accu) i i
- and cont_t printer i =
- let s =
- if str then (Obj.magic printer : unit -> string) ()
- else exstring (fun ppf () -> printer ppf) () in
- get (s :: s0 :: accu) i i
- and cont_f i =
- format_invalid_arg "bad tag name specification" fmt i in
- Printf.scan_format fmt j cont_s cont_a cont_t cont_f cont_m
- | c -> get accu i (succ j) in
- get [] i i
-
- and do_pp_break ppf i =
- if i >= limit then begin pp_print_space ppf (); doprn i end else
- match fmt.[i] with
- | '<' ->
- let rec got_nspaces nspaces i =
- get_int i (got_offset nspaces)
- and got_offset nspaces offset i =
- pp_print_break ppf nspaces offset;
- doprn (skip_gt i) in
- get_int (succ i) got_nspaces
- | c -> pp_print_space ppf (); doprn i
-
- and do_pp_open_box ppf i =
- if i >= limit then begin pp_open_box_gen ppf 0 Pp_box; doprn i end else
- match fmt.[i] with
- | '<' ->
- let kind, i = get_box_kind (succ i) in
- let got_size size i =
- pp_open_box_gen ppf size kind;
- doprn (skip_gt i) in
- get_int i got_size
- | c -> pp_open_box_gen ppf 0 Pp_box; doprn i
-
- and do_pp_open_tag ppf i =
- if i >= limit then begin pp_open_tag ppf ""; doprn i end else
- match fmt.[i] with
- | '<' ->
- let got_name tag_name i =
- pp_open_tag ppf tag_name;
- doprn (skip_gt i) in
- get_tag_name (succ i) got_name
- | c -> pp_open_tag ppf ""; doprn i in
-
- doprn 0;;
+ let rec get j =
+ if j >= len then invalid_integer fmt j else
+ match fmt.[j] with
+ | '0' .. '9' | '-' -> get (succ j)
+ | _ ->
+ let size =
+ if j = i then size_of_int 0 else
+ format_int_of_string fmt j (String.sub fmt i (j - i)) in
+ c size n j in
+ get i
+
+ and skip_gt i =
+ if i >= len then invalid_format fmt i else
+ match fmt.[i] with
+ | ' ' -> skip_gt (succ i)
+ | '>' -> succ i
+ | _ -> invalid_format fmt i
+
+ and get_box_kind i =
+ if i >= len then Pp_box, i else
+ match fmt.[i] with
+ | 'h' ->
+ let i = succ i in
+ if i >= len then Pp_hbox, i else
+ begin match fmt.[i] with
+ | 'o' ->
+ let i = succ i in
+ if i >= len then format_invalid_arg "bad box format" fmt i else
+ begin match fmt.[i] with
+ | 'v' -> Pp_hovbox, succ i
+ | c ->
+ format_invalid_arg
+ ("bad box name ho" ^ String.make 1 c) fmt i end
+ | 'v' -> Pp_hvbox, succ i
+ | c -> Pp_hbox, i
+ end
+ | 'b' -> Pp_box, succ i
+ | 'v' -> Pp_vbox, succ i
+ | _ -> Pp_box, i
+
+ and get_tag_name n i c =
+ let rec get accu n i j =
+ if j >= len
+ then c (implode_rev (String.sub fmt i (j - i)) accu) n j else
+ match fmt.[j] with
+ | '>' -> c (implode_rev (String.sub fmt i (j - i)) accu) n j
+ | '%' ->
+ let s0 = String.sub fmt i (j - i) in
+ let cont_s n s i = get (s :: s0 :: accu) n i i
+ and cont_a n printer arg i =
+ let s =
+ if str
+ then (Obj.magic printer : unit -> _ -> string) () arg
+ else exstring printer arg in
+ get (s :: s0 :: accu) n i i
+ and cont_t n printer i =
+ let s =
+ if str
+ then (Obj.magic printer : unit -> string) ()
+ else exstring (fun ppf () -> printer ppf) () in
+ get (s :: s0 :: accu) n i i
+ and cont_f n i =
+ format_invalid_arg "bad tag name specification" fmt i
+ and cont_m n sfmt i =
+ format_invalid_arg "bad tag name specification" fmt i in
+ Printf.scan_format fmt v n j cont_s cont_a cont_t cont_f cont_m
+ | c -> get accu n i (succ j) in
+ get [] n i i
+
+ and do_pp_break ppf n i =
+ if i >= len then begin pp_print_space ppf (); doprn n i end else
+ match fmt.[i] with
+ | '<' ->
+ let rec got_nspaces nspaces n i =
+ get_int n i (got_offset nspaces)
+ and got_offset nspaces offset n i =
+ pp_print_break ppf (int_of_size nspaces) (int_of_size offset);
+ doprn n (skip_gt i) in
+ get_int n (succ i) got_nspaces
+ | c -> pp_print_space ppf (); doprn n i
+
+ and do_pp_open_box ppf n i =
+ if i >= len then begin pp_open_box_gen ppf 0 Pp_box; doprn n i end else
+ match fmt.[i] with
+ | '<' ->
+ let kind, i = get_box_kind (succ i) in
+ let got_size size n i =
+ pp_open_box_gen ppf (int_of_size size) kind;
+ doprn n (skip_gt i) in
+ get_int n i got_size
+ | c -> pp_open_box_gen ppf 0 Pp_box; doprn n i
+
+ and do_pp_open_tag ppf n i =
+ if i >= len then begin pp_open_tag ppf ""; doprn n i end else
+ match fmt.[i] with
+ | '<' ->
+ let got_name tag_name n i =
+ pp_open_tag ppf tag_name;
+ doprn n (skip_gt i) in
+ get_tag_name n (succ i) got_name
+ | c -> pp_open_tag ppf ""; doprn n i in
+
+ doprn (Printf.sz_of_int 0) 0 in
+
+ Printf.kapr kpr fmt in
+
+ kprintf;;
(**************************************************************
@@ -1139,22 +1190,24 @@ let rec fprintf_out str out ppf fmt =
**************************************************************)
-let kfprintf k = fprintf_out false k;;
-let fprintf ppf = kfprintf unit_out ppf;;
-let printf f = fprintf std_formatter f;;
-let eprintf f = fprintf err_formatter f;;
+let kfprintf k ppf = mkprintf false (fun _ -> ppf) k;;
-let bprintf b =
- let ppf = formatter_of_buffer b in
- kfprintf (fun ppf -> pp_flush_queue ppf false) ppf;;
+let fprintf ppf = kfprintf ignore ppf;;
+let printf fmt = fprintf std_formatter fmt;;
+let eprintf fmt = fprintf err_formatter fmt;;
-let ksprintf k =
- let b = Buffer.create 512 in
- let ppf = formatter_of_buffer b in
- fprintf_out true (fun ppf -> k (string_out b ppf)) ppf;;
+let kbprintf k b =
+ mkprintf false (fun _ -> formatter_of_buffer b) k;;
-let sprintf f = ksprintf (fun s -> s) f;;
+let bprintf b = kbprintf ignore b;;
+
+let ksprintf k =
+ let b = Buffer.create 512 in
+ let k ppf = k (string_out b ppf) in
+ mkprintf true (fun _ -> formatter_of_buffer b) k;;
let kprintf = ksprintf;;
+let sprintf fmt = ksprintf (fun s -> s) fmt;;
+
at_exit print_flush;;