From 25b89e8470ea6380bac72e9720d32c939fbdc673 Mon Sep 17 00:00:00 2001 From: jake bolewski Date: Thu, 18 Dec 2014 14:09:01 -0500 Subject: [PATCH] Parse all command line options in repl.c - 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= command line flag (equivalent to -p ) - add --history-file={yes|no} and --startup-file={yes|no} cmdline opts - --worker command line arguments changed to --worker, --worker=default, or --worker=custom - 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 --- base/client.jl | 236 +++++++------ base/deprecated.jl | 2 +- base/inference.jl | 23 +- base/managers.jl | 5 +- base/options.jl | 34 ++ base/sysimg.jl | 1 + base/util.jl | 2 +- doc/man/julia.1 | 94 +++-- doc/manual/getting-started.rst | 58 +-- doc/manual/parallel-computing.rst | 2 +- examples/clustermanager/0mq/ZMQCM.jl | 2 +- .../clustermanager/simple/UnixDomainCM.jl | 2 +- src/ast.c | 6 +- src/cgutils.cpp | 12 +- src/codegen.cpp | 20 +- src/dump.c | 2 +- src/gf.c | 2 +- src/init.c | 102 +++--- src/intrinsics.cpp | 4 +- src/jlapi.c | 10 +- src/julia.h | 71 ++-- src/toplevel.c | 2 +- test/Makefile | 2 +- test/choosetests.jl | 2 +- test/cmdlineargs.jl | 168 +++++++++ test/examples.jl | 1 + test/repl.jl | 4 +- test/runtests.jl | 1 - ui/repl.c | 329 ++++++++++++------ 29 files changed, 785 insertions(+), 414 deletions(-) create mode 100644 base/options.jl create mode 100644 test/cmdlineargs.jl diff --git a/base/client.jl b/base/client.jl index 5e2da9f39fad6..d4ddccc809fdd 100644 --- a/base/client.jl +++ b/base/client.jl @@ -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]) @@ -210,120 +208,126 @@ 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" - worker_arg = (i == length(args)) ? "" : args[i+1] - - if worker_arg == "custom" - i += 1 - else - start_worker() - # doesn't return - end - - 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 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 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 provided") - i+=1 - eval(Main,parse_input_line(args[i])) - elseif args[i]=="-L" || args[i]=="--load" - i == length(args) && error("-L, --load no provided") - i+=1 - require(args[i]) - elseif args[i]=="-p" - i == length(args) && error("-p 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 must be ≥ 1") +# NOTE: This set of required arguments need to be kept in sync with the required arguments defined in ui/repl.c +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 + repl = true + startup = true + quiet = false + color_set = false + no_history_file = false + while true + # show julia VERSION and quit + if bool(opts.version) + println(STDOUT, "julia version ", VERSION) + exit(0) end - addprocs(np) - elseif args[i]=="--machinefile" - i == length(args) && error("--machinefile no 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 + # startup worker + if bool(opts.worker) + assert(opts.worker == 1 || opts.worker == 2) + # if default, start worker process otherwise if custom pass through + if opts.worker == 1 + start_worker() # does not return end 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() @@ -341,6 +345,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 @@ -387,6 +393,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) @@ -396,11 +404,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, schedule head process + bool(opts.worker) || init_head_sched() + (quiet,repl,startup,color_set,no_history_file) = process_options(opts,copy(ARGS)) local term global active_repl diff --git a/base/deprecated.jl b/base/deprecated.jl index 7d6e6e2aae19c..fa19f14560c0c 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -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) diff --git a/base/inference.jl b/base/inference.jl index 0dfa737778750..be9337540df01 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -41,27 +41,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 - fast_math::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) @@ -1695,7 +1674,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]) diff --git a/base/managers.jl b/base/managers.jl index 7a99a6f3333a6..2b8e976da1e36 100644 --- a/base/managers.jl +++ b/base/managers.jl @@ -87,7 +87,7 @@ function launch_on_machine(manager::SSHManager, machine, cnt, params, launched, if length(machine_bind) > 1 exeflags = `--bind-to $(machine_bind[2]) $exeflags` end - exeflags = `$exeflags --worker` + exeflags = `$exeflags --worker=default` machine_def = machine_bind[1] machine_def = split(machine_def, ':') @@ -183,7 +183,8 @@ function launch(manager::LocalManager, params::Dict, launched::Array, c::Conditi exeflags = params[:exeflags] for i in 1:manager.np - io, pobj = open(detach(setenv(`$(julia_cmd(exename)) $exeflags --bind-to $(LPROC.bind_addr) --worker`, dir=dir)), "r") + io, pobj = open(detach( + setenv(`$(julia_cmd(exename)) $exeflags --bind-to $(LPROC.bind_addr) --worker=default`, dir=dir)), "r") wconfig = WorkerConfig() wconfig.process = pobj wconfig.io = io diff --git a/base/options.jl b/base/options.jl new file mode 100644 index 0000000000000..e6a44c5b784bd --- /dev/null +++ b/base/options.jl @@ -0,0 +1,34 @@ +# NOTE: This type needs to be kept in sync with jl_options 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 + fast_math::Int8 + worker::Int8 + bindto::Ptr{Cchar} +end + +JLOptions() = unsafe_load(cglobal(:jl_options, JLOptions)) diff --git a/base/sysimg.jl b/base/sysimg.jl index 50d0b30585d84..48a772486af60 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -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") diff --git a/base/util.jl b/base/util.jl index bb606c4f1a18b..f7295ec2b7e98 100644 --- a/base/util.jl +++ b/base/util.jl @@ -261,7 +261,7 @@ warn(err::Exception; prefix="ERROR: ", kw...) = warn(STDERR, 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` diff --git a/doc/man/julia.1 b/doc/man/julia.1 index d25a8bcbc3b2b..edf367f116e50 100644 --- a/doc/man/julia.1 +++ b/doc/man/julia.1 @@ -56,6 +56,22 @@ If a Julia source file is given as a \fIprogram\fP (optionally followed by .SH "COMMAND-LINE OPTIONS" .TP 25 +.TP +-v, --version +Display version information + +.TP +-h, --help +Print help message + +.TP +-q, --quiet +Quiet startup without banner + +.TP +-H, --home +Set location of julia executable + .TP -e, --eval Evaluate @@ -65,77 +81,85 @@ Evaluate Evaluate and show .TP --f, --no-startup -Don't load ~/.juliarc.jl +-P, --post-boot +Evaluate , but don't disable interactive mode .TP --F -Load ~/.juliarc.jl, then handle remaining inputs +-L, --load +Load immediately on all processors .TP --h, --help -Print this message +-J, --sysimage +Start up with the given system image file .TP --H, --home -Set location of julia executable +-C, --cpu-target +Limit usage of cpu features up to .TP --i -Force isinteractive() to be true +-p, --procs +Run n local processes .TP --J, --sysimage -Start up with the given system image file +--machinefile +Run processes on hosts listed in .TP --L, --load -Load right after boot on all processors +-i +Force isinteractive() to be true .TP --p -Run n local processes +--color={yes|no} +Enable or disable color text .TP --P, --post-boot -Evaluate right after boot +--history-file={yes|no} +Load or save history .TP --q, --quiet -Quiet startup without banner +--startup-file={yes|no} +Load ~/.juliarc.jl .TP --v, --version -Display version information +--compile={yes|no|all} +Enable or disable compiler, or request exhaustive compilation .TP ---code-coverage -Count executions of source lines +--code-coverage={none|user|all}, --code-coverage +Count executions of source lines (omitting setting is equivalent to 'user') .TP ---color={yes|no} -Enable or disable color text +--track-allocation={none|user|all}, --track-allocation +Count bytes allocated by each source line .TP ---check-bounds={yes|no} -Emit bounds checks always or never (ignoring declarations) +-O, --optimize +Run time-intensive code optimizations .TP ---math-mode={ieee|user} -Always use IEEE semantics for math (ignoring declarations), -or adhere to declarations in source code +--check-bounds={yes|no} +Emit bounds checks always or never (ignoring declarations) .TP --int-literals={32|64} Select integer literal size independent of platform .TP ---machinefile -Run processes on hosts listed in +--dump-bitcode={yes|no} +Dump bitcode for the system image (used with --build) .TP ---no-history-file -Don't load or save history +--depwarn={yes|no} +Enable or disable syntax and method deprecation warnings + +.TP +--inline={yes|no} +Control whether inlining is permitted (overrides functions declared as @inline) + +.TP +--math-mode={ieee|user} +Always use IEEE semantics for math (ignoring declarations), +or adhere to declarations in source code .SH FILES .I ~/.juliarc.jl diff --git a/doc/manual/getting-started.rst b/doc/manual/getting-started.rst index d214751c50227..c7693c7c1aca3 100644 --- a/doc/manual/getting-started.rst +++ b/doc/manual/getting-started.rst @@ -103,41 +103,47 @@ There are various ways to run Julia code and provide options, similar to those available for the ``perl`` and ``ruby`` programs:: julia [options] [program] [args...] - -v, --version Display version information - -h, --help Print this message - -q, --quiet Quiet startup without banner - -H, --home Set location of julia executable + -v, --version Display version information + -h, --help Print this message + -q, --quiet Quiet startup without banner + -H, --home Set location of julia executable - -e, --eval Evaluate - -E, --print Evaluate and show - -P, --post-boot Evaluate , but don't disable interactive mode - -L, --load Load immediately on all processors - -J, --sysimage Start up with the given system image file + -e, --eval Evaluate + -E, --print Evaluate and show + -P, --post-boot Evaluate , but don't disable interactive mode + -L, --load Load immediately on all processors + -J, --sysimage Start up with the given system image file + -C, --cpu-target Limit usage of cpu features up to - -p Run n local processes - --machinefile Run processes on hosts listed in + -p, --procs Run n local processes + --machinefile Run processes on hosts listed in - -i Force isinteractive() to be true - --no-history-file Don't load or save history - -f, --no-startup Don't load ~/.juliarc.jl - -F Load ~/.juliarc.jl, then handle remaining inputs - --color={yes|no} Enable or disable color text + -i Force isinteractive() to be true + --color={yes|no} Enable or disable color text - --compile={yes|no|all} Enable or disable compiler, or request exhaustive compilation + --history-file={yes|no} Load or save history + --no-history-file Don't load history file (deprecated, use --history-file=no) + --startup-file={yes|no} Load ~/.juliarc.jl + -f, --no-startup Don't load ~/.juliarc (deprecated, use --startup-file=no) + -F Load ~/.juliarc (deprecated, use --startup-file=yes) + + --compile={yes|no|all} Enable or disable compiler, or request exhaustive compilation --code-coverage={none|user|all}, --code-coverage Count executions of source lines (omitting setting is equivalent to 'user') - --track-allocation={none|user|all} - Count bytes allocated by each source line - --check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations) - --math-mode={ieee|user} Always use IEEE semantics for math (ignoring declarations), - or adhere to declarations in source code - -O, --optimize Run time-intensive code optimizations - --int-literals={32|64} Select integer literal size independent of platform - --dump-bitcode={yes|no} Dump bitcode for the system image (used with --build) - --depwarn={yes|no} Enable or disable syntax and method deprecation warnings + --track-allocation={none|user|all}, --track-allocation + Count bytes allocated by each source line + -O, --optimize + Run time-intensive code optimizations + --check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations) + --int-literals={32|64} Select integer literal size independent of platform + --dump-bitcode={yes|no} Dump bitcode for the system image (used with --build) + --depwarn={yes|no} Enable or disable syntax and method deprecation warnings + --inline={yes|no} Control whether inlining is permitted (overrides functions declared as @inline) + --math-mode={ieee|user} Always use IEEE semantics for math (ignoring declarations), + or adhere to declarations in source code Resources --------- diff --git a/doc/manual/parallel-computing.rst b/doc/manual/parallel-computing.rst index d7e220d4d8611..68b17c9d7a2ec 100644 --- a/doc/manual/parallel-computing.rst +++ b/doc/manual/parallel-computing.rst @@ -851,7 +851,7 @@ Note: The julia processes are still all *logically* connected to each other - an awareness of 0MQ being used as the transport layer. When using custom transports: - - julia workers must be started with arguments ``--worker custom``. Just ``--worker`` will result in the newly launched + - julia workers must be started with arguments ``--worker=custom``. Just ``--worker`` or ``--worker=default`` will result in the newly launched workers defaulting to the socket transport implementation - For every logical connection with a worker, ``process_messages(rd::AsyncStream, wr::AsyncStream)`` must be called. This launches a new task that handles reading and writing of messages from/to the worker represented by the ``AsyncStream`` objects diff --git a/examples/clustermanager/0mq/ZMQCM.jl b/examples/clustermanager/0mq/ZMQCM.jl index f7db7ca649d75..552651c4e0745 100644 --- a/examples/clustermanager/0mq/ZMQCM.jl +++ b/examples/clustermanager/0mq/ZMQCM.jl @@ -195,7 +195,7 @@ end function launch(manager::ZMQCMan, params::Dict, launched::Array, c::Condition) #println("launch $(params[:np])") for i in 1:params[:np] - io, pobj = open (`julia --worker custom worker.jl $i`, "r") + io, pobj = open (`julia --worker=custom worker.jl $i`, "r") wconfig = WorkerConfig() wconfig.userdata = Dict(:zid=>i, :io=>io) diff --git a/examples/clustermanager/simple/UnixDomainCM.jl b/examples/clustermanager/simple/UnixDomainCM.jl index 114d70bdaf479..8d316b3fb7389 100644 --- a/examples/clustermanager/simple/UnixDomainCM.jl +++ b/examples/clustermanager/simple/UnixDomainCM.jl @@ -9,7 +9,7 @@ function launch(manager::UnixDomainCM, params::Dict, launched::Array, c::Conditi for i in 1:manager.np sockname = tempname() try - cmd = `$(params[:exename]) --worker custom $(@__FILE__) worker $sockname` + cmd = `$(params[:exename]) --worker=custom $(@__FILE__) worker $sockname` io, pobj = open (cmd, "r") wconfig = WorkerConfig() diff --git a/src/ast.c b/src/ast.c index 66b47620b1759..3a7de1927396f 100644 --- a/src/ast.c +++ b/src/ast.c @@ -138,7 +138,7 @@ void jl_init_frontend(void) fl_jlgensym_sym = symbol("jlgensym"); // Enable / disable syntax deprecation warnings - jl_parse_depwarn((int)jl_compileropts.depwarn); + jl_parse_depwarn((int)jl_options.depwarn); } DLLEXPORT void jl_lisp_prompt(void) @@ -245,9 +245,9 @@ static jl_value_t *scm_to_julia_(value_t e, int eo) } if ( #ifdef _P64 - jl_compileropts.int_literals==32 + jl_options.int_literals==32 #else - jl_compileropts.int_literals!=64 + jl_options.int_literals!=64 #endif ) { if (i64 > (int64_t)S32_MAX || i64 < (int64_t)S32_MIN) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 114155005fb2a..89b42fc019b74 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -313,7 +313,7 @@ static void jl_gen_llvm_gv_array(llvm::Module *mod, SmallVectorgetType(), @@ -323,7 +323,7 @@ static void jl_gen_llvm_gv_array(llvm::Module *mod, SmallVectorboundsCheck.empty() || ctx->boundsCheck.back()==true) && - jl_compileropts.check_bounds != JL_COMPILEROPT_CHECK_BOUNDS_OFF) || - jl_compileropts.check_bounds == JL_COMPILEROPT_CHECK_BOUNDS_ON) { + jl_options.check_bounds != JL_OPTIONS_CHECK_BOUNDS_OFF) || + jl_options.check_bounds == JL_OPTIONS_CHECK_BOUNDS_ON) { Value *ok = builder.CreateICmpULT(im1, len); BasicBlock *failBB = BasicBlock::Create(getGlobalContext(),"fail",ctx->f); BasicBlock *passBB = BasicBlock::Create(getGlobalContext(),"pass"); @@ -1469,8 +1469,8 @@ static Value *emit_array_nd_index(Value *a, jl_value_t *ex, size_t nd, jl_value_ Value *stride = ConstantInt::get(T_size, 1); #if CHECK_BOUNDS==1 bool bc = ((ctx->boundsCheck.empty() || ctx->boundsCheck.back()==true) && - jl_compileropts.check_bounds != JL_COMPILEROPT_CHECK_BOUNDS_OFF) || - jl_compileropts.check_bounds == JL_COMPILEROPT_CHECK_BOUNDS_ON; + jl_options.check_bounds != JL_OPTIONS_CHECK_BOUNDS_OFF) || + jl_options.check_bounds == JL_OPTIONS_CHECK_BOUNDS_ON; BasicBlock *failBB=NULL, *endBB=NULL; if (bc) { failBB = BasicBlock::Create(getGlobalContext(), "oob"); diff --git a/src/codegen.cpp b/src/codegen.cpp index d8b3b30d37439..07371cbcb9614 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -943,7 +943,7 @@ extern "C" int isabspath(const char *in); void write_log_data(logdata_t logData, const char *extension) { - std::string base = std::string(jl_compileropts.julia_home); + std::string base = std::string(jl_options.julia_home); base = base + "/../share/julia/base/"; logdata_t::iterator it = logData.begin(); for (; it != logData.end(); it++) { @@ -3365,7 +3365,7 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed, } else if (head == boundscheck_sym) { if (jl_array_len(ex->args) > 0 && - jl_compileropts.check_bounds == JL_COMPILEROPT_CHECK_BOUNDS_DEFAULT) { + jl_options.check_bounds == JL_OPTIONS_CHECK_BOUNDS_DEFAULT) { jl_value_t *arg = args[0]; if (arg == jl_true) { ctx->boundsCheck.push_back(true); @@ -3916,8 +3916,8 @@ static Function *emit_function(jl_lambda_info_t *lam, bool cstyle) // step 5. set up debug info context and create first basic block bool in_user_code = !jl_is_submodule(lam->module, jl_base_module) && !jl_is_submodule(lam->module, jl_core_module); - bool do_coverage = jl_compileropts.code_coverage == JL_LOG_ALL || (jl_compileropts.code_coverage == JL_LOG_USER && in_user_code); - bool do_malloc_log = jl_compileropts.malloc_log == JL_LOG_ALL || (jl_compileropts.malloc_log == JL_LOG_USER && in_user_code); + bool do_coverage = jl_options.code_coverage == JL_LOG_ALL || (jl_options.code_coverage == JL_LOG_USER && in_user_code); + bool do_malloc_log = jl_options.malloc_log == JL_LOG_ALL || (jl_options.malloc_log == JL_LOG_USER && in_user_code); jl_value_t *stmt = skip_meta(stmts); std::string filename = "no file"; char *dbgFuncName = lam->name->name; @@ -5193,7 +5193,7 @@ static void init_julia_llvm_env(Module *m) #endif #endif FPM->add(createTypeBasedAliasAnalysisPass()); - if (jl_compileropts.opt_level>=1) + if (jl_options.opt_level>=1) FPM->add(createBasicAliasAnalysisPass()); // list of passes from vmkit FPM->add(createCFGSimplificationPass()); // Clean up disgusting code @@ -5262,13 +5262,13 @@ static void init_julia_llvm_env(Module *m) FPM->add(createJumpThreadingPass()); // Thread jumps FPM->add(createDeadStoreEliminationPass()); // Delete dead stores #if LLVM33 && !defined(INSTCOMBINE_BUG) - if (jl_compileropts.opt_level>=1) + if (jl_options.opt_level>=1) FPM->add(createSLPVectorizerPass()); // Vectorize straight-line code #endif FPM->add(createAggressiveDCEPass()); // Delete dead instructions #if LLVM33 && !defined(INSTCOMBINE_BUG) - if (jl_compileropts.opt_level>=1) + if (jl_options.opt_level>=1) FPM->add(createInstructionCombiningPass()); // Clean up after SLP loop vectorizer #endif #if LLVM35 @@ -5285,7 +5285,7 @@ extern "C" void jl_init_codegen(void) #ifdef JL_DEBUG_BUILD cl::ParseEnvironmentOptions("Julia", "JULIA_LLVM_ARGS"); #endif - imaging_mode = jl_compileropts.build_path != NULL; + imaging_mode = jl_options.build_path != NULL; #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR <= 3 // this option disables LLVM's signal handlers @@ -5382,9 +5382,9 @@ extern "C" void jl_init_codegen(void) TheTriple, "", #if LLVM35 - strcmp(jl_compileropts.cpu_target,"native") ? StringRef(jl_compileropts.cpu_target) : sys::getHostCPUName(), + strcmp(jl_options.cpu_target,"native") ? StringRef(jl_options.cpu_target) : sys::getHostCPUName(), #else - strcmp(jl_compileropts.cpu_target,"native") ? jl_compileropts.cpu_target : "", + strcmp(jl_options.cpu_target,"native") ? jl_options.cpu_target : "", #endif MAttrs); jl_TargetMachine = jl_TargetMachine->getTarget().createTargetMachine( diff --git a/src/dump.c b/src/dump.c index ed02d046bbf0a..51a6e2c63e073 100644 --- a/src/dump.c +++ b/src/dump.c @@ -190,7 +190,7 @@ static void jl_load_sysimg_so(char *fname) sysimg_gvars = (jl_value_t***)jl_dlsym(jl_sysimg_handle, "jl_sysimg_gvars"); globalUnique = *(size_t*)jl_dlsym(jl_sysimg_handle, "jl_globalUnique"); const char *cpu_target = (const char*)jl_dlsym(jl_sysimg_handle, "jl_sysimg_cpu_target"); - if (strcmp(cpu_target,jl_compileropts.cpu_target) != 0) + if (strcmp(cpu_target,jl_options.cpu_target) != 0) jl_error("Julia and the system image were compiled for different architectures.\n" "Please delete or regenerate sys.{so,dll,dylib}.\n"); uint32_t info[4]; diff --git a/src/gf.c b/src/gf.c index 9b5ed25f2a6dd..553dc556d2a9d 100644 --- a/src/gf.c +++ b/src/gf.c @@ -847,7 +847,7 @@ static jl_function_t *cache_method(jl_methtable_t *mt, jl_tuple_t *type, return newmeth; } else { - if (jl_compileropts.compile_enabled == 0) { + if (jl_options.compile_enabled == 0) { if (method->linfo->unspecialized == NULL) { jl_printf(JL_STDERR,"code missing for %s", method->linfo->name->name); jl_static_show(JL_STDERR, (jl_value_t*)type); diff --git a/src/init.c b/src/init.c index db59f2a325be0..eb6abbc3046b4 100644 --- a/src/init.c +++ b/src/init.c @@ -84,21 +84,35 @@ DLLEXPORT void gdblookup(ptrint_t ip); static const char system_image_path[256] = JL_SYSTEM_IMAGE_PATH; -jl_compileropts_t jl_compileropts = { NULL, // julia_home - NULL, // julia_bin - NULL, // build_path - system_image_path, // image_file - NULL, // cpu_target ("native", "core2", etc...) - 0, // code_coverage - 0, // malloc_log - JL_COMPILEROPT_CHECK_BOUNDS_DEFAULT, - JL_COMPILEROPT_DUMPBITCODE_OFF, - 0, // int_literals - JL_COMPILEROPT_COMPILE_DEFAULT, - 0, // opt_level - 1, // depwarn - 1, // can_inline - JL_COMPILEROPT_FAST_MATH_DEFAULT +jl_options_t jl_options = { 0, // version + 0, // quiet + NULL, // julia_home + NULL, // julia_bin + NULL, // build_path + NULL, // eval + NULL, // print + NULL, // postboot + NULL, // load + system_image_path, // image_file + NULL, // cpu_taget ("native", "core2", etc...) + 0, // nprocs + NULL, // machinefile + 0, // isinteractive + 0, // color + 0, // historyfile + 0, // startupfile + JL_OPTIONS_COMPILE_DEFAULT, // compile_enabled + 0, // code_coverage + 0, // malloc_log + 0, // opt_level + JL_OPTIONS_CHECK_BOUNDS_DEFAULT, // check_bounds + 0, // int_literals + JL_OPTIONS_DUMPBITCODE_OFF, // dump_bitcode + 1, // depwarn + 1, // can_inline + JL_OPTIONS_FAST_MATH_DEFAULT, + 0, // worker + NULL, // bindto }; int jl_boot_file_loaded = 0; @@ -482,9 +496,9 @@ DLLEXPORT void jl_atexit_hook() #if defined(JL_GC_MARKSWEEP) && defined(GC_FINAL_STATS) jl_print_gc_stats(JL_STDERR); #endif - if (jl_compileropts.code_coverage) + if (jl_options.code_coverage) jl_write_coverage_data(); - if (jl_compileropts.malloc_log) + if (jl_options.malloc_log) jl_write_malloc_log(); if (jl_base_module) { jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); @@ -853,12 +867,12 @@ static char *abspath(const char *in) } static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel) -{ // this function resolves the paths in jl_compileropts to absolute file locations as needed +{ // this function resolves the paths in jl_options to absolute file locations as needed // and it replaces the pointers to `julia_home`, `julia_bin`, `image_file`, and `build_path` // it may fail, print an error, and exit(1) if any of these paths are longer than PATH_MAX // // note: if you care about lost memory, you should call the appropriate `free()` function - // on the original pointer for each `char*` you've inserted into `jl_compileropts`, after + // on the original pointer for each `char*` you've inserted into `jl_options`, after // calling `julia_init()` char *free_path = (char*)malloc(PATH_MAX); size_t path_size = PATH_MAX; @@ -868,37 +882,37 @@ static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel) if (path_size >= PATH_MAX) { jl_error("fatal error: jl_compileropts.julia_bin path too long\n"); } - jl_compileropts.julia_bin = strdup(free_path); - if (!jl_compileropts.julia_home) { - jl_compileropts.julia_home = getenv("JULIA_HOME"); - if (!jl_compileropts.julia_home) { - jl_compileropts.julia_home = dirname(free_path); + jl_options.julia_bin = strdup(free_path); + if (!jl_options.julia_home) { + jl_options.julia_home = getenv("JULIA_HOME"); + if (!jl_options.julia_home) { + jl_options.julia_home = dirname(free_path); } } - if (jl_compileropts.julia_home) - jl_compileropts.julia_home = abspath(jl_compileropts.julia_home); + if (jl_options.julia_home) + jl_options.julia_home = abspath(jl_options.julia_home); free(free_path); free_path = NULL; - if (jl_compileropts.image_file) { - if (rel == JL_IMAGE_JULIA_HOME && !isabspath(jl_compileropts.image_file)) { + if (jl_options.image_file) { + if (rel == JL_IMAGE_JULIA_HOME && !isabspath(jl_options.image_file)) { // build time path, relative to JULIA_HOME free_path = (char*)malloc(PATH_MAX); int n = snprintf(free_path, PATH_MAX, "%s" PATHSEPSTRING "%s", - jl_compileropts.julia_home, jl_compileropts.image_file); + jl_options.julia_home, jl_options.image_file); if (n >= PATH_MAX || n < 0) { jl_error("fatal error: jl_compileropts.image_file path too long\n"); } - jl_compileropts.image_file = free_path; + jl_options.image_file = free_path; } - if (jl_compileropts.image_file) - jl_compileropts.image_file = abspath(jl_compileropts.image_file); + if (jl_options.image_file) + jl_options.image_file = abspath(jl_options.image_file); if (free_path) { free(free_path); free_path = NULL; } } - if (jl_compileropts.build_path) - jl_compileropts.build_path = abspath(jl_compileropts.build_path); + if (jl_options.build_path) + jl_options.build_path = abspath(jl_options.build_path); } void _julia_init(JL_IMAGE_SEARCH rel) @@ -910,11 +924,11 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_resolve_sysimg_location(rel); // If we are able to load the sysimg and get a cpu_target, use that unless user has overridden - if (jl_compileropts.cpu_target == NULL) { - const char * sysimg_cpu_target = jl_get_system_image_cpu_target(jl_compileropts.image_file); + if (jl_options.cpu_target == NULL) { + const char * sysimg_cpu_target = jl_get_system_image_cpu_target(jl_options.image_file); // If we can't load anything from the sysimg, default to native - jl_compileropts.cpu_target = sysimg_cpu_target ? sysimg_cpu_target : "native"; + jl_options.cpu_target = sysimg_cpu_target ? sysimg_cpu_target : "native"; } jl_page_size = jl_getpagesize(); @@ -986,7 +1000,7 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_an_empty_cell = (jl_value_t*)jl_alloc_cell_1d(0); jl_init_serializer(); - if (!jl_compileropts.image_file) { + if (!jl_options.image_file) { jl_core_module = jl_new_module(jl_symbol("Core")); jl_init_intrinsic_functions(); jl_init_primitives(); @@ -1003,9 +1017,9 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_init_box_caches(); } - if (jl_compileropts.image_file) { + if (jl_options.image_file) { JL_TRY { - jl_restore_system_image(jl_compileropts.image_file); + jl_restore_system_image(jl_options.image_file); } JL_CATCH { jl_printf(JL_STDERR, "error during init:\n"); @@ -1141,7 +1155,7 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_gc_enable(); #endif - if (jl_compileropts.image_file) + if (jl_options.image_file) jl_init_restored_modules(); jl_install_sigint_handler(); @@ -1170,15 +1184,15 @@ void jl_compile_all(void); DLLEXPORT void julia_save() { - const char *build_path = jl_compileropts.build_path; + const char *build_path = jl_options.build_path; if (build_path) { - if (jl_compileropts.compile_enabled == JL_COMPILEROPT_COMPILE_ALL) + if (jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL) jl_compile_all(); char *build_ji; if (asprintf(&build_ji, "%s.ji",build_path) > 0) { jl_save_system_image(build_ji); free(build_ji); - if (jl_compileropts.dumpbitcode == JL_COMPILEROPT_DUMPBITCODE_ON) { + if (jl_options.dumpbitcode == JL_OPTIONS_DUMPBITCODE_ON) { char *build_bc; if (asprintf(&build_bc, "%s.bc",build_path) > 0) { jl_dump_bitcode(build_bc); diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index bec70bb91f229..7877ad1c11d8f 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -734,9 +734,9 @@ struct math_builder { math_builder(jl_codectx_t *ctx, bool always_fast = false): old_fmf(builder.getFastMathFlags()) { - if (jl_compileropts.fast_math != JL_COMPILEROPT_FAST_MATH_OFF && + if (jl_options.fast_math != JL_OPTIONS_FAST_MATH_OFF && (always_fast || - jl_compileropts.fast_math == JL_COMPILEROPT_FAST_MATH_ON)) { + jl_options.fast_math == JL_OPTIONS_FAST_MATH_ON)) { FastMathFlags fmf; fmf.setUnsafeAlgebra(); builder.SetFastMathFlags(fmf); diff --git a/src/jlapi.c b/src/jlapi.c index 2d2c3a02a1b29..dea7ae409d822 100644 --- a/src/jlapi.c +++ b/src/jlapi.c @@ -35,9 +35,9 @@ DLLEXPORT void jl_init_with_image(const char *julia_home_dir, const char *image_ { if (jl_is_initialized()) return; libsupport_init(); - jl_compileropts.julia_home = julia_home_dir; + jl_options.julia_home = julia_home_dir; if (image_relative_path != NULL) - jl_compileropts.image_file = image_relative_path; + jl_options.image_file = image_relative_path; julia_init(JL_IMAGE_JULIA_HOME); //TODO: these should be part of Multi.__init__() //currently, we have them here since we may not want them @@ -245,17 +245,17 @@ DLLEXPORT int jl_is_debugbuild(void) DLLEXPORT jl_value_t *jl_get_julia_home(void) { - return jl_cstr_to_string(jl_compileropts.julia_home); + return jl_cstr_to_string(jl_options.julia_home); } DLLEXPORT jl_value_t *jl_get_julia_bin(void) { - return jl_cstr_to_string(jl_compileropts.julia_bin); + return jl_cstr_to_string(jl_options.julia_bin); } DLLEXPORT jl_value_t *jl_get_image_file(void) { - return jl_cstr_to_string(jl_compileropts.image_file); + return jl_cstr_to_string(jl_options.image_file); } DLLEXPORT int jl_ver_major(void) diff --git a/src/julia.h b/src/julia.h index 864767d6f606a..0816b11c6df9d 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1395,48 +1395,75 @@ void jl_print_gc_stats(JL_STREAM *s); // debugging void show_execution_point(char *filename, int lno); -// compiler options ----------------------------------------------------------- - -// Note: need to keep this in sync with its initialization in -// src/init.c, and with JLCompilerOpts in base/inference.jl +// julia options ----------------------------------------------------------- +// NOTE: This struct needs to be kept in sync with JLOptions type in base/options.jl typedef struct { + int8_t version; + int8_t quiet; const char *julia_home; const char *julia_bin; const char *build_path; + const char *eval; + const char *print; + const char *postboot; + const char *load; const char *image_file; const char *cpu_target; + long nprocs; + const char *machinefile; + int8_t isinteractive; + int8_t color; + int8_t historyfile; + int8_t startupfile; + int8_t compile_enabled; int8_t code_coverage; int8_t malloc_log; + int8_t opt_level; int8_t check_bounds; + int int_literals; int8_t dumpbitcode; - int int_literals; - int8_t compile_enabled; - int8_t opt_level; int8_t depwarn; int8_t can_inline; int8_t fast_math; -} jl_compileropts_t; + int8_t worker; + const char *bindto; +} jl_options_t; -extern DLLEXPORT jl_compileropts_t jl_compileropts; +extern DLLEXPORT jl_options_t jl_options; // Settings for code_coverage and malloc_log +// NOTE: if these numbers change, test/cmdlineargs.jl will have to be updated #define JL_LOG_NONE 0 #define JL_LOG_USER 1 #define JL_LOG_ALL 2 -#define JL_COMPILEROPT_CHECK_BOUNDS_DEFAULT 0 -#define JL_COMPILEROPT_CHECK_BOUNDS_ON 1 -#define JL_COMPILEROPT_CHECK_BOUNDS_OFF 2 -#define JL_COMPILEROPT_FAST_MATH_DEFAULT 0 -#define JL_COMPILEROPT_FAST_MATH_ON 1 -#define JL_COMPILEROPT_FAST_MATH_OFF 2 -#define JL_COMPILEROPT_COMPILE_DEFAULT 1 -#define JL_COMPILEROPT_COMPILE_OFF 0 -#define JL_COMPILEROPT_COMPILE_ON 1 -#define JL_COMPILEROPT_COMPILE_ALL 2 - -#define JL_COMPILEROPT_DUMPBITCODE_ON 1 -#define JL_COMPILEROPT_DUMPBITCODE_OFF 2 +#define JL_OPTIONS_CHECK_BOUNDS_DEFAULT 0 +#define JL_OPTIONS_CHECK_BOUNDS_ON 1 +#define JL_OPTIONS_CHECK_BOUNDS_OFF 2 + +#define JL_OPTIONS_COMPILE_DEFAULT 1 +#define JL_OPTIONS_COMPILE_OFF 0 +#define JL_OPTIONS_COMPILE_ON 1 +#define JL_OPTIONS_COMPILE_ALL 2 + +#define JL_OPTIONS_DUMPBITCODE_ON 1 +#define JL_OPTIONS_DUMPBITCODE_OFF 2 + +#define JL_OPTIONS_COLOR_ON 1 +#define JL_OPTIONS_COLOR_OFF 2 + +#define JL_OPTIONS_HISTORYFILE_ON 1 +#define JL_OPTIONS_HISTORYFILE_OFF 0 + +#define JL_OPTIONS_STARTUPFILE_ON 1 +#define JL_OPTIONS_STARTUPFILE_OFF 2 + +#define JL_OPTIONS_FAST_MATH_ON 1 +#define JL_OPTIONS_FAST_MATH_OFF 2 +#define JL_OPTIONS_FAST_MATH_DEFAULT 0 + +#define JL_OPTIONS_WORKER_DEFAULT 1 +#define JL_OPTIONS_WORKER_CUSTOM 2 // Version information #include "julia_version.h" diff --git a/src/toplevel.c b/src/toplevel.c index 9abf17398d6ea..69e85561e38b3 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -70,7 +70,7 @@ jl_array_t *jl_module_init_order = NULL; // load time init procedure: in build mode, only record order void jl_module_load_time_initialize(jl_module_t *m) { - int build_mode = (jl_compileropts.build_path != NULL); + int build_mode = (jl_options.build_path != NULL); if (build_mode) { if (jl_module_init_order == NULL) jl_module_init_order = jl_alloc_cell_1d(0); diff --git a/test/Makefile b/test/Makefile index d75a284b0c4d3..3a30a86e79944 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,7 +6,7 @@ TESTS = all linalg sparse $(filter-out TestHelpers runtests testdefs,$(subst .jl default: all $(TESTS) :: - @$(call PRINT_JULIA, $(call spawn,$(JULIA_EXECUTABLE)) --check-bounds=yes -f ./runtests.jl $@) + @$(call PRINT_JULIA, $(call spawn,$(JULIA_EXECUTABLE)) --check-bounds=yes --startup-file=no ./runtests.jl $@) perf: @$(MAKE) -C perf all diff --git a/test/choosetests.jl b/test/choosetests.jl index 1079338db50f0..1878556a743a7 100644 --- a/test/choosetests.jl +++ b/test/choosetests.jl @@ -28,7 +28,7 @@ function choosetests(choices = []) "replutil", "sets", "test", "goto", "llvmcall", "grisu", "nullable", "meta", "profile", "libgit2", "docs", "markdown", "base64", "parser", "serialize", "functors", "char", "misc", - "enums" + "enums", "cmdlineargs" ] if isdir(joinpath(JULIA_HOME, Base.DOCDIR, "examples")) diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl new file mode 100644 index 0000000000000..093badc7d3edf --- /dev/null +++ b/test/cmdlineargs.jl @@ -0,0 +1,168 @@ +let exename = joinpath(JULIA_HOME, (ccall(:jl_is_debugbuild, Cint, ()) == 0 ? "julia" : "julia-debug")) + # --version + let v = split(readall(`$exename -v`), "julia version ")[end] + @test VERSION == VersionNumber(v) + end + @test readall(`$exename -v`) == readall(`$exename --version`) + + # --help + @test startswith(readall(`$exename -h`), "julia [options] [program] [args...]") + @test startswith(readall(`$exename --help`), "julia [options] [program] [args...]") + + # --quiet + # This flag is indirectly tested in test/repl.jl + + # --home + @test success(`$exename -H $JULIA_HOME`) + @test success(`$exename --home=$JULIA_HOME`) + + # --eval + @test success(`$exename -e "exit(0)"`) + @test !success(`$exename -e "exit(1)"`) + @test success(`$exename --eval="exit(0)"`) + @test !success(`$exename --eval="exit(1)"`) + @test !success(`$exename -e`) + @test !success(`$exename --eval`) + + # --print + @test readall(`$exename -E "1+1"`) == "2\n" + @test readall(`$exename --print="1+1"`) == "2\n" + @test !success(`$exename -E`) + @test !success(`$exename --print`) + + # --post-boot + @test success(`$exename -P "exit(0)"`) + @test !success(`$exename -P "exit(1)"`) + @test success(`$exename --post-boot="exit(0)"`) + @test !success(`$exename --post-boot="exit(1)"`) + @test !success(`$exename -P`) + @test !success(`$exename --post-boot`) + + # --load + let testfile = tempname() + try + open(testfile, "w") do io + println(io, "testvar = :test") + end + @test split(readchomp(`$exename --load=$testfile -P "println(testvar)"`), '\n')[end] == "test" + @test split(readchomp(`$exename -P "println(testvar)" -L $testfile`), '\n')[end] == "test" + finally + rm(testfile) + end + end + # -L, --load requires an argument + @test !success(`$exename -L`) + @test !success(`$exename --load`) + + # --cpu-target + @test !success(`$exename -C invalidtarget`) + @test !success(`$exename --cpu-target=invalidtarget`) + + # --procs + @test readchomp(`$exename -q -p 2 -P "println(nworkers()); exit(0)"`) == "2" + @test !success(`$exename -p 0`) + @test !success(`$exename --procs=1.0`) + + # --machinefile + # this does not check that machinefile works, + # only that the filename gets correctly passed to the option struct + let fname = tempname() + touch(fname) + try + @test readchomp(`$exename --machinefile $fname -e "println(bytestring(Base.JLOptions().machinefile))"`) == fname + finally + rm(fname) + end + end + + # -i, isinteractive + @test readchomp(`$exename -E "isinteractive()"`) == "false" + @test readchomp(`$exename -E "isinteractive()" -i`) == "true" + + # --color + @test readchomp(`$exename --color=yes -E "Base.have_color"`) == "true" + @test readchomp(`$exename --color=no -E "Base.have_color"`) == "false" + @test !success(`$exename --color=false`) + + # --history-file + @test readchomp(`$exename -E "bool(Base.JLOptions().historyfile)" --history-file=yes`) == "true" + @test readchomp(`$exename -E "bool(Base.JLOptions().historyfile)" --history-file=no`) == "false" + @test !success(`$exename --history-file=false`) + + # --startup-file + let JL_OPTIONS_STARTUPFILE_ON = 1, + JL_OPTIONS_STARTUPFILE_OFF = 2 + @test int(readchomp(`$exename -E "Base.JLOptions().startupfile" --startup-file=yes`)) == JL_OPTIONS_STARTUPFILE_ON + @test int(readchomp(`$exename -E "Base.JLOptions().startupfile" --startup-file=no`)) == JL_OPTIONS_STARTUPFILE_OFF + end + @test !success(`$exename --startup-file=false`) + + # --code-coverage + @test readchomp(`$exename -E "bool(Base.JLOptions().code_coverage)"`) == "false" + @test readchomp(`$exename -E "bool(Base.JLOptions().code_coverage)" --code-coverage=none`) == "false" + + @test readchomp(`$exename -E "bool(Base.JLOptions().code_coverage)" --code-coverage`) == "true" + @test readchomp(`$exename -E "bool(Base.JLOptions().code_coverage)" --code-coverage=user`) == "true" + + # --track-allocation + @test readchomp(`$exename -E "bool(Base.JLOptions().malloc_log)"`) == "false" + @test readchomp(`$exename -E "bool(Base.JLOptions().malloc_log)" --track-allocation=none`) == "false" + + @test readchomp(`$exename -E "bool(Base.JLOptions().malloc_log)" --track-allocation`) == "true" + @test readchomp(`$exename -E "bool(Base.JLOptions().malloc_log)" --track-allocation=user`) == "true" + + # --optimize + @test readchomp(`$exename -E "bool(Base.JLOptions().opt_level)"`) == "false" + @test readchomp(`$exename -E "bool(Base.JLOptions().opt_level)" -O`) == "true" + @test readchomp(`$exename -E "bool(Base.JLOptions().opt_level)" --optimize`) == "true" + + # --check-bounds + let JL_OPTIONS_CHECK_BOUNDS_DEFAULT = 0, + JL_OPTIONS_CHECK_BOUNDS_ON = 1, + JL_OPTIONS_CHECK_BOUNDS_OFF = 2 + @test int(readchomp(`$exename -E "int(Base.JLOptions().check_bounds)"`)) == JL_OPTIONS_CHECK_BOUNDS_DEFAULT + @test int(readchomp(`$exename -E "int(Base.JLOptions().check_bounds)" --check-bounds=yes`)) == JL_OPTIONS_CHECK_BOUNDS_ON + @test int(readchomp(`$exename -E "int(Base.JLOptions().check_bounds)" --check-bounds=no`)) == JL_OPTIONS_CHECK_BOUNDS_OFF + end + # check-bounds takes yes/no as argument + @test !success(`$exename -E "exit(0)" --check-bounds=false`) + + # --depwarn + @test readchomp(`$exename --depwarn=no -E "Base.syntax_deprecation_warnings(true)"`) == "false" + @test readchomp(`$exename --depwarn=yes -E "Base.syntax_deprecation_warnings(false)"`) == "true" + @test !success(`$exename --depwarn=false`) + + # --inline + @test readchomp(`$exename -E "bool(Base.JLOptions().can_inline)"`) == "true" + @test readchomp(`$exename --inline=yes -E "bool(Base.JLOptions().can_inline)"`) == "true" + @test readchomp(`$exename --inline=no -E "bool(Base.JLOptions().can_inline)"`) == "false" + # --inline takes yes/no as arugment + @test !success(`$exename --inline=false`) + + # --fast-math + let JL_OPTIONS_FAST_MATH_DEFAULT = 0, + JL_OPTIONS_FAST_MATH_OFF = 2 + @test int(readchomp(`$exename -E "int(Base.JLOptions().fast_math)"`)) == JL_OPTIONS_FAST_MATH_DEFAULT + @test int(readchomp(`$exename --math-mode=user -E "int(Base.JLOptions().fast_math)"`)) == JL_OPTIONS_FAST_MATH_DEFAULT + @test int(readchomp(`$exename --math-mode=ieee -E "int(Base.JLOptions().fast_math)"`)) == JL_OPTIONS_FAST_MATH_OFF + end + # --math-mode takes ieee/user as argument + @test !success(`$exename --math-mode=fast`) + + # --worker takes default / custom as arugment (default/custom arguments tested in test/parallel.jl, test/examples.jl) + @test !success(`$exename --worker=true`) + + # test passing arguments + let testfile = tempname() + try + # write a julia source file that just prints ARGS to STDOUT and exits + open(testfile, "w") do io + println(io, "println(ARGS)") + end + @test readchomp(`$exename $testfile foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]" + @test !success(`$exename --foo $testfile`) + finally + rm(testfile) + end + end +end diff --git a/test/examples.jl b/test/examples.jl index bb9a8a5b70290..eb0b0833b8cdf 100644 --- a/test/examples.jl +++ b/test/examples.jl @@ -34,6 +34,7 @@ include(joinpath(dir, "queens.jl")) # Different cluster managers do not play well together. Since # the test infrastructure already uses LocalManager, we will test the simple # cluster manager example through a new Julia session. + @unix_only begin script = joinpath(dir, "clustermanager/simple/test_simple.jl") cmd = `$(joinpath(JULIA_HOME,Base.julia_exename())) $script` diff --git a/test/repl.jl b/test/repl.jl index 9b5028e81c435..687ec6336312e 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -240,7 +240,7 @@ master = Base.TTY(RawFD(fdm); readable = true) nENV = copy(ENV) nENV["TERM"] = "dumb" -p = spawn(setenv(`$exename -f --quiet`,nENV),slave,slave,slave) +p = spawn(setenv(`$exename --startup-file=no --quiet`,nENV),slave,slave,slave) start_reading(master) Base.wait_readnb(master,1) write(master,"1\nquit()\n") @@ -257,7 +257,7 @@ close(master) end # Test stream mode -outs, ins, p = readandwrite(`$exename -f --quiet`) +outs, ins, p = readandwrite(`$exename --startup-file=no --quiet`) write(ins,"1\nquit()\n") @test readall(outs) == "1\n" end diff --git a/test/runtests.jl b/test/runtests.jl index 70d91476050cd..a327d5c7a02e2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,5 @@ include("choosetests.jl") tests, net_on = choosetests(ARGS) - cd(dirname(@__FILE__)) do n = 1 if net_on diff --git a/ui/repl.c b/ui/repl.c index ce8a0efd01126..a8c9bfb8247bb 100644 --- a/ui/repl.c +++ b/ui/repl.c @@ -43,75 +43,105 @@ static char *program = NULL; static int imagepathspecified = 0; static const char usage[] = "julia [options] [program] [args...]\n"; -static const char opts[] = +static const char opts[] = " -v, --version Display version information\n" " -h, --help Print this message\n" " -q, --quiet Quiet startup without banner\n" " -H, --home Set location of julia executable\n\n" - " -e, --eval Evaluate \n" - " -E, --print Evaluate and show \n" - " -P, --post-boot Evaluate , but don't disable interactive mode\n" - " -L, --load Load immediately on all processors\n" - " -J, --sysimage Start up with the given system image file\n" - " -C --cpu-target Limit usage of cpu features up to \n\n" + " -e, --eval Evaluate \n" + " -E, --print Evaluate and show \n" + " -P, --post-boot Evaluate , but don't disable interactive mode\n" + " -L, --load Load immediately on all processors\n" + " -J, --sysimage Start up with the given system image file\n" + " -C, --cpu-target Limit usage of cpu features up to \n\n" - " -p Run n local processes\n" - " --machinefile Run processes on hosts listed in \n\n" + " -p, --procs Run n local processes\n" + " --machinefile Run processes on hosts listed in \n\n" - " -i Force isinteractive() to be true\n" - " --no-history-file Don't load or save history\n" - " -f, --no-startup Don't load ~/.juliarc.jl\n" - " -F Load ~/.juliarc.jl, then handle remaining inputs\n" - " --color={yes|no} Enable or disable color text\n\n" + " -i Force isinteractive() to be true\n" + " --color={yes|no} Enable or disable color text\n\n" + " --history-file={yes|no} Load or save history\n" + " --no-history-file Don't load history file (deprecated, use --history-file=no)\n" + " --startup-file={yes|no} Load ~/.juliarc.jl\n" + " -f, --no-startup Don't load ~/.juliarc (deprecated, use --startup-file=no)\n" + " -F Load ~/.juliarc (deprecated, use --startup-file=yes)\n\n" - " --compile={yes|no|all} Enable or disable compiler, or request exhaustive compilation\n\n" + " --compile={yes|no|all} Enable or disable compiler, or request exhaustive compilation\n\n" " --code-coverage={none|user|all}, --code-coverage\n" - " Count executions of source lines (omitting setting is equivalent to 'user')\n" - " --track-allocation={none|user|all}\n" - " Count bytes allocated by each source line\n" - " --check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations)\n" - " --inline={yes|no} Control whether inlining is permitted (even for functions declared as @inline)\n" - " --math-mode={ieee|user} Always use IEEE semantics for math (ignoring declarations),\n" - " or adhere to declarations in source code\n" - " -O, --optimize Run time-intensive code optimizations\n" - " --int-literals={32|64} Select integer literal size independent of platform\n" - " --dump-bitcode={yes|no} Dump bitcode for the system image (used with --build)\n" - " --depwarn={yes|no} Enable or disable syntax and method deprecation warnings\n"; + " Count executions of source lines (omitting setting is equivalent to 'user')\n\n" + + " --track-allocation={none|user|all}, --track-allocation\n" + " Count bytes allocated by each source line\n\n" + " -O, --optimize\n" + " Run time-intensive code optimizations\n" + " --check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations)\n" + " --int-literals={32|64} Select integer literal size independent of platform\n" + " --dump-bitcode={yes|no} Dump bitcode for the system image (used with --build)\n" + " --depwarn={yes|no} Enable or disable syntax and method deprecation warnings\n" + " --inline={yes|no} Control whether inlining is permitted (overrides functions declared as @inline)\n"; void parse_opts(int *argcp, char ***argvp) { - enum { - opt_check_bounds = 300, - opt_int_literals, - opt_dump_bitcode, - opt_compile, - opt_depwarn, - opt_inline, - opt_math_mode + enum { opt_machinefile = 300, + opt_color, + opt_history_file, + opt_no_history_file, + opt_startup_file, + opt_compile, + opt_code_coverage, + opt_track_allocation, + opt_check_bounds, + opt_int_literals, + opt_dump_bitcode, + opt_depwarn, + opt_inline, + opt_math_mode, + opt_worker, + opt_bind_to }; - static const char shortopts[] = "+H:hJ:C:O"; - static const struct option longopts[] = { - { "home", required_argument, 0, 'H' }, - { "build", required_argument, 0, 'b' }, - { "lisp", no_argument, &lisp_prompt, 1 }, - { "help", no_argument, 0, 'h' }, - { "sysimage", required_argument, 0, 'J' }, - { "code-coverage", optional_argument, 0, 'c' }, - { "cpu-target", required_argument, 0, 'C' }, - { "track-allocation",required_argument, 0, 'm' }, - { "check-bounds", required_argument, 0, opt_check_bounds }, - { "optimize", no_argument, 0, 'O' }, - { "int-literals", required_argument, 0, opt_int_literals }, - { "dump-bitcode", required_argument, 0, opt_dump_bitcode }, - { "compile", required_argument, 0, opt_compile }, - { "depwarn", required_argument, 0, opt_depwarn }, - { "inline", required_argument, 0, opt_inline }, - { "math-mode", required_argument, 0, opt_math_mode }, + static char* shortopts = "+vhqFfH:e:E:P:L:J:C:ip:Ob:"; + static struct option longopts[] = { + // exposed command line options + // NOTE: This set of required arguments need to be kept in sync + // with the required arguments defined in base/client.jl `process_options()` + { "version", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, + { "quiet", no_argument, 0, 'q' }, + { "home", required_argument, 0, 'H' }, + { "eval", required_argument, 0, 'e' }, + { "print", required_argument, 0, 'E' }, + { "post-boot", required_argument, 0, 'P' }, + { "load", required_argument, 0, 'L' }, + { "sysimage", required_argument, 0, 'J' }, + { "cpu-target", required_argument, 0, 'C' }, + { "procs", required_argument, 0, 'p' }, + { "machinefile", required_argument, 0, opt_machinefile }, + { "color", required_argument, 0, opt_color }, + { "history-file", required_argument, 0, opt_history_file }, + { "no-history-file", no_argument, 0, opt_no_history_file }, // deprecated + { "startup-file", required_argument, 0, opt_startup_file }, + { "no-startup", no_argument, 0, 'f' }, // deprecated + { "compile", required_argument, 0, opt_compile }, + { "code-coverage", optional_argument, 0, opt_code_coverage }, + { "track-allocation",optional_argument, 0, opt_track_allocation }, + { "optimize", no_argument, 0, 'O' }, + { "check-bounds", required_argument, 0, opt_check_bounds }, + { "int-literals", required_argument, 0, opt_int_literals }, + { "dump-bitcode", required_argument, 0, opt_dump_bitcode }, + { "depwarn", required_argument, 0, opt_depwarn }, + { "inline", required_argument, 0, opt_inline }, + { "math-mode", required_argument, 0, opt_math_mode }, + // hidden command line options + { "build", required_argument, 0, 'b' }, + { "worker", optional_argument, 0, opt_worker }, + { "bind-to", required_argument, 0, opt_bind_to }, + { "lisp", no_argument, &lisp_prompt, 1 }, { 0, 0, 0, 0 } }; int c; + char *endptr; opterr = 0; int skip = 0; int lastind = optind; @@ -120,31 +150,93 @@ void parse_opts(int *argcp, char ***argvp) case 0: break; case '?': - if (optind != lastind) skip++; + if (optind != lastind) skip++; lastind = optind; break; - case 'H': - jl_compileropts.julia_home = strdup(optarg); + case 'v': // version + jl_options.version = 1; break; - case 'b': - jl_compileropts.build_path = strdup(optarg); - if (!imagepathspecified) - jl_compileropts.image_file = NULL; + case 'h': // help + jl_printf(JL_STDOUT, "%s%s", usage, opts); + jl_exit(0); + case 'q': // quiet + jl_options.quiet = 1; + break; + case 'H': // home + jl_options.julia_home = strdup(optarg); + break; + case 'e': // eval + jl_options.eval = strdup(optarg); + break; + case 'E': // print + jl_options.print = strdup(optarg); break; - case 'J': - jl_compileropts.image_file = strdup(optarg); + case 'P': // post-boot + jl_options.postboot = strdup(optarg); + break; + case 'L': // load + jl_options.load = strdup(optarg); + break; + case 'J': // sysimage + jl_options.image_file = strdup(optarg); imagepathspecified = 1; break; - case 'C': - jl_compileropts.cpu_target = strdup(optarg); + case 'C': // cpu-target + jl_options.cpu_target = strdup(optarg); break; - case 'h': - jl_printf(JL_STDOUT, "%s%s", usage, opts); - jl_exit(0); - case 'O': - jl_compileropts.opt_level = 1; + case 'p': // procs + errno = 0; + jl_options.nprocs = strtol(optarg, &endptr, 10); + if (errno != 0 || optarg == endptr || *endptr != 0 || jl_options.nprocs < 1) + jl_errorf("julia: -p,--procs= must be an integer >= 1\n"); break; - case 'c': + case opt_machinefile: + jl_options.machinefile = strdup(optarg); + break; + case opt_color: + if (!strcmp(optarg,"yes")) + jl_options.color = JL_OPTIONS_COLOR_ON; + else if (!strcmp(optarg,"no")) + jl_options.color = JL_OPTIONS_COLOR_OFF; + else + jl_errorf("julia: invalid argument to --color={yes|no} (%s)\n", optarg); + break; + case opt_history_file: + if (!strcmp(optarg,"yes")) + jl_options.historyfile = JL_OPTIONS_HISTORYFILE_ON; + else if (!strcmp(optarg,"no")) + jl_options.historyfile = JL_OPTIONS_HISTORYFILE_OFF; + else + jl_errorf("julia: invalid argument to --history-file={yes|no} (%s)\n", optarg); + break; + case opt_no_history_file: + jl_options.historyfile = JL_OPTIONS_HISTORYFILE_OFF; + break; + case opt_startup_file: + if (!strcmp(optarg,"yes")) + jl_options.startupfile = JL_OPTIONS_STARTUPFILE_ON; + else if (!strcmp(optarg,"no")) + jl_options.startupfile = JL_OPTIONS_STARTUPFILE_OFF; + else + jl_errorf("julia: invalid argument to --startup-file={yes|no} (%s)\n", optarg); + break; + case 'f': + jl_options.startupfile = JL_OPTIONS_STARTUPFILE_OFF; + break; + case 'F': + jl_options.startupfile = JL_OPTIONS_STARTUPFILE_ON; + break; + case opt_compile: + if (!strcmp(optarg,"yes")) + jl_options.compile_enabled = JL_OPTIONS_COMPILE_ON; + else if (!strcmp(optarg,"no")) + jl_options.compile_enabled = JL_OPTIONS_COMPILE_OFF; + else if (!strcmp(optarg,"all")) + jl_options.compile_enabled = JL_OPTIONS_COMPILE_ALL; + else + jl_errorf("julia: invalid argument to --compile (%s)\n", optarg); + break; + case opt_code_coverage: if (optarg != NULL) { if (!strcmp(optarg,"user")) codecov = JL_LOG_USER; @@ -158,7 +250,7 @@ void parse_opts(int *argcp, char ***argvp) codecov = JL_LOG_USER; } break; - case 'm': + case opt_track_allocation: if (optarg != NULL) { if (!strcmp(optarg,"user")) malloclog = JL_LOG_USER; @@ -168,78 +260,93 @@ void parse_opts(int *argcp, char ***argvp) malloclog = JL_LOG_NONE; break; } + else { + malloclog = JL_LOG_USER; + } + break; + case 'O': // optimize + jl_options.opt_level = 1; + break; + case 'i': // isinteractive + jl_options.isinteractive = 1; + break; case opt_check_bounds: if (!strcmp(optarg,"yes")) - jl_compileropts.check_bounds = JL_COMPILEROPT_CHECK_BOUNDS_ON; + jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_ON; else if (!strcmp(optarg,"no")) - jl_compileropts.check_bounds = JL_COMPILEROPT_CHECK_BOUNDS_OFF; + jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_OFF; + else + jl_errorf("julia: invalid argument to --check-bounds={yes|no} (%s)\n", optarg); break; case opt_int_literals: if (!strcmp(optarg,"32")) - jl_compileropts.int_literals = 32; + jl_options.int_literals = 32; else if (!strcmp(optarg,"64")) - jl_compileropts.int_literals = 64; - else { - jl_errorf("julia: invalid integer literal size (%s)\n", optarg); - } + jl_options.int_literals = 64; + else + jl_errorf("julia: invalid argument to --int-literals={32|64} (%s)\n", optarg); break; case opt_dump_bitcode: if (!strcmp(optarg,"yes")) - jl_compileropts.dumpbitcode = JL_COMPILEROPT_DUMPBITCODE_ON; - else if (!strcmp(optarg,"no")) - jl_compileropts.dumpbitcode = JL_COMPILEROPT_DUMPBITCODE_OFF; - break; - case opt_compile: - if (!strcmp(optarg,"yes")) - jl_compileropts.compile_enabled = 1; + jl_options.dumpbitcode = JL_OPTIONS_DUMPBITCODE_ON; else if (!strcmp(optarg,"no")) - jl_compileropts.compile_enabled = 0; - else if (!strcmp(optarg,"all")) - jl_compileropts.compile_enabled = 2; - else { - jl_errorf("julia: invalid argument to --compile (%s)\n", optarg); - } + jl_options.dumpbitcode = JL_OPTIONS_DUMPBITCODE_OFF; break; case opt_depwarn: if (!strcmp(optarg,"yes")) - jl_compileropts.depwarn = 1; + jl_options.depwarn = 1; else if (!strcmp(optarg,"no")) - jl_compileropts.depwarn = 0; - else { - jl_errorf("julia: invalid argument to --depwarn (%s)\n", optarg); - } + jl_options.depwarn = 0; + else + jl_errorf("julia: invalid argument to --depwarn={yes|no} (%s)\n", optarg); break; - case opt_inline: /* inline */ + case opt_inline: if (!strcmp(optarg,"yes")) - jl_compileropts.can_inline = 1; + jl_options.can_inline = 1; else if (!strcmp(optarg,"no")) - jl_compileropts.can_inline = 0; + jl_options.can_inline = 0; else { - ios_printf(ios_stderr, "julia: invalid argument to --inline (%s)\n", optarg); - exit(1); + jl_errorf("julia: invalid argument to --inline (%s)\n", optarg); } break; case opt_math_mode: - if (!strcmp(optarg, "ieee")) - jl_compileropts.fast_math = JL_COMPILEROPT_FAST_MATH_OFF; - else if (!strcmp(optarg, "user")) - jl_compileropts.fast_math = JL_COMPILEROPT_FAST_MATH_DEFAULT; - else { - ios_printf(ios_stderr, "julia: invalid argument to --math-mode (%s)\n", optarg); - exit(1); - } + if (!strcmp(optarg,"ieee")) + jl_options.fast_math = JL_OPTIONS_FAST_MATH_OFF; + else if (!strcmp(optarg,"user")) + jl_options.fast_math = JL_OPTIONS_FAST_MATH_DEFAULT; + else + jl_errorf("julia: invalid argument to --math-mode (%s)\n", optarg); + break; + case 'b': // build + jl_options.build_path = strdup(optarg); + if (!imagepathspecified) + jl_options.image_file = NULL; + break; + case opt_worker: + if (optarg != NULL) + if (!strcmp(optarg,"default")) + jl_options.worker = JL_OPTIONS_WORKER_DEFAULT; + else if (!strcmp(optarg,"custom")) + jl_options.worker = JL_OPTIONS_WORKER_CUSTOM; + else + jl_errorf("julia: invalid argument to --worker={default|custom} (%s)\n", optarg); + else + jl_options.worker = JL_OPTIONS_WORKER_DEFAULT; + break; + case opt_bind_to: + jl_options.bindto = strdup(optarg); break; default: jl_errorf("julia: unhandled option -- %c\n" "This is a bug, please report it.\n", c); } } - jl_compileropts.code_coverage = codecov; - jl_compileropts.malloc_log = malloclog; + jl_options.code_coverage = codecov; + jl_options.malloc_log = malloclog; optind -= skip; *argvp += optind; *argcp -= optind; - if (jl_compileropts.image_file==NULL && *argcp > 0) { + if (jl_options.image_file==NULL && *argcp > 0) { if (strcmp((*argvp)[0], "-")) { program = (*argvp)[0]; }