Skip to content

Commit

Permalink
parse all command line options in repl.c
Browse files Browse the repository at this point in the history
 - 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
 - modify test/Makefile to use long command line option, add command line argument tests to runtests.jl
  • Loading branch information
jakebolewski committed Dec 29, 2014
1 parent 2a72e4e commit 586b9e1
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 185 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
231 changes: 128 additions & 103 deletions base/client.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
## client.jl - frontend handling command line options, environment setup,
## and REPL

immutable JLOptions
version::Int8
quiet::Int8
eval::Ptr{Cchar}
print::Ptr{Cchar}
postboot::Ptr{Cchar}
load::Ptr{Cchar}
nprocs::Clong
machinefile::Ptr{Cchar}
isinteractive::Int8
color::Int8
historyfile::Int8
startupfile::Int8
worker::Int8
bindto::Ptr{Cchar}
end

const ARGS = UTF8String[]

const text_colors = AnyDict(
Expand Down Expand Up @@ -183,12 +200,12 @@ 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})
function init_bind_addr()
# 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], ":")
opts = unsafe_load(cglobal(:jl_options, 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 +227,121 @@ 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",
"--build", "-b",
"--bind-to"])
global process_options
function process_options(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 beginswith(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(opt.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 Down Expand Up @@ -388,7 +413,7 @@ import .REPL
function _start()
try
init_parallel()
init_bind_addr(ARGS)
init_bind_addr()
any(a->(a=="--worker"), ARGS) || init_head_sched()
(quiet,repl,startup,color_set,no_history_file) = process_options(copy(ARGS))

Expand Down
1 change: 1 addition & 0 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1161,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
16 changes: 16 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ jl_compileropts_t jl_compileropts = { NULL, // julia_home
1, // depwarn
};

jl_options_t jl_options = { 0, // version
0, // quiet
NULL, // eval
NULL, // print
NULL, // postboot
NULL, // load
0, // nprocs
NULL, // machinefile
0, // isinteractive
0, // color
0, // historyfile
0, // startupfile
0, // worker
NULL, // bindto
};

int jl_boot_file_loaded = 0;
int exit_on_sigint = 0;

Expand Down
27 changes: 25 additions & 2 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,7 @@ extern DLLEXPORT jl_compileropts_t jl_compileropts;
#define JL_COMPILEROPT_CHECK_BOUNDS_DEFAULT 0
#define JL_COMPILEROPT_CHECK_BOUNDS_ON 1
#define JL_COMPILEROPT_CHECK_BOUNDS_OFF 2

#define JL_COMPILEROPT_COMPILE_DEFAULT 1
#define JL_COMPILEROPT_COMPILE_OFF 0
#define JL_COMPILEROPT_COMPILE_ON 1
Expand All @@ -1355,11 +1356,33 @@ extern DLLEXPORT jl_compileropts_t jl_compileropts;
// julia options --------------------------------------------------------------

typedef struct {
compiler_opts_t *compiler_opts;
} jl_options_t
int8_t version;
int8_t quiet;
const char *eval;
const char *print;
const char *postboot;
const char *load;
long nprocs;
const char *machinefile;
int8_t isinteractive;
int8_t color;
int8_t historyfile;
int8_t startupfile;
int8_t worker;
const char *bindto;
} jl_options_t;

extern DLLEXPORT jl_options_t jl_options;

#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

// Version information
#include "julia_version.h"

Expand Down
2 changes: 1 addition & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ TESTS = all linalg $(filter-out TestHelpers runtests testdefs,$(subst .jl,,$(wil
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
Expand Down
Loading

0 comments on commit 586b9e1

Please sign in to comment.