summaryrefslogtreecommitdiff
path: root/stdlib/printf.ml
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/printf.ml')
-rw-r--r--stdlib/printf.ml45
1 files changed, 41 insertions, 4 deletions
diff --git a/stdlib/printf.ml b/stdlib/printf.ml
index 92ce254769..a061af7359 100644
--- a/stdlib/printf.ml
+++ b/stdlib/printf.ml
@@ -142,7 +142,8 @@ let extract_format fmt start stop widths =
| ('*', []) ->
assert false (* should not happen *)
| (c, _) ->
- Buffer.add_char b c; fill_format (succ i) widths in
+ Buffer.add_char b c;
+ fill_format (succ i) widths in
fill_format start (List.rev widths);
Buffer.contents b
;;
@@ -156,6 +157,15 @@ let extract_format_int conv fmt start stop widths =
| _ -> sfmt
;;
+let extract_format_float conv fmt start stop widths =
+ let sfmt = extract_format fmt start stop widths in
+ match conv with
+ | 'F' ->
+ sfmt.[String.length sfmt - 1] <- 'f';
+ sfmt
+ | _ -> sfmt
+;;
+
(* Returns the position of the next character following the meta format
string, starting from position [i], inside a given format [fmt].
According to the character [conv], the meta format string is
@@ -297,7 +307,7 @@ let ac_of_format fmt =
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
;;
let list_iter_i f l =
@@ -417,6 +427,31 @@ let get_index spec n =
| Spec_index p -> p
;;
+(* Format a float argument as a valid Caml lexem. *)
+let format_float_lexem =
+ let valid_float_lexem sfmt s =
+ let l = String.length s in
+ if l = 0 then "nan" else
+ let add_dot sfmt s =
+ if s.[0] = ' ' || s.[0] = '+' || s.[0] = '0'
+ then String.sub s 1 (l - 1) ^ "."
+ else String.sub s 0 (l - 1) ^ "." in
+
+ let rec loop i =
+ if i >= l then add_dot sfmt s else
+ match s.[i] with
+ | '.' -> s
+ | _ -> loop (i + 1) in
+
+ loop 0 in
+
+ (fun sfmt x ->
+ let s = format_float sfmt x in
+ match classify_float x with
+ | FP_normal | FP_subnormal | FP_zero -> valid_float_lexem sfmt s
+ | FP_nan | FP_infinite -> s)
+;;
+
(* Decode a format string and act on it.
[fmt] is the [printf] format string, and [pos] points to a [%] character in
the format string.
@@ -485,9 +520,11 @@ let scan_format fmt args n pos cont_s cont_a cont_t cont_f cont_m =
let (x : float) = get_arg spec n in
let s = format_float (extract_format fmt pos i widths) x in
cont_s (next_index spec n) s (succ i)
- | 'F' ->
+ | 'F' as conv ->
let (x : float) = get_arg spec n in
- cont_s (next_index spec n) (string_of_float x) (succ i)
+ let s =
+ format_float_lexem (extract_format_float conv fmt pos i widths) x in
+ cont_s (next_index spec n) s (succ i)
| 'B' | 'b' ->
let (x : bool) = get_arg spec n in
cont_s (next_index spec n) (string_of_bool x) (succ i)