diff -Naur old/stdlib/.depend new/stdlib/.depend --- old/stdlib/.depend 2014-06-22 18:34:31.298480318 +0200 +++ new/stdlib/.depend 2014-06-22 18:34:17.522479966 +0200 @@ -147,10 +147,10 @@ digest.cmx char.cmx array.cmx random.cmi scanf.cmo : string.cmi printf.cmi pervasives.cmi list.cmi \ camlinternalFormatBasics.cmi camlinternalFormat.cmi bytes.cmi buffer.cmi \ - scanf.cmi + weak.cmi scanf.cmi scanf.cmx : string.cmx printf.cmx pervasives.cmx list.cmx \ camlinternalFormatBasics.cmx camlinternalFormat.cmx bytes.cmx buffer.cmx \ - scanf.cmi + weak.cmx scanf.cmi set.cmo : list.cmi set.cmi set.cmx : list.cmx set.cmi sort.cmo : array.cmi sort.cmi diff -Naur old/stdlib/Makefile.shared new/stdlib/Makefile.shared --- old/stdlib/Makefile.shared 2014-06-22 18:33:54.426479374 +0200 +++ new/stdlib/Makefile.shared 2014-06-22 18:33:42.866479078 +0200 @@ -30,9 +30,9 @@ camlinternalLazy.cmo lazy.cmo stream.cmo \ buffer.cmo camlinternalFormat.cmo printf.cmo \ arg.cmo printexc.cmo gc.cmo \ - digest.cmo random.cmo hashtbl.cmo format.cmo scanf.cmo callback.cmo \ + digest.cmo random.cmo hashtbl.cmo format.cmo weak.cmo scanf.cmo callback.cmo \ camlinternalOO.cmo oo.cmo camlinternalMod.cmo \ - genlex.cmo weak.cmo \ + genlex.cmo \ filename.cmo complex.cmo \ arrayLabels.cmo listLabels.cmo bytesLabels.cmo \ stringLabels.cmo moreLabels.cmo stdLabels.cmo diff -Naur old/stdlib/scanf.ml new/stdlib/scanf.ml --- old/stdlib/scanf.ml 2014-06-22 18:31:52.162476244 +0200 +++ new/stdlib/scanf.ml 2014-06-22 18:31:35.010475805 +0200 @@ -390,12 +390,31 @@ let from_file_bin = open_in_bin;; let memo_from_ic = - let memo = ref [] in + let module IcMemo = Weak.Make (struct + type t = Pervasives.in_channel + let equal ic1 ic2 = ic1 = ic2 + let hash ic = Hashtbl.hash ic + end) in + let module PairMemo = Weak.Make (struct + type t = Pervasives.in_channel * in_channel + let equal (ic1, _) (ic2, _) = ic1 = ic2 + let hash (ic, _) = Hashtbl.hash ic + end) in + let ic_memo = IcMemo.create 16 in + let pair_memo = PairMemo.create 16 in + let rec finaliser ((ic, _) as pair) = + if IcMemo.mem ic_memo ic then ( + Gc.finalise finaliser pair; + PairMemo.add pair_memo pair; + ) in (fun scan_close_ic ic -> - try List.assq ic !memo with + try snd (PairMemo.find pair_memo (ic, stdin)) with | Not_found -> let ib = from_ic scan_close_ic (From_channel ic) ic in - memo := (ic, ib) :: !memo; + let pair = (ic, ib) in + IcMemo.add ic_memo ic; + Gc.finalise finaliser pair; + PairMemo.add pair_memo pair; ib) ;;