This repository has been archived by the owner on Mar 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathprinter.rkt
129 lines (105 loc) · 3.79 KB
/
printer.rkt
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#lang racket/base
; Write $message instances to ports
(require racket/contract
racket/fasl
racket/list
racket/pretty
racket/serialize
"format.rkt"
"message.rkt"
"setting.rkt"
"subprogram.rkt")
(provide (contract-out
[write-message-log
(-> (or/c $message? subprogram-log/c)
message-formatter/c
void?)]
[write-message
(->* ($message?) (#:newline? any/c message-formatter/c output-port?) void?)]))
(define+provide-message $verbose (message))
(define+provide-setting DENXI_FASL_OUTPUT boolean? #f)
(define+provide-setting DENXI_VERBOSE boolean? #f)
(define+provide-setting DENXI_READER_FRIENDLY_OUTPUT boolean? #f)
(define (filter-output m)
(if ($verbose? m)
(and (DENXI_VERBOSE)
($verbose-message m))
m))
; Program output can be a subprogram log so that users don't always have to
; construct an organized list of messages.
(define (write-message-log program-output format-message)
(define messages
(if (list? program-output)
(reverse (flatten program-output))
(in-value program-output)))
(for ([m messages])
(write-message m format-message)))
(define (write-message v
#:newline? [newline? #t]
[formatter (current-message-formatter)]
[out (current-output-port)])
(define maybe-message (filter-output v))
(when maybe-message
(parameterize ([current-output-port out])
(define to-send
(if (DENXI_READER_FRIENDLY_OUTPUT)
maybe-message
(formatter maybe-message)))
(if (DENXI_FASL_OUTPUT)
(s-exp->fasl (serialize to-send) (current-output-port))
(if (DENXI_READER_FRIENDLY_OUTPUT)
(pretty-write #:newline? newline? to-send)
((if newline? displayln display) to-send)))
(flush-output))))
(module+ test
(require racket/format
rackunit
"setting.rkt")
(define dummy ($show-string "Testing: Blah"))
(define (write-output v [out (current-output-port)])
(write-message v default-message-formatter out))
(define (capture-bytes p)
(define buffer (open-output-bytes))
(p buffer)
(get-output-bytes buffer #t))
(define (test-output msg v expected)
(define buffer (open-output-bytes))
; parameterize adds coverage for default value in write-output
(parameterize ([current-output-port buffer])
(write-output v))
(test-true msg
(if (or (regexp? expected)
(pregexp? expected))
(regexp-match? expected (get-output-bytes buffer #t))
(equal? (get-output-bytes buffer #t) expected))))
(test-output "By default, program output is human-friendly"
dummy
#px"Testing: Blah")
(DENXI_READER_FRIENDLY_OUTPUT #t
(λ ()
(test-output "Allow reader-friendly output"
dummy
(capture-bytes
(λ (o)
(pretty-write #:newline? #t dummy o))))
(DENXI_FASL_OUTPUT #t
(λ ()
(test-case "Allow FASL output"
(define in
(open-input-bytes
(capture-bytes
(λ (o) (write-output dummy o)))))
(check-equal? (deserialize (fasl->s-exp in))
dummy))))))
(test-case "Control verbose output"
(DENXI_VERBOSE #f
(λ ()
(test-output "Opt out of verbose output"
($verbose dummy)
#"")))
(DENXI_VERBOSE #t
(λ () (DENXI_READER_FRIENDLY_OUTPUT #t
(λ ()
(test-output "Opt into verbose output"
($verbose dummy)
#px"\\$show-string")))))))