Code re-factoring
This commit is contained in:
parent
1665b78a54
commit
56b64fcef7
953
src/Gnuplot.jl
953
src/Gnuplot.jl
File diff suppressed because it is too large
Load Diff
@ -1,247 +0,0 @@
|
||||
isdefined(Base, :__precompile__) && __precompile__()
|
||||
|
||||
######################################################################
|
||||
# MODULE GnuplotInternals (private functions and definitions)
|
||||
######################################################################
|
||||
module p_
|
||||
|
||||
importall Gnuplot
|
||||
const P_ = Gnuplot
|
||||
|
||||
|
||||
######################################################################
|
||||
# Structure definitions
|
||||
######################################################################
|
||||
|
||||
"""
|
||||
Structure containing the `Pipe` and `Process` objects associated to a
|
||||
Gnuplot process.
|
||||
"""
|
||||
mutable struct GnuplotProc
|
||||
pin::Base.Pipe
|
||||
pout::Base.Pipe
|
||||
perr::Base.Pipe
|
||||
proc::Base.Process
|
||||
channel::Channel{String}
|
||||
|
||||
"""
|
||||
Start a new gnuplot process using the command given in the `cmd` argument.
|
||||
"""
|
||||
function GnuplotProc(cmd::String)
|
||||
this = new()
|
||||
this.pin = Base.Pipe()
|
||||
this.pout = Base.Pipe()
|
||||
this.perr = Base.Pipe()
|
||||
this.channel = Channel{String}(32)
|
||||
|
||||
# Start gnuplot process
|
||||
this.proc = spawn(`$cmd`, (this.pin, this.pout, this.perr))
|
||||
|
||||
# Close unused sides of the pipes
|
||||
Base.close_pipe_sync(this.pout.in)
|
||||
Base.close_pipe_sync(this.perr.in)
|
||||
Base.close_pipe_sync(this.pin.out)
|
||||
Base.start_reading(this.pout.out)
|
||||
Base.start_reading(this.perr.out)
|
||||
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
"""
|
||||
Structure containing a single plot command and the associated
|
||||
multiplot index.
|
||||
"""
|
||||
mutable struct MultiCmd
|
||||
cmd::String # command
|
||||
id::Int # multiplot index
|
||||
end
|
||||
|
||||
"""
|
||||
Structure containing the state of a single gnuplot session.
|
||||
"""
|
||||
mutable struct GnuplotSession
|
||||
blockCnt::Int # data blocks counter
|
||||
cmds::Vector{MultiCmd} # gnuplot commands
|
||||
data::Vector{String} # data blocks
|
||||
plot::Vector{MultiCmd} # plot specifications associated to each data block
|
||||
splot::Bool # plot / splot session
|
||||
lastDataName::String # name of the last data block
|
||||
multiID::Int # current multiplot index (0 if no multiplot)
|
||||
|
||||
GnuplotSession() = new(1, Vector{MultiCmd}(), Vector{String}(),
|
||||
Vector{MultiCmd}(), false, "", 0)
|
||||
end
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
"""
|
||||
Structure containing the global package state.
|
||||
"""
|
||||
mutable struct MainState
|
||||
colorOut::Symbol # gnuplot STDOUT is printed with this color
|
||||
colorIn::Symbol # gnuplot STDIN is printed with this color
|
||||
verboseLev::Int # verbosity level (0 - 3), default: 3
|
||||
gnuplotCmd::String # command used to start the gnuplot process
|
||||
startup::String # commands automatically sent to each new gnuplot process
|
||||
procs::Vector{GnuplotProc} # array of currently active gnuplot process and pipes
|
||||
states::Vector{GnuplotSession} # array of gnuplot sessions
|
||||
handles::Vector{Int} # handles of gnuplot sessions
|
||||
curPos::Int # index in the procs, states and handles array of current session
|
||||
|
||||
MainState() = new(:cyan, :yellow, 0,
|
||||
"", "", Vector{GnuplotProc}(), Vector{GnuplotSession}(),
|
||||
Vector{Int}(), 0)
|
||||
end
|
||||
|
||||
|
||||
######################################################################
|
||||
# Functions
|
||||
######################################################################
|
||||
|
||||
"""
|
||||
Check gnuplot is runnable with the command given in `main.gnuplotCmd`.
|
||||
Also check that gnuplot version is >= 4.7 (required to use data
|
||||
blocks).
|
||||
"""
|
||||
function checkGnuplotVersion()
|
||||
cmd = `$(main.gnuplotCmd) --version`
|
||||
out, procs = open(`$cmd`, "r")
|
||||
s = String(read(out))
|
||||
if !success(procs)
|
||||
error("An error occurred while running: " * string(cmd))
|
||||
end
|
||||
|
||||
s = split(s, " ")
|
||||
ver = ""
|
||||
for token in s
|
||||
try
|
||||
ver = VersionNumber("$token")
|
||||
break
|
||||
catch
|
||||
end
|
||||
end
|
||||
|
||||
if ver < v"4.7"
|
||||
# Do not raise error in order to pass Travis CI test, since it has v4.6
|
||||
println("gnuplot ver. >= 4.7 is required, but " * string(ver) * " was found.")
|
||||
end
|
||||
if ver < v"4.6"
|
||||
error("gnuplot ver. >= 4.7 is required, but " * string(ver) * " was found.")
|
||||
end
|
||||
log(1, "Found gnuplot version: " * string(ver))
|
||||
return ver
|
||||
end
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
"""
|
||||
Logging facility (each line is prefixed with the session handle.)
|
||||
|
||||
Printing occur only if the logging level is >= current verbosity
|
||||
level.
|
||||
"""
|
||||
function log(level::Int, s::String; id=nothing, color=nothing)
|
||||
if (main.verboseLev < level)
|
||||
return
|
||||
end
|
||||
|
||||
color == nothing && (color = main.colorOut)
|
||||
|
||||
prefix = ""
|
||||
if (id == nothing) && (main.curPos > 0)
|
||||
id = main.handles[main.curPos]
|
||||
end
|
||||
prefix = string("GP(", id, ")")
|
||||
|
||||
a = split(s, "\n")
|
||||
for v in a
|
||||
print_with_color(color, "$prefix $v\n")
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
"""
|
||||
Read gnuplot outputs, and optionally redirect to a `Channel`.
|
||||
|
||||
This fuction is supposed to be run in a `Task`.
|
||||
"""
|
||||
function readTask(sIN, channel; kw...)
|
||||
saveOutput::Bool = false
|
||||
while isopen(sIN)
|
||||
line = convert(String, readline(sIN))
|
||||
|
||||
if line == "GNUPLOT_JL_SAVE_OUTPUT"
|
||||
saveOutput = true
|
||||
log(4, "|begin of captured data =========================")
|
||||
else
|
||||
if saveOutput
|
||||
put!(channel, line)
|
||||
end
|
||||
|
||||
if line == "GNUPLOT_JL_SAVE_OUTPUT_END"
|
||||
saveOutput = false
|
||||
log(4, "|end of captured data ===========================")
|
||||
elseif line != ""
|
||||
if saveOutput
|
||||
log(3, "| " * line; kw...)
|
||||
else
|
||||
log(2, " " * line; kw...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
log(1, "pipe closed"; kw...)
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
"""
|
||||
Return a unique data block name
|
||||
"""
|
||||
function mkBlockName(;prefix::Union{Void,String}=nothing)
|
||||
if prefix == nothing
|
||||
prefix = string("d", main.handles[main.curPos])
|
||||
end
|
||||
|
||||
cur = main.states[main.curPos]
|
||||
name = string(prefix, "_", cur.blockCnt)
|
||||
cur.blockCnt += 1
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
"""
|
||||
Return the GnuplotProc structure of current session, or start a new
|
||||
gnuplot process if none is running.
|
||||
"""
|
||||
function getProcOrStartIt()
|
||||
if main.curPos == 0
|
||||
log(1, "Starting a new gnuplot process...")
|
||||
id = P_.session()
|
||||
end
|
||||
|
||||
p = main.procs[main.curPos]
|
||||
|
||||
if !Base.process_running(p.proc)
|
||||
error("The current gnuplot process is no longer running.")
|
||||
end
|
||||
|
||||
return p
|
||||
end
|
||||
|
||||
|
||||
######################################################################
|
||||
# Module initialization
|
||||
######################################################################
|
||||
const main = MainState()
|
||||
|
||||
end #module
|
||||
@ -1,6 +1,5 @@
|
||||
using Base.Test
|
||||
using Gnuplot
|
||||
const gp = Gnuplot
|
||||
|
||||
function pressEnter()
|
||||
println("Press enter...")
|
||||
@ -8,72 +7,72 @@ function pressEnter()
|
||||
end
|
||||
|
||||
function gp_test(terminal="unknown")
|
||||
gp.setOption(startup="set term $terminal")
|
||||
gpOptions.startup = "set term $terminal"
|
||||
|
||||
gp.reset()
|
||||
gpReset()
|
||||
x = collect(1.:100)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
gp.send("plot sin(x)")
|
||||
gpSend("plot sin(x)")
|
||||
terminal == "unknown" || pressEnter()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
id1 = gp.current()
|
||||
id2 = gp.session()
|
||||
id3 = gp.session()
|
||||
id1 = gpCurrentID()
|
||||
id2 = gpNewSession()
|
||||
id3 = gpNewSession()
|
||||
|
||||
for i in 1:10
|
||||
gp.setCurrent(id1)
|
||||
gp.send("plot sin($i*x)")
|
||||
gpSetCurrentID(id1)
|
||||
gpSend("plot sin($i*x)")
|
||||
|
||||
gp.setCurrent(id2)
|
||||
gp.send("plot sin($i*x)")
|
||||
gpSetCurrentID(id2)
|
||||
gpSend("plot sin($i*x)")
|
||||
|
||||
gp.setCurrent(id3)
|
||||
gp.send("plot sin($i*x)")
|
||||
gpSetCurrentID(id3)
|
||||
gpSend("plot sin($i*x)")
|
||||
|
||||
sleep(0.3)
|
||||
end
|
||||
terminal == "unknown" || pressEnter()
|
||||
gp.exitAll()
|
||||
gpExitAll()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
gp.reset()
|
||||
name = gp.data([1,2,3,5,8,13])
|
||||
gp.plot("$name w points ps 3")
|
||||
gp.dump()
|
||||
gpReset()
|
||||
name = gpData([1,2,3,5,8,13])
|
||||
gpPlot("$name w points ps 3")
|
||||
gpDump()
|
||||
terminal == "unknown" || pressEnter()
|
||||
|
||||
gp.plot(last=true, "w l lw 3")
|
||||
gp.dump()
|
||||
gpPlot(last=true, "w l lw 3")
|
||||
gpDump()
|
||||
terminal == "unknown" || pressEnter()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
gp.reset()
|
||||
gpReset()
|
||||
|
||||
gp.cmd("set format y \"%.1f\"")
|
||||
gp.cmd("set key box opaque")
|
||||
gp.cmd("set xrange [-2*pi:2*pi]")
|
||||
gp.multi("layout 2,2 columnsfirst title \"Multiplot title\"")
|
||||
gpCmd("set format y \"%.1f\"")
|
||||
gpCmd("set key box opaque")
|
||||
gpCmd("set xrange [-2*pi:2*pi]")
|
||||
gpMulti("layout 2,2 columnsfirst title \"Multiplot title\"")
|
||||
|
||||
gp.cmd(ylab="Y label")
|
||||
gp.plot("sin(x) lt 1")
|
||||
gpCmd(ylab="Y label")
|
||||
gpPlot("sin(x) lt 1")
|
||||
|
||||
gp.next()
|
||||
gp.cmd(xlab="X label")
|
||||
gp.plot("cos(x) lt 2")
|
||||
gpNext()
|
||||
gpCmd(xlab="X label")
|
||||
gpPlot("cos(x) lt 2")
|
||||
|
||||
gp.next()
|
||||
gp.cmd("unset ylabel")
|
||||
gp.cmd("unset ytics")
|
||||
gp.cmd("unset xlabel")
|
||||
gp.plot("sin(2*x) lt 3")
|
||||
gpNext()
|
||||
gpCmd("unset ylabel")
|
||||
gpCmd("unset ytics")
|
||||
gpCmd("unset xlabel")
|
||||
gpPlot("sin(2*x) lt 3")
|
||||
|
||||
gp.next()
|
||||
gp.cmd(xlab="X label")
|
||||
gp.plot("cos(2*x) lt 4")
|
||||
gpNext()
|
||||
gpCmd(xlab="X label")
|
||||
gpPlot("cos(2*x) lt 4")
|
||||
|
||||
gp.dump()
|
||||
gpDump()
|
||||
terminal == "unknown" || pressEnter()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
@ -184,7 +183,7 @@ function gp_test(terminal="unknown")
|
||||
:plot, "x8, v, (u<0.5) ? -1 : sinc(x8,v) notitle",
|
||||
:plot, "x9, v, (u<0.5) ? -1 : sinc(x9,v) notitle")
|
||||
|
||||
gp.exitAll()
|
||||
gpExitAll()
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user