Add: julia-0.6.2
Former-commit-id: ccc667cf67d569f3fb3df39aa57c2134755a7551
This commit is contained in:
424
julia-0.6.2/share/julia/base/client.jl
Normal file
424
julia-0.6.2/share/julia/base/client.jl
Normal file
@@ -0,0 +1,424 @@
|
||||
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||||
|
||||
## client.jl - frontend handling command line options, environment setup,
|
||||
## and REPL
|
||||
|
||||
const text_colors = AnyDict(
|
||||
:black => "\033[30m",
|
||||
:red => "\033[31m",
|
||||
:green => "\033[32m",
|
||||
:yellow => "\033[33m",
|
||||
:blue => "\033[34m",
|
||||
:magenta => "\033[35m",
|
||||
:cyan => "\033[36m",
|
||||
:white => "\033[37m",
|
||||
:light_black => "\033[90m", # gray
|
||||
:light_red => "\033[91m",
|
||||
:light_green => "\033[92m",
|
||||
:light_yellow => "\033[93m",
|
||||
:light_blue => "\033[94m",
|
||||
:light_magenta => "\033[95m",
|
||||
:light_cyan => "\033[96m",
|
||||
:normal => "\033[0m",
|
||||
:default => "\033[39m",
|
||||
:bold => "\033[1m",
|
||||
:nothing => "",
|
||||
)
|
||||
|
||||
for i in 0:255
|
||||
text_colors[i] = "\033[38;5;$(i)m"
|
||||
end
|
||||
|
||||
const disable_text_style = AnyDict(
|
||||
:bold => "\033[22m",
|
||||
:normal => "",
|
||||
:default => "",
|
||||
)
|
||||
|
||||
# Create a docstring with an automatically generated list
|
||||
# of colors.
|
||||
available_text_colors = collect(Iterators.filter(x -> !isa(x, Integer), keys(text_colors)))
|
||||
const possible_formatting_symbols = [:normal, :bold, :default]
|
||||
available_text_colors = cat(1,
|
||||
sort!(intersect(available_text_colors, possible_formatting_symbols), rev=true),
|
||||
sort!(setdiff( available_text_colors, possible_formatting_symbols)))
|
||||
|
||||
const available_text_colors_docstring =
|
||||
string(join([string("`:", key,"`")
|
||||
for key in available_text_colors], ",\n", ", or \n"))
|
||||
|
||||
"""Dictionary of color codes for the terminal.
|
||||
|
||||
Available colors are: $available_text_colors_docstring as well as the integers 0 to 255 inclusive.
|
||||
|
||||
The color `:default` will print text in the default color while the color `:normal`
|
||||
will print text with all text properties (like boldness) reset.
|
||||
Printing with the color `:nothing` will print the string without modifications.
|
||||
"""
|
||||
text_colors
|
||||
|
||||
have_color = false
|
||||
default_color_warn = :yellow
|
||||
default_color_error = :light_red
|
||||
default_color_info = :cyan
|
||||
default_color_input = :normal
|
||||
default_color_answer = :normal
|
||||
color_normal = text_colors[:normal]
|
||||
|
||||
function repl_color(key, default)
|
||||
env_str = get(ENV, key, "")
|
||||
c = tryparse(Int, env_str)
|
||||
c_conv = isnull(c) ? Symbol(env_str) : get(c)
|
||||
haskey(text_colors, c_conv) ? c_conv : default
|
||||
end
|
||||
|
||||
error_color() = repl_color("JULIA_ERROR_COLOR", default_color_error)
|
||||
warn_color() = repl_color("JULIA_WARN_COLOR" , default_color_warn)
|
||||
info_color() = repl_color("JULIA_INFO_COLOR" , default_color_info)
|
||||
|
||||
input_color() = text_colors[repl_color("JULIA_INPUT_COLOR", default_color_input)]
|
||||
answer_color() = text_colors[repl_color("JULIA_ANSWER_COLOR", default_color_answer)]
|
||||
|
||||
stackframe_lineinfo_color() = repl_color("JULIA_STACKFRAME_LINEINFO_COLOR", :bold)
|
||||
stackframe_function_color() = repl_color("JULIA_STACKFRAME_FUNCTION_COLOR", :bold)
|
||||
|
||||
function repl_cmd(cmd, out)
|
||||
shell = shell_split(get(ENV,"JULIA_SHELL",get(ENV,"SHELL","/bin/sh")))
|
||||
shell_name = Base.basename(shell[1])
|
||||
|
||||
if isempty(cmd.exec)
|
||||
throw(ArgumentError("no cmd to execute"))
|
||||
elseif cmd.exec[1] == "cd"
|
||||
new_oldpwd = pwd()
|
||||
if length(cmd.exec) > 2
|
||||
throw(ArgumentError("cd method only takes one argument"))
|
||||
elseif length(cmd.exec) == 2
|
||||
dir = cmd.exec[2]
|
||||
if dir == "-"
|
||||
if !haskey(ENV, "OLDPWD")
|
||||
error("cd: OLDPWD not set")
|
||||
end
|
||||
cd(ENV["OLDPWD"])
|
||||
else
|
||||
cd(@static is_windows() ? dir : readchomp(`$shell -c "echo $(shell_escape(dir))"`))
|
||||
end
|
||||
else
|
||||
cd()
|
||||
end
|
||||
ENV["OLDPWD"] = new_oldpwd
|
||||
println(out, pwd())
|
||||
else
|
||||
run(ignorestatus(@static is_windows() ? cmd : (isa(STDIN, TTY) ? `$shell -i -c "$(shell_wrap_true(shell_name, cmd))"` : `$shell -c "$(shell_wrap_true(shell_name, cmd))"`)))
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
function shell_wrap_true(shell_name, cmd)
|
||||
if shell_name == "fish"
|
||||
"begin; $(shell_escape(cmd)); and true; end"
|
||||
else
|
||||
"($(shell_escape(cmd))) && true"
|
||||
end
|
||||
end
|
||||
|
||||
function display_error(io::IO, er, bt)
|
||||
if !isempty(bt)
|
||||
st = stacktrace(bt)
|
||||
if !isempty(st)
|
||||
io = redirect(io, log_error_to, st[1])
|
||||
end
|
||||
end
|
||||
print_with_color(Base.error_color(), io, "ERROR: "; bold = true)
|
||||
# remove REPL-related frames from interactive printing
|
||||
eval_ind = findlast(addr->Base.REPL.ip_matches_func(addr, :eval), bt)
|
||||
if eval_ind != 0
|
||||
bt = bt[1:eval_ind-1]
|
||||
end
|
||||
showerror(IOContext(io, :limit => true), er, bt)
|
||||
println(io)
|
||||
end
|
||||
display_error(er, bt) = display_error(STDERR, er, bt)
|
||||
display_error(er) = display_error(er, [])
|
||||
|
||||
function eval_user_input(ast::ANY, show_value)
|
||||
errcount, lasterr, bt = 0, (), nothing
|
||||
while true
|
||||
try
|
||||
if have_color
|
||||
print(color_normal)
|
||||
end
|
||||
if errcount > 0
|
||||
display_error(lasterr,bt)
|
||||
errcount, lasterr = 0, ()
|
||||
else
|
||||
ast = expand(ast)
|
||||
value = eval(Main, ast)
|
||||
eval(Main, Expr(:body, Expr(:(=), :ans, QuoteNode(value)), Expr(:return, nothing)))
|
||||
if !(value === nothing) && show_value
|
||||
if have_color
|
||||
print(answer_color())
|
||||
end
|
||||
try
|
||||
eval(Main, Expr(:body, Expr(:return, Expr(:call, display, QuoteNode(value)))))
|
||||
catch err
|
||||
println(STDERR, "Evaluation succeeded, but an error occurred while showing value of type ", typeof(value), ":")
|
||||
rethrow(err)
|
||||
end
|
||||
println()
|
||||
end
|
||||
end
|
||||
break
|
||||
catch err
|
||||
if errcount > 0
|
||||
println(STDERR, "SYSTEM: show(lasterr) caused an error")
|
||||
end
|
||||
errcount, lasterr = errcount+1, err
|
||||
if errcount > 2
|
||||
println(STDERR, "WARNING: it is likely that something important is broken, and Julia will not be able to continue normally")
|
||||
break
|
||||
end
|
||||
bt = catch_backtrace()
|
||||
end
|
||||
end
|
||||
isa(STDIN,TTY) && println()
|
||||
end
|
||||
|
||||
syntax_deprecation_warnings(warn::Bool) =
|
||||
ccall(:jl_parse_depwarn, Cint, (Cint,), warn) == 1
|
||||
|
||||
function syntax_deprecation_warnings(f::Function, warn::Bool)
|
||||
prev = syntax_deprecation_warnings(warn)
|
||||
try
|
||||
f()
|
||||
finally
|
||||
syntax_deprecation_warnings(prev)
|
||||
end
|
||||
end
|
||||
|
||||
function parse_input_line(s::String; filename::String="none")
|
||||
# (expr, pos) = parse(s, 1)
|
||||
# (ex, pos) = ccall(:jl_parse_string, Any,
|
||||
# (Ptr{UInt8},Csize_t,Int32,Int32),
|
||||
# s, sizeof(s), pos-1, 1)
|
||||
# if ex!==()
|
||||
# throw(ParseError("extra input after end of expression"))
|
||||
# end
|
||||
# expr
|
||||
ex = ccall(:jl_parse_input_line, Any, (Ptr{UInt8}, Csize_t, Ptr{UInt8}, Csize_t),
|
||||
s, sizeof(s), filename, sizeof(filename))
|
||||
if ex === :_
|
||||
# remove with 0.6 deprecation
|
||||
expand(ex) # to get possible warning about using _ as an rvalue
|
||||
end
|
||||
return ex
|
||||
end
|
||||
parse_input_line(s::AbstractString) = parse_input_line(String(s))
|
||||
|
||||
function parse_input_line(io::IO)
|
||||
s = ""
|
||||
while !eof(io)
|
||||
s *= readline(io, chomp=false)
|
||||
e = parse_input_line(s)
|
||||
if !(isa(e,Expr) && e.head === :incomplete)
|
||||
return e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# detect the reason which caused an :incomplete expression
|
||||
# from the error message
|
||||
# NOTE: the error messages are defined in src/julia-parser.scm
|
||||
incomplete_tag(ex) = :none
|
||||
function incomplete_tag(ex::Expr)
|
||||
Meta.isexpr(ex, :incomplete) || return :none
|
||||
msg = ex.args[1]
|
||||
contains(msg, "string") && return :string
|
||||
contains(msg, "comment") && return :comment
|
||||
contains(msg, "requires end") && return :block
|
||||
contains(msg, "\"`\"") && return :cmd
|
||||
contains(msg, "character") && return :char
|
||||
return :other
|
||||
end
|
||||
|
||||
# try to include() a file, ignoring if not found
|
||||
try_include(path::AbstractString) = isfile(path) && include(path)
|
||||
|
||||
function process_options(opts::JLOptions)
|
||||
if !isempty(ARGS)
|
||||
idxs = find(x -> x == "--", ARGS)
|
||||
length(idxs) > 0 && deleteat!(ARGS, idxs[1])
|
||||
end
|
||||
repl = true
|
||||
startup = (opts.startupfile != 2)
|
||||
history_file = (opts.historyfile != 0)
|
||||
quiet = (opts.quiet != 0)
|
||||
color_set = (opts.color != 0)
|
||||
global have_color = (opts.color == 1)
|
||||
global is_interactive = (opts.isinteractive != 0)
|
||||
while true
|
||||
# startup worker.
|
||||
# opts.startupfile, opts.load, etc should should not be processed for workers.
|
||||
if opts.worker != C_NULL
|
||||
start_worker(unsafe_string(opts.worker)) # does not return
|
||||
end
|
||||
|
||||
# add processors
|
||||
if opts.nprocs > 0
|
||||
addprocs(opts.nprocs)
|
||||
end
|
||||
# load processes from machine file
|
||||
if opts.machinefile != C_NULL
|
||||
addprocs(load_machine_file(unsafe_string(opts.machinefile)))
|
||||
end
|
||||
|
||||
# load ~/.juliarc file
|
||||
startup && load_juliarc()
|
||||
|
||||
# load file immediately on all processors
|
||||
if opts.load != C_NULL
|
||||
@sync for p in procs()
|
||||
@async remotecall_fetch(include, p, unsafe_string(opts.load))
|
||||
end
|
||||
end
|
||||
# eval expression
|
||||
if opts.eval != C_NULL
|
||||
repl = false
|
||||
eval(Main, parse_input_line(unsafe_string(opts.eval)))
|
||||
break
|
||||
end
|
||||
# eval expression and show result
|
||||
if opts.print != C_NULL
|
||||
repl = false
|
||||
show(eval(Main, parse_input_line(unsafe_string(opts.print))))
|
||||
println()
|
||||
break
|
||||
end
|
||||
# load file
|
||||
if !isempty(ARGS) && !isempty(ARGS[1])
|
||||
# program
|
||||
repl = false
|
||||
# remove filename from ARGS
|
||||
global PROGRAM_FILE = shift!(ARGS)
|
||||
if !is_interactive
|
||||
ccall(:jl_exit_on_sigint, Void, (Cint,), 1)
|
||||
end
|
||||
include(PROGRAM_FILE)
|
||||
end
|
||||
break
|
||||
end
|
||||
repl |= is_interactive
|
||||
return (quiet,repl,startup,color_set,history_file)
|
||||
end
|
||||
|
||||
function load_juliarc()
|
||||
# If the user built us with a specific Base.SYSCONFDIR, check that location first for a juliarc.jl file
|
||||
# If it is not found, then continue on to the relative path based on JULIA_HOME
|
||||
if !isempty(Base.SYSCONFDIR) && isfile(joinpath(JULIA_HOME,Base.SYSCONFDIR,"julia","juliarc.jl"))
|
||||
include(abspath(JULIA_HOME,Base.SYSCONFDIR,"julia","juliarc.jl"))
|
||||
else
|
||||
try_include(abspath(JULIA_HOME,"..","etc","julia","juliarc.jl"))
|
||||
end
|
||||
try_include(abspath(homedir(),".juliarc.jl"))
|
||||
end
|
||||
|
||||
function load_machine_file(path::AbstractString)
|
||||
machines = []
|
||||
for line in split(readstring(path),'\n'; keep=false)
|
||||
s = split(line, '*'; keep = false)
|
||||
map!(strip, s, s)
|
||||
if length(s) > 1
|
||||
cnt = isnumber(s[1]) ? parse(Int,s[1]) : Symbol(s[1])
|
||||
push!(machines,(s[2], cnt))
|
||||
else
|
||||
push!(machines,line)
|
||||
end
|
||||
end
|
||||
return machines
|
||||
end
|
||||
|
||||
import .Terminals
|
||||
import .REPL
|
||||
|
||||
const repl_hooks = []
|
||||
|
||||
"""
|
||||
atreplinit(f)
|
||||
|
||||
Register a one-argument function to be called before the REPL interface is initialized in
|
||||
interactive sessions; this is useful to customize the interface. The argument of `f` is the
|
||||
REPL object. This function should be called from within the `.juliarc.jl` initialization
|
||||
file.
|
||||
"""
|
||||
atreplinit(f::Function) = (unshift!(repl_hooks, f); nothing)
|
||||
|
||||
function __atreplinit(repl)
|
||||
for f in repl_hooks
|
||||
try
|
||||
f(repl)
|
||||
catch err
|
||||
showerror(STDERR, err)
|
||||
println(STDERR)
|
||||
end
|
||||
end
|
||||
end
|
||||
_atreplinit(repl) = @eval Main $__atreplinit($repl)
|
||||
|
||||
function _start()
|
||||
empty!(ARGS)
|
||||
append!(ARGS, Core.ARGS)
|
||||
opts = JLOptions()
|
||||
try
|
||||
(quiet,repl,startup,color_set,history_file) = process_options(opts)
|
||||
|
||||
local term
|
||||
global active_repl
|
||||
global active_repl_backend
|
||||
if repl
|
||||
if !isa(STDIN,TTY)
|
||||
global is_interactive |= !isa(STDIN, Union{File, IOStream})
|
||||
color_set || (global have_color = false)
|
||||
else
|
||||
term = Terminals.TTYTerminal(get(ENV, "TERM", @static is_windows() ? "" : "dumb"), STDIN, STDOUT, STDERR)
|
||||
global is_interactive = true
|
||||
color_set || (global have_color = Terminals.hascolor(term))
|
||||
quiet || REPL.banner(term,term)
|
||||
if term.term_type == "dumb"
|
||||
active_repl = REPL.BasicREPL(term)
|
||||
quiet || warn("Terminal not fully functional")
|
||||
else
|
||||
active_repl = REPL.LineEditREPL(term, true)
|
||||
active_repl.history_file = history_file
|
||||
active_repl.hascolor = have_color
|
||||
end
|
||||
# Make sure any displays pushed in .juliarc.jl ends up above the
|
||||
# REPLDisplay
|
||||
pushdisplay(REPL.REPLDisplay(active_repl))
|
||||
end
|
||||
end
|
||||
|
||||
if repl
|
||||
if !isa(STDIN,TTY)
|
||||
# note: currently IOStream is used for file STDIN
|
||||
if isa(STDIN,File) || isa(STDIN,IOStream)
|
||||
# reading from a file, behave like include
|
||||
eval(Main,parse_input_line(readstring(STDIN)))
|
||||
else
|
||||
# otherwise behave repl-like
|
||||
while !eof(STDIN)
|
||||
eval_user_input(parse_input_line(STDIN), true)
|
||||
end
|
||||
end
|
||||
else
|
||||
_atreplinit(active_repl)
|
||||
REPL.run_repl(active_repl, backend->(global active_repl_backend = backend))
|
||||
end
|
||||
end
|
||||
catch err
|
||||
eval(Main, Expr(:body, Expr(:return, Expr(:call, Base.display_error,
|
||||
QuoteNode(err), catch_backtrace()))))
|
||||
exit(1)
|
||||
end
|
||||
if is_interactive && have_color
|
||||
print(color_normal)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user