Skip to content

Commit

Permalink
Parse all command line options in repl.c
Browse files Browse the repository at this point in the history
 - consolidate all compiler / cmdline options into jl_options_t struct in julia.h

 - add options.jl to base/ with an immutable type JLOptions that
   reflects the jl_options_t struct

 - add --procs=<n> command line flag (equivalent to -p <n>)

 - add --history-file={yes|no} and --startup-file={yes|no} cmdline opts

 - deprecate -f, -F, --no-startup, --no-history-file cmdline flags

 - add tests for cmdline arguments in test/cmdlineargs.jl

 - modify test/Makefile and tests to use long command line option,
   add command line argument tests to runtests.jl

 - update relevant docs in the manual and manpages
  • Loading branch information
jakebolewski committed Jan 5, 2015
1 parent 060aaec commit 8cfc435
Show file tree
Hide file tree
Showing 24 changed files with 765 additions and 385 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ BASE_SRCS := $(wildcard base/*.jl base/*/*.jl base/*/*/*.jl)
$(build_private_libdir)/sys.o: VERSION $(BASE_SRCS) $(build_docdir)/helpdb.jl $(build_private_libdir)/sys0.$(SHLIB_EXT)
@$(call PRINT_JULIA, cd base && \
$(call spawn,$(JULIA_EXECUTABLE)) -C $(JULIA_CPU_TARGET) --build $(call cygpath_w,$(build_private_libdir)/sys) \
-J$(call cygpath_w,$(build_private_libdir))/$$([ -e $(build_private_libdir)/sys.ji ] && echo sys.ji || echo sys0.ji) -f sysimg.jl \
-J$(call cygpath_w,$(build_private_libdir))/$$([ -e $(build_private_libdir)/sys.ji ] && echo sys.ji || echo sys0.ji) --startup-file=no sysimg.jl \
|| { echo '*** This error is usually fixed by running `make clean`. If the error persists$(,) try `make cleanall`. ***' && false; } )

$(build_bindir)/stringreplace: contrib/stringreplace.c | $(build_bindir)
Expand Down
227 changes: 120 additions & 107 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,10 @@ end
# try to include() a file, ignoring if not found
try_include(path::AbstractString) = isfile(path) && include(path)

function init_bind_addr(args::Vector{UTF8String})
# Treat --bind-to in a position independent manner in ARGS since
# --worker, -n and --machinefile options are affected by it
btoidx = findfirst(args, "--bind-to")
if btoidx > 0
bind_to = split(args[btoidx+1], ":")
# initialize the local proc network address / port
function init_bind_addr(opts::JLOptions)
if opts.bindto != C_NULL
bind_to = split(bytestring(opts.bindto), ":")
bind_addr = string(parseip(bind_to[1]))
if length(bind_to) > 1
bind_port = parseint(bind_to[2])
Expand All @@ -210,113 +208,122 @@ function init_bind_addr(args::Vector{UTF8String})
LPROC.bind_port = uint16(bind_port)
end


function process_options(args::Vector{UTF8String})
quiet = false
repl = true
startup = true
color_set = false
no_history_file = false
i = 1
while i <= length(args)
if args[i]=="-q" || args[i]=="--quiet"
quiet = true
elseif args[i]=="--worker"
start_worker()
# doesn't return
elseif args[i]=="--bind-to"
i+=1 # has already been processed
elseif args[i]=="-e" || args[i]=="--eval"
i == length(args) && error("-e,--eval no <expr> provided")
repl = false
i+=1
splice!(ARGS, 1:length(ARGS), args[i+1:end])
eval(Main,parse_input_line(args[i]))
break
elseif args[i]=="-E" || args[i]=="--print"
i == length(args) && error("-E,--print no <expr> provided")
repl = false
i+=1
splice!(ARGS, 1:length(ARGS), args[i+1:end])
show(eval(Main,parse_input_line(args[i])))
println()
break
elseif args[i]=="-P" || args[i]=="--post-boot"
i == length(args) && error("-P,--post-boot no <expr> provided")
i+=1
eval(Main,parse_input_line(args[i]))
elseif args[i]=="-L" || args[i]=="--load"
i == length(args) && error("-L, --load no <file> provided")
i+=1
require(args[i])
elseif args[i]=="-p"
i == length(args) && error("-p <n> processes not provided")
i+=1
if i > length(args) || !isdigit(args[i][1])
np = Sys.CPU_CORES
i -= 1
else
np = int(args[i])
np < 1 && error("-p <n> must be ≥ 1")
let reqarg = Set(UTF8String["--home", "-H",
"--eval", "-e",
"--print", "-E",
"--post-boot", "-P",
"--load", "-L",
"--sysimage", "-J",
"--cpu-target", "-C",
"--procs", "-p",
"--machinefile",
"--color",
"--history-file",
"--startup-file",
"--compile",
"--check-bounds",
"--int-literals",
"--dump-bitcode",
"--depwarn",
"--inline",
"--build", "-b",
"--bind-to"])
global process_options
function process_options(opts::JLOptions, args::Vector{UTF8String})
if !isempty(args) && (arg = first(args); arg[1] == '-' && in(arg, reqarg))
println(STDERR, "julia: option `$arg` is missing an argument")
exit(1)
end
quiet = false
repl = true
startup = true
color_set = false
no_history_file = false
opts = unsafe_load(cglobal(:jl_options, JLOptions))
while true
# show julia VERSION and quit
if bool(opts.version)
println("julia version ", VERSION)
exit(0)
end
addprocs(np)
elseif args[i]=="--machinefile"
i == length(args) && error("--machinefile no <file> provided")
i+=1
machines = load_machine_file(args[i])
addprocs(machines)
elseif args[i]=="-v" || args[i]=="--version"
println("julia version ", VERSION)
exit(0)
elseif args[i]=="--no-history"
# deprecated in v0.3
warn("'--no-history' is deprecated; use '--no-history-file'")
no_history_file = true
elseif args[i] == "--no-history-file"
no_history_file = true
elseif args[i] == "-f" || args[i] == "--no-startup"
startup = false
elseif args[i] == "-F"
# load juliarc now before processing any more options
load_juliarc()
startup = false
elseif args[i] == "-i"
global is_interactive = true
elseif startswith(args[i], "--color")
if args[i] == "--color"
color_set = true
global have_color = true
elseif args[i][8] == '='
val = args[i][9:end]
if in(val, ("no","0","false"))
color_set = true
global have_color = false
elseif in(val, ("yes","1","true"))
color_set = true
global have_color = true
end
# startup worker
if bool(opts.worker)
start_worker() # does not return
end
if !color_set
error("invalid option: ", args[i])
# load file immediately on all processors
if opts.load != C_NULL
require(bytestring(opts.load))
end
elseif args[i][1]!='-'
if startup
# show banner
quiet = bool(opts.quiet)
# load ~/.juliarc file
if opts.startupfile == 1
load_juliarc()
startup = false
elseif opts.startupfile == 2
startup = false
end
# load ~/.julia_history file
no_history_file = bool(opts.historyfile)
# add processors
if opts.nprocs > 1
addprocs(opts.nprocs)
end
# load processes from machine file
if opts.machinefile != C_NULL
addprocs(load_machine_file(bytestring(opts.machinefile)))
end
global is_interactive = bool(opts.isinteractive)
# REPL color
if opts.color == 0
color_set = false
global have_color = false
elseif opts.color == 1
color_set = true
global have_color = true
elseif opts.color == 2
color_set = true
global have_color = false
end
# eval expression
if opts.eval != C_NULL
repl = false
eval(Main, parse_input_line(bytestring(opts.eval)))
break
end
# eval expression and show result
if opts.print != C_NULL
repl = false
show(eval(Main, parse_input_line(bytestring(opts.print))))
println()
break
end
# eval expression but don't disable interactive mode
if opts.postboot != C_NULL
eval(Main, parse_input_line(bytestring(opts.postboot)))
end
# load file
if !isempty(args)
if args[1][1] != '-'
if startup
load_juliarc()
startup = false
end
# program
repl = false
# remove filename from ARGS
shift!(ARGS)
ccall(:jl_exit_on_sigint, Void, (Cint,), 1)
include(args[1])
else
println(STDERR, "julia: unknown option `$(args[1])`")
exit(1)
end
end
# program
repl = false
# remove julia's arguments
splice!(ARGS, 1:length(ARGS), args[i+1:end])
ccall(:jl_exit_on_sigint, Void, (Cint,), 1)
include(args[i])
break
else
error("unknown option: ", args[i])
end
i += 1
return (quiet,repl,startup,color_set,no_history_file)
end
return (quiet,repl,startup,color_set,no_history_file)
end

const roottask = current_task()
Expand All @@ -334,6 +341,8 @@ function init_load_path()
push!(LOAD_PATH,abspath(JULIA_HOME,"..","share","julia","site",vers))
end

# start local process as head "master" process with process id 1
# register this process as a local worker
function init_head_sched()
# start in "head node" mode
global PGRP
Expand Down Expand Up @@ -377,6 +386,8 @@ function early_init()
end
end

# starts the gc message task (for distrubuted gc) and
# registers worker process termination method
function init_parallel()
start_gc_msgs_task()
atexit(terminate_all_workers)
Expand All @@ -386,11 +397,13 @@ import .Terminals
import .REPL

function _start()
opts = JLOptions()
try
init_parallel()
init_bind_addr(ARGS)
any(a->(a=="--worker"), ARGS) || init_head_sched()
(quiet,repl,startup,color_set,no_history_file) = process_options(copy(ARGS))
init_bind_addr(opts)
# if this process is not a worker,
bool(opts.worker) || init_head_sched()
(quiet,repl,startup,color_set,no_history_file) = process_options(opts,copy(ARGS))

local term
global active_repl
Expand Down
2 changes: 1 addition & 1 deletion base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ macro deprecate(old,new)
end

function depwarn(msg, funcsym)
if bool(compileropts().depwarn)
if bool(JLOptions().depwarn)
bt = backtrace()
caller = firstcaller(bt, funcsym)
warn(msg, once=(caller!=C_NULL), key=caller, bt=bt)
Expand Down
23 changes: 2 additions & 21 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,6 @@ end

inference_stack = EmptyCallStack()

# Julia compiler options struct (see jl_compileropts_t in src/julia.h)
immutable JLCompilerOpts
julia_home::Ptr{Cchar}
julia_bin::Ptr{Cchar}
build_path::Ptr{Cchar}
image_file::Ptr{Cchar}
cpu_target::Ptr{Cchar}
code_coverage::Int8
malloc_log::Int8
check_bounds::Int8
dumpbitcode::Int8
int_literals::Cint
compile_enabled::Int8
opt_level::Int8
depwarn::Int8
can_inline::Int8
end

compileropts() = unsafe_load(cglobal(:jl_compileropts, JLCompilerOpts))

function is_static_parameter(sv::StaticVarInfo, s::Symbol)
sp = sv.sp
for i=1:2:length(sp)
Expand Down Expand Up @@ -1181,6 +1161,7 @@ function tmerge(typea::ANY, typeb::ANY)
return u
end


tchanged(n::ANY, o::ANY) = is(o,NF) || (!is(n,NF) && !(n <: o))

stupdate(state::(), changes::VarTable, vars) = copy(changes)
Expand Down Expand Up @@ -1592,7 +1573,7 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)

if !rec
@assert fulltree.args[3].head === :body
if compileropts().can_inline == 1
if JLOptions().can_inline == 1
fulltree.args[3] = inlining_pass(fulltree.args[3], sv, fulltree)[1]
# inlining can add variables
sv.vars = append_any(f_argnames(fulltree), fulltree.args[2][1])
Expand Down
34 changes: 34 additions & 0 deletions base/options.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Julia options struct (see jl_options_t in src/julia.h)

immutable JLOptions
version::Int8
quiet::Int8
julia_home::Ptr{Cchar}
julia_bin::Ptr{Cchar}
build_path::Ptr{Cchar}
eval::Ptr{Cchar}
print::Ptr{Cchar}
postboot::Ptr{Cchar}
load::Ptr{Cchar}
image_file::Ptr{Cchar}
cpu_target::Ptr{Cchar}
nprocs::Clong
machinefile::Ptr{Cchar}
isinteractive::Int8
color::Int8
historyfile::Int8
startupfile::Int8
compile_enabled::Int8
code_coverage::Int8
malloc_log::Int8
opt_level::Int8
check_bounds::Int8
int_literals::Cint
dumpbitcode::Int8
depwarn::Int8
can_inline::Int8
worker::Int8
bindto::Ptr{Cchar}
end

JLOptions() = unsafe_load(cglobal(:jl_options, JLOptions))
1 change: 1 addition & 0 deletions base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ include("reflection.jl")
include("build_h.jl")
include("version_git.jl")
include("c.jl")
include("options.jl")

# core operations & types
include("promotion.jl")
Expand Down
2 changes: 1 addition & 1 deletion base/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ warn(err::Exception; prefix="ERROR: ", kw...) =
warn(sprint(io->showerror(io,err)), prefix=prefix; kw...)

function julia_cmd(julia=joinpath(JULIA_HOME, "julia"))
opts = compileropts()
opts = JLOptions()
cpu_target = bytestring(opts.cpu_target)
image_file = bytestring(opts.image_file)
`$julia -C$cpu_target -J$image_file`
Expand Down
Loading

0 comments on commit 8cfc435

Please sign in to comment.