1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
(* cpif-dev.sml
* 2005 Matthew Fluet (mfluet@acm.org)
* Adapted for MLton.
*)
(* cpif-dev.sml
* A simple pretty-printing device that eventually writes to a
* text file unless the current contents of that file coincides
* with what's being written.
*
* (C) 2002, Lucent Technologies, Bell Labs
*
* author: Matthias Blume (blume@research.bell-labs.com)
*)
structure CPIFDev : sig
include PP_DEVICE
val openOut : string * int -> device
val closeOut : device -> unit
end = struct
datatype device =
DEV of { filename: string,
buffer : string list ref,
wid : int }
(* no style support *)
type style = unit
fun sameStyle _ = true
fun pushStyle _ = ()
fun popStyle _ = ()
fun defaultStyle _ = ()
(* Allocate an empty buffer and remember the file name. *)
fun openOut (f, w) = DEV { filename = f, buffer = ref [], wid = w }
(* Calculate the final output and compare it with the current
* contents of the file. If they do not coincide, write the file. *)
fun closeOut (DEV { buffer = ref l, filename, ... }) = let
val s = concat (rev l)
fun write () = let
val f = TextIO.openOut filename
in
TextIO.output (f, s);
TextIO.closeOut f
end
in
let val f = TextIO.openIn filename
val s' = TextIO.inputAll f
in
TextIO.closeIn f;
if s = s' then () else write ()
end handle _ => write ()
end
(* maximum printing depth (in terms of boxes) *)
fun depth _ = NONE
(* the width of the device *)
fun lineWidth (DEV{wid, ...}) = SOME wid
(* the suggested maximum width of text on a line *)
fun textWidth _ = NONE
(* output a string/character in the current style to the device *)
fun string (DEV { buffer, ... }, s) = buffer := s :: !buffer
fun char (d, c) = string (d, String.str c)
fun space (d, n) = string (d, StringCvt.padLeft #" " n "")
fun newline d = string (d, "\n")
fun flush d = ()
end
|