Improved readTask and capture protocol

This commit is contained in:
Giorgio Calderone 2020-04-22 17:56:50 +02:00
parent deee2693df
commit 8f737205a1

View File

@ -220,7 +220,7 @@ Base.@kwdef mutable struct Options
MIME"image/jpeg" => "jpeg enhanced", MIME"image/jpeg" => "jpeg enhanced",
MIME"application/pdf" => "pdfcairo enhanced", MIME"application/pdf" => "pdfcairo enhanced",
MIME"text/html" => "svg enhanced dynamic", # canvas mousing MIME"text/html" => "svg enhanced dynamic", # canvas mousing
MIME"text/plain" => "dumb") MIME"text/plain" => "dumb enhanced ansi")
init::Vector{String} = Vector{String}() init::Vector{String} = Vector{String}()
verbose::Bool = false verbose::Bool = false
preferred_format::Symbol = :auto preferred_format::Symbol = :auto
@ -442,47 +442,71 @@ end
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
function readTask(gp::GPSession)
pagerTokens() = ["Press return for more:"] pagerTokens() = ["Press return for more:"]
function GPSession(sid::Symbol) repeatID = 0
function readTask(sid, stream, channel) function gpreadline()
function gpreadline(stream)
line = "" line = ""
while true while true
c = read(stream, Char) c = read(gp.perr, Char)
(c == '\r') && continue (c == '\r') && continue
(c == '\n') && break (c == '\n') && break
line *= c line *= c
for token in pagerTokens() # handle pager interaction for token in pagerTokens() # handle pager interaction
if (length(line) == length(token)) && (line == token) if (length(line) == length(token)) && (line == token)
return line # GNUPLOT_CAPTURE_END maybe lost when pager is
# running: send it again.
repeatID += 1
write(gp.pin, "\nprint 'GNUPLOT_CAPTURE_END $repeatID'\n")
line = ""
end end
end end
end end
if line == "GNUPLOT_CAPTURE_BEGIN"
repeatID += 1
write(gp.pin, "\nprint 'GNUPLOT_CAPTURE_END $repeatID'\n")
end
return line return line
end end
try
saveOutput = false saveOutput = false
while isopen(stream) while isopen(gp.perr)
line = gpreadline(stream) line = gpreadline()
if line == "GNUPLOT_CAPTURE_BEGIN" if line == "GNUPLOT_CAPTURE_BEGIN"
saveOutput = true saveOutput = true
elseif line == "GNUPLOT_CAPTURE_END" elseif line == "GNUPLOT_CAPTURE_END $repeatID"
put!(channel, line)
saveOutput = false saveOutput = false
put!(gp.channel, "GNUPLOT_CAPTURE_END")
elseif !isnothing(findfirst("GNUPLOT_CAPTURE_END", line))
continue # old GNUPLOT_CAPTURE_END, ignore it
else else
if line != "" if line != ""
if options.verbose || !saveOutput if options.verbose || !saveOutput
printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n") printstyled(color=:cyan, "GNUPLOT ($(gp.sid)) -> $line\n")
end end
end end
(saveOutput) && (put!(channel, line)) (saveOutput) && (put!(gp.channel, line))
end end
end end
delete!(sessions, sid) catch err
return nothing if isopen(gp.perr)
@error "Error occurred in readTask for session $(gp.sid)"
@show(err)
else
put!(gp.channel, "GNUPLOT_CAPTURE_END")
end
end
if options.verbose
printstyled(color=:red, "GNUPLOT ($(gp.sid)) Process terminated\n")
end
delete!(sessions, gp.sid)
end end
function GPSession(sid::Symbol)
session = DrySession(sid) session = DrySession(sid)
if !options.dry if !options.dry
try try
@ -505,13 +529,13 @@ function GPSession(sid::Symbol)
Base.close(pin.out) Base.close(pin.out)
Base.start_reading(perr.out) Base.start_reading(perr.out)
# Start reading tasks
@async readTask(sid, perr, chan)
out = GPSession(getfield.(Ref(session), fieldnames(DrySession))..., out = GPSession(getfield.(Ref(session), fieldnames(DrySession))...,
pin, perr, proc, chan) pin, perr, proc, chan)
sessions[sid] = out sessions[sid] = out
# Start reading tasks
@async readTask(out)
return out return out
end end
@ -596,34 +620,12 @@ function writeread(gp::GPSession, str::AbstractString)
options.verbose = verbose options.verbose = verbose
write(gp, str) write(gp, str)
options.verbose = false
write(gp, "print 'GNUPLOT_CAPTURE_END'")
options.verbose = verbose
out = Vector{String}() out = Vector{String}()
while true while true
l = take!(gp.channel) l = take!(gp.channel)
if l in pagerTokens()
# Consume all data from the pager
while true
write(gp, "")
sleep(0.5)
if isready(gp.channel)
while isready(gp.channel)
push!(out, take!(gp.channel))
end
else
options.verbose = false
write(gp, "print 'GNUPLOT_CAPTURE_END'")
options.verbose = verbose
break
end
end
else
l == "GNUPLOT_CAPTURE_END" && break l == "GNUPLOT_CAPTURE_END" && break
push!(out, l) push!(out, l)
end end
end
return out return out
end end