File: cpif-dev.sml

package info (click to toggle)
mlton 20100608-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 34,980 kB
  • ctags: 69,089
  • sloc: ansic: 18,421; lisp: 2,879; makefile: 1,570; sh: 1,325; pascal: 256; asm: 97
file content (74 lines) | stat: -rw-r--r-- 2,092 bytes parent folder | download | duplicates (6)
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