-
Notifications
You must be signed in to change notification settings - Fork 180
/
Copy pathIODebug.jl
111 lines (86 loc) · 3.06 KB
/
IODebug.jl
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
const live_mode = true
import ..debug_header
@static if live_mode
struct IODebug{T <: IO} <: IO
io::T
end
logwrite(iod::IODebug, f, x) = show_io_debug(stdout, "➡️ ", f, x)
logread(iod::IODebug, f, x) = show_io_debug(stdout, "⬅️ ", f, x)
else
struct IODebug{T <: IO} <: IO
io::T
log::Vector{Tuple{String,String}}
end
IODebug(io::T) where T <: IO = IODebug{T}(io, [])
logwrite(iod::IODebug, f, x) = push!(iod.log, ("➡️ ", f, x))
logread(iod::IODebug, f, x) = push!(iod.log, ("⬅️ ", f, x))
end
Base.wait_close(iod::IODebug) = Base.wait_close(iod.io)
Base.write(iod::IODebug, a...) =
(logwrite(iod, :write, join(a));
write(iod.io, a...))
Base.write(iod::IODebug, a::Array) =
(logwrite(iod, :write, join(a));
write(iod.io, a))
Base.write(iod::IODebug, x::String) =
(logwrite(iod, :write, x);
write(iod.io, x))
Base.unsafe_write(iod::IODebug, x::Ptr{UInt8}, n::UInt) =
(logwrite(iod, :unsafe_write, unsafe_string(x,n));
unsafe_write(iod.io, x, n))
Base.unsafe_read(iod::IODebug, x::Ptr{UInt8}, n::UInt) =
(r = unsafe_read(iod.io, x, n);
logread(iod, :unsafe_read, unsafe_string(x,n)); r)
Base.read(iod::IODebug, n::Integer) =
(r = read(iod.io, n);
logread(iod, :read, String(copy(r))); r)
Base.readavailable(iod::IODebug) =
(r = readavailable(iod.io);
logread(iod, :readavailable, String(copy(r))); r)
Base.readuntil(iod::IODebug, f) =
(r = readuntil(iod.io, f);
logread(iod, :readuntil, String(copy(r))); r)
Base.readuntil(iod::IODebug, f, h) =
(r = readuntil(iod.io, f, h);
logread(iod, :readuntil, String(copy(r))); r)
Base.eof(iod::IODebug) = eof(iod.io)
Base.close(iod::IODebug) = close(iod.io)
Base.isopen(iod::IODebug) = isopen(iod.io)
Base.iswritable(iod::IODebug) = iswritable(iod.io)
Base.isreadable(iod::IODebug) = isreadable(iod.io)
IOExtras.startread(iod::IODebug) = startread(iod.io)
IOExtras.startwrite(iod::IODebug) = startwrite(iod.io)
IOExtras.closeread(iod::IODebug) = closeread(iod.io)
IOExtras.closewrite(iod::IODebug) = closewrite(iod.io)
Base.bytesavailable(iod::IODebug) = bytesavailable(iod.io)
Base.show(io::IO, iod::IODebug) = show(io, iod.io)
function show_log(io::IO, iod::IODebug)
lock(io)
println(io, "$(typeof(iod)):\nio: $(iod.io)")
prevop = ""
for (operation, f, bytes) in iod.log
if prevop != "" && prevop != operation
println(io)
end
show_io_debug(io, operation, f, bytes)
prevop = operation
end
println(io)
unlock(io)
end
function show_io_debug(io::IO, operation, f, bytes)
prefix = string(debug_header(), rpad(operation, 4))
i = j = 1
while i <= length(bytes)
j = findnext(isequal('\n'), bytes, i)
if j === nothing || j == 0
j = prevind(bytes, length(bytes)+1)
end
println(io, prefix, "\"", escape_string(bytes[i:j]), "\"",
i == 1 ? " ($f)" : "")
if i == 1
prefix = rpad("DEBUG:", length(prefix) - 1)
end
i = nextind(bytes, j)
end
end