summaryrefslogtreecommitdiffstats
path: root/stdlib/printf.ml
diff options
context:
space:
mode:
authorPierre Weis <Pierre.Weis@inria.fr>2008-07-01 09:55:52 +0000
committerPierre Weis <Pierre.Weis@inria.fr>2008-07-01 09:55:52 +0000
commit10b38811b6fdd4d37ad8fd93f17f58cb2884cd0e (patch)
tree8d3cd452522295bbf1f5f1b0d34648a4e43d9064 /stdlib/printf.ml
parent5abe61a5ade8c30c3c634748b2346ac88f3a8055 (diff)
Support for tk8.5: correcting tk_incs.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@8899 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'stdlib/printf.ml')
-rw-r--r--stdlib/printf.ml166
1 files changed, 109 insertions, 57 deletions
diff --git a/stdlib/printf.ml b/stdlib/printf.ml
index f3c122d82..b82970c32 100644
--- a/stdlib/printf.ml
+++ b/stdlib/printf.ml
@@ -28,11 +28,14 @@ module Sformat = struct
type index;;
- external unsafe_index_of_int : int -> index = "%identity";;
+ external unsafe_index_of_int : int -> index = "%identity"
+ ;;
let index_of_int i =
if i >= 0 then unsafe_index_of_int i
- else failwith ("index_of_int: negative argument " ^ string_of_int i);;
- external int_of_index : index -> int = "%identity";;
+ else failwith ("Sformat.index_of_int: negative argument " ^ string_of_int i)
+ ;;
+ external int_of_index : index -> int = "%identity"
+ ;;
let add_int_index i idx = index_of_int (i + int_of_index idx);;
let succ_index = add_int_index 1;;
@@ -40,31 +43,41 @@ module Sformat = struct
let index_of_litteral_position p = index_of_int (pred p);;
external length : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> int
- = "%string_length";;
+ = "%string_length"
+ ;;
external get : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> int -> char
- = "%string_safe_get";;
+ = "%string_safe_get"
+ ;;
external unsafe_get : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> int -> char
- = "%string_unsafe_get";;
+ = "%string_unsafe_get"
+ ;;
external unsafe_to_string : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> string
- = "%identity";;
+ = "%identity"
+ ;;
let sub fmt idx len =
- String.sub (unsafe_to_string fmt) (int_of_index idx) len;;
- let to_string fmt = sub fmt (unsafe_index_of_int 0) (length fmt);;
+ String.sub (unsafe_to_string fmt) (int_of_index idx) len
+ ;;
+ let to_string fmt = sub fmt (unsafe_index_of_int 0) (length fmt)
+ ;;
-end;;
+end
+;;
let bad_conversion sfmt i c =
invalid_arg
- ("printf: bad conversion %" ^ String.make 1 c ^ ", at char number " ^
- string_of_int i ^ " in format string ``" ^ sfmt ^ "''");;
+ ("Printf: bad conversion %" ^ String.make 1 c ^ ", at char number " ^
+ string_of_int i ^ " in format string ``" ^ sfmt ^ "''")
+;;
let bad_conversion_format fmt i c =
- bad_conversion (Sformat.to_string fmt) i c;;
+ bad_conversion (Sformat.to_string fmt) i c
+;;
let incomplete_format fmt =
invalid_arg
- ("printf: premature end of format string ``" ^
- Sformat.to_string fmt ^ "''");;
+ ("Printf: premature end of format string ``" ^
+ Sformat.to_string fmt ^ "''")
+;;
(* Parses a string conversion to return the specified length and the padding direction. *)
let parse_string_conversion sfmt =
@@ -79,7 +92,9 @@ let parse_string_conversion sfmt =
parse true (succ i)
| _ ->
parse neg (succ i) in
- try parse false 1 with Failure _ -> bad_conversion sfmt 0 's'
+ try parse false 1 with
+ | Failure _ -> bad_conversion sfmt 0 's'
+;;
(* Pad a (sub) string into a blank string of length [p],
on the right if [neg] is true, on the left otherwise. *)
@@ -93,14 +108,16 @@ let pad_string pad_char p neg s i len =
res
(* Format a string given a %s format, e.g. %40s or %-20s.
- To do: ignore other flags (#, +, etc)? *)
+ To do ?: ignore other flags (#, +, etc). *)
let format_string sfmt s =
let (p, neg) = parse_string_conversion sfmt in
- pad_string ' ' p neg s 0 (String.length s);;
+ pad_string ' ' p neg s 0 (String.length s)
+;;
(* Extract a format string out of [fmt] between [start] and [stop] inclusive.
'*' in the format are replaced by integers taken from the [widths] list.
- extract_format returns a string. *)
+ [extract_format] returns a string which is the string representation of
+ the resulting format string. *)
let extract_format fmt start stop widths =
let skip_positional_spec start =
match Sformat.unsafe_get fmt start with
@@ -127,7 +144,8 @@ let extract_format fmt start stop widths =
| (c, _) ->
Buffer.add_char b c; fill_format (succ i) widths in
fill_format start (List.rev widths);
- Buffer.contents b;;
+ Buffer.contents b
+;;
let extract_format_int conv fmt start stop widths =
let sfmt = extract_format fmt start stop widths in
@@ -135,7 +153,8 @@ let extract_format_int conv fmt start stop widths =
| 'n' | 'N' ->
sfmt.[String.length sfmt - 1] <- 'u';
sfmt
- | _ -> sfmt;;
+ | _ -> sfmt
+;;
(* Returns the position of the next character following the meta format
string, starting from position [i], inside a given format [fmt].
@@ -157,12 +176,14 @@ let sub_format incomplete_format bad_conversion_format conv fmt i =
if j >= len then incomplete_format fmt else
match Sformat.get fmt j with
| '(' | '{' as c ->
- let j = sub_fmt c (succ j) in sub (succ j)
+ let j = sub_fmt c (succ j) in
+ sub (succ j)
| '}' | ')' as c ->
if c = close then succ j else bad_conversion_format fmt i c
| _ -> sub (succ j) in
sub i in
- sub_fmt conv i;;
+ sub_fmt conv i
+;;
let sub_format_for_printf conv =
sub_format incomplete_format bad_conversion_format conv;;
@@ -225,7 +246,8 @@ let iter_on_format_args fmt add_conv add_char =
else scan_fmt (succ i)
else i in
- ignore (scan_fmt 0);;
+ ignore (scan_fmt 0)
+;;
(* Returns a string that summarizes the typing information that a given
format string contains.
@@ -239,7 +261,8 @@ let summarize_format_type fmt =
if skip then Buffer.add_string b "%_" else Buffer.add_char b '%';
add_char i c in
iter_on_format_args fmt add_conv add_char;
- Buffer.contents b;;
+ Buffer.contents b
+;;
module Ac = struct
type ac = {
@@ -247,11 +270,12 @@ module Ac = struct
mutable ac_skip : int;
mutable ac_rdrs : int;
}
-end;;
+end
+;;
open Ac;;
-(* Computes the number of arguments of a format (including flag
+(* Computes the number of arguments of a format (including the flag
arguments if any). *)
let ac_of_format fmt =
let ac = { ac_rglr = 0; ac_skip = 0; ac_rdrs = 0; } in
@@ -268,18 +292,21 @@ let ac_of_format fmt =
and add_char i c = succ i in
iter_on_format_args fmt add_conv add_char;
- ac;;
+ ac
+;;
let count_arguments_of_format fmt =
let ac = ac_of_format fmt in
- ac.ac_rglr + ac.ac_skip + ac.ac_rdrs;;
+ ac.ac_rglr + ac.ac_skip + ac.ac_rdrs
+;;
let list_iter_i f l =
let rec loop i = function
| [] -> ()
| [x] -> f i x (* Tail calling [f] *)
| x :: xs -> f i x; loop (succ i) xs in
- loop 0 l;;
+ loop 0 l
+;;
(* ``Abstracting'' version of kprintf: returns a (curried) function that
will print when totally applied.
@@ -322,13 +349,19 @@ let kapr kpr fmt =
list_iter_i (fun i arg -> a.(nargs - i - 1) <- arg) args;
kpr fmt a
else Obj.magic (fun x -> loop (succ i) (x :: args)) in
- loop 0 [];;
+ loop 0 []
+;;
type positional_specification =
- | Spec_none | Spec_index of Sformat.index;;
+ | Spec_none | Spec_index of Sformat.index
+;;
(* To scan an optional positional parameter specification,
i.e. an integer followed by a [$].
+
+ Calling [got_spec] with appropriate arguments, we ``return'' a positional
+ specification and an index to go on scanning the [fmt] format at hand.
+
We do not support [*$] specifications, since this would lead to type checking
problems: the type of the specified [*$] parameter would be the type of the
corresponding argument to [printf], hence the type of the $n$-th argument to
@@ -346,35 +379,44 @@ let scan_positional_spec fmt got_spec n i =
if accu = 0 then
failwith "printf: bad positional specification (0)." else
got_spec (Spec_index (Sformat.index_of_litteral_position accu)) (succ j)
- (* Not a positional specification. *)
+ (* Not a positional specification: tell so the caller, and go back to
+ scanning the format from the original [i] position we were called at
+ first. *)
| _ -> got_spec Spec_none i in
get_int_litteral (int_of_char d - 48) (succ i)
- (* No positional specification. *)
- | _ -> got_spec Spec_none i;;
+ (* No positional specification: tell so the caller, and go back to scanning
+ the format from the original [i] position. *)
+ | _ -> got_spec Spec_none i
+;;
-(* Get the position of the next argument to printf, according to the given
+(* Get the index of the next argument to printf, according to the given
positional specification. *)
let next_index spec n =
match spec with
| Spec_none -> Sformat.succ_index n
- | Spec_index _ -> n;;
+ | Spec_index _ -> n
+;;
-(* Get the position of the actual argument to printf, according to its
+(* Get the index of the actual argument to printf, according to its
optional positional specification. *)
let get_index spec n =
match spec with
| Spec_none -> n
- | Spec_index p -> p;;
+ | Spec_index p -> p
+;;
(* Decode a format string and act on it.
- [fmt] is the printf format string, and [pos] points to a [%] character.
+ [fmt] is the printf format string, and [pos] points to a [%] character in
+ the format string.
After consuming the appropriate number of arguments and formatting
- them, one of the five continuations is called:
- [cont_s] for outputting a string (args: arg num, string, next pos)
- [cont_a] for performing a %a action (args: arg num, fn, arg, next pos)
- [cont_t] for performing a %t action (args: arg num, fn, next pos)
- [cont_f] for performing a flush action (args: arg num, next pos)
- [cont_m] for performing a %( action (args: arg num, sfmt, next pos)
+ them, one of the five continuations is called.
+ If we denote [idx] the index of the following argument to printf,
+ [pos] the index of the next character to scan in the format strin.
+ [cont_s] for outputting a string (arguments: the , string, next pos)
+ [cont_a] for performing a %a action (arguments: arg num, fn, arg, next pos)
+ [cont_t] for performing a %t action (arguments: arg num, fn, next pos)
+ [cont_f] for performing a flush action (arguments: arg num, next pos)
+ [cont_m] for performing a %( action (arguments: arg num, sfmt, next pos)
"arg num" is the index in array args of the next argument to printf.
"next pos" is the position in [fmt] of the first character following
@@ -488,11 +530,12 @@ let scan_format fmt args n pos cont_s cont_a cont_t cont_f cont_m =
| conv ->
bad_conversion_format fmt i conv in
- scan_positional n [] (succ pos);;
+ scan_positional n [] (succ pos)
+;;
let mkprintf to_s get_out outc outs flush k fmt =
- (* out is global to this invocation of pr, and must be shared by all its
+ (* [out] is global to this definition of [pr], and must be shared by all its
recursive calls (if any). *)
let out = get_out fmt in
@@ -529,10 +572,12 @@ let mkprintf to_s get_out outc outs flush k fmt =
let kpr = pr k (Sformat.index_of_int 0) in
- kapr kpr fmt;;
+ kapr kpr fmt
+;;
let kfprintf k oc =
- mkprintf false (fun _ -> oc) output_char output_string flush k;;
+ mkprintf false (fun _ -> oc) output_char output_string flush k
+;;
let ifprintf oc = kapr (fun _ -> Obj.magic ignore);;
let fprintf oc = kfprintf ignore oc;;
@@ -540,22 +585,26 @@ let printf fmt = fprintf stdout fmt;;
let eprintf fmt = fprintf stderr fmt;;
let kbprintf k b =
- mkprintf false (fun _ -> b) Buffer.add_char Buffer.add_string ignore k;;
+ mkprintf false (fun _ -> b) Buffer.add_char Buffer.add_string ignore k
+;;
let bprintf b = kbprintf ignore b;;
let get_buff fmt =
let len = 2 * Sformat.length fmt in
- Buffer.create len;;
+ Buffer.create len
+;;
let get_contents b =
let s = Buffer.contents b in
Buffer.clear b;
- s;;
+ s
+;;
let get_cont k b = k (get_contents b);;
let ksprintf k =
- mkprintf true get_buff Buffer.add_char Buffer.add_string ignore (get_cont k);;
+ mkprintf true get_buff Buffer.add_char Buffer.add_string ignore (get_cont k)
+;;
let kprintf = ksprintf;;
@@ -572,7 +621,8 @@ module CamlinternalPr = struct
mutable ac_rglr : int;
mutable ac_skip : int;
mutable ac_rdrs : int;
- };;
+ }
+;;
let ac_of_format = ac_of_format;;
@@ -584,6 +634,8 @@ module CamlinternalPr = struct
let kapr = kapr;;
- end;;
+ end
+;;
-end;;
+end
+;;