summaryrefslogtreecommitdiffstats
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/pervasives.ml44
1 files changed, 27 insertions, 17 deletions
diff --git a/stdlib/pervasives.ml b/stdlib/pervasives.ml
index ce0a33744..a13c925f3 100644
--- a/stdlib/pervasives.ml
+++ b/stdlib/pervasives.ml
@@ -310,23 +310,33 @@ let really_input ic s ofs len =
external input_scan_line : in_channel -> int = "caml_input_scan_line"
-let rec input_line chan =
- let n = input_scan_line chan in
- if n = 0 then (* n = 0: we are at EOF *)
- raise End_of_file
- else if n > 0 then begin (* n > 0: newline found in buffer *)
- let res = string_create (n-1) in
- ignore (unsafe_input chan res 0 (n-1));
- ignore (input_char chan); (* skip the newline *)
- res
- end else begin (* n < 0: newline not found *)
- let beg = string_create (-n) in
- ignore(unsafe_input chan beg 0 (-n));
- try
- beg ^ input_line chan
- with End_of_file ->
- beg
- end
+let input_line chan =
+ let rec build_result buf pos = function
+ [] -> buf
+ | hd :: tl ->
+ let len = string_length hd in
+ string_blit hd 0 buf (pos - len) len;
+ build_result buf (pos - len) tl in
+ let rec scan accu len =
+ let n = input_scan_line chan in
+ if n = 0 then begin (* n = 0: we are at EOF *)
+ match accu with
+ [] -> raise End_of_file
+ | _ -> build_result (string_create len) len accu
+ end else if n > 0 then begin (* n > 0: newline found in buffer *)
+ let res = string_create (n-1) in
+ ignore (unsafe_input chan res 0 (n-1));
+ ignore (input_char chan); (* skip the newline *)
+ match accu with
+ [] -> res
+ | _ -> let len = len + n - 1 in
+ build_result (string_create len) len (res :: accu)
+ end else begin (* n < 0: newline not found *)
+ let beg = string_create (-n) in
+ ignore(unsafe_input chan beg 0 (-n));
+ scan (beg :: accu) (len - n)
+ end
+ in scan [] 0
external input_byte : in_channel -> int = "caml_input_char"
external input_binary_int : in_channel -> int = "caml_input_int"