| Line | Exclusive | Inclusive | Code |
|---|---|---|---|
| 1 | # This file is a part of Julia. License is MIT: https://julialang.org/license | ||
| 2 | |||
| 3 | ## client.jl - frontend handling command line options, environment setup, | ||
| 4 | ## and REPL | ||
| 5 | |||
| 6 | have_color = nothing | ||
| 7 | const default_color_warn = :yellow | ||
| 8 | const default_color_error = :light_red | ||
| 9 | const default_color_info = :cyan | ||
| 10 | const default_color_debug = :blue | ||
| 11 | const default_color_input = :normal | ||
| 12 | const default_color_answer = :normal | ||
| 13 | const color_normal = text_colors[:normal] | ||
| 14 | |||
| 15 | function repl_color(key, default) | ||
| 16 | env_str = get(ENV, key, "") | ||
| 17 | c = tryparse(Int, env_str) | ||
| 18 | c_conv = something(c, Symbol(env_str)) | ||
| 19 | haskey(text_colors, c_conv) ? c_conv : default | ||
| 20 | end | ||
| 21 | |||
| 22 | error_color() = repl_color("JULIA_ERROR_COLOR", default_color_error) | ||
| 23 | warn_color() = repl_color("JULIA_WARN_COLOR" , default_color_warn) | ||
| 24 | info_color() = repl_color("JULIA_INFO_COLOR" , default_color_info) | ||
| 25 | debug_color() = repl_color("JULIA_DEBUG_COLOR" , default_color_debug) | ||
| 26 | |||
| 27 | input_color() = text_colors[repl_color("JULIA_INPUT_COLOR", default_color_input)] | ||
| 28 | answer_color() = text_colors[repl_color("JULIA_ANSWER_COLOR", default_color_answer)] | ||
| 29 | |||
| 30 | stackframe_lineinfo_color() = repl_color("JULIA_STACKFRAME_LINEINFO_COLOR", :bold) | ||
| 31 | stackframe_function_color() = repl_color("JULIA_STACKFRAME_FUNCTION_COLOR", :bold) | ||
| 32 | |||
| 33 | function repl_cmd(cmd, out) | ||
| 34 | shell = shell_split(get(ENV, "JULIA_SHELL", get(ENV, "SHELL", "/bin/sh"))) | ||
| 35 | shell_name = Base.basename(shell[1]) | ||
| 36 | |||
| 37 | # Immediately expand all arguments, so that typing e.g. ~/bin/foo works. | ||
| 38 | cmd.exec .= expanduser.(cmd.exec) | ||
| 39 | |||
| 40 | if isempty(cmd.exec) | ||
| 41 | throw(ArgumentError("no cmd to execute")) | ||
| 42 | elseif cmd.exec[1] == "cd" | ||
| 43 | new_oldpwd = pwd() | ||
| 44 | if length(cmd.exec) > 2 | ||
| 45 | throw(ArgumentError("cd method only takes one argument")) | ||
| 46 | elseif length(cmd.exec) == 2 | ||
| 47 | dir = cmd.exec[2] | ||
| 48 | if dir == "-" | ||
| 49 | if !haskey(ENV, "OLDPWD") | ||
| 50 | error("cd: OLDPWD not set") | ||
| 51 | end | ||
| 52 | dir = ENV["OLDPWD"] | ||
| 53 | end | ||
| 54 | cd(dir) | ||
| 55 | else | ||
| 56 | cd() | ||
| 57 | end | ||
| 58 | ENV["OLDPWD"] = new_oldpwd | ||
| 59 | println(out, pwd()) | ||
| 60 | else | ||
| 61 | @static if !Sys.iswindows() | ||
| 62 | if shell_name == "fish" | ||
| 63 | shell_escape_cmd = "begin; $(shell_escape_posixly(cmd)); and true; end" | ||
| 64 | else | ||
| 65 | shell_escape_cmd = "($(shell_escape_posixly(cmd))) && true" | ||
| 66 | end | ||
| 67 | cmd = `$shell -c $shell_escape_cmd` | ||
| 68 | end | ||
| 69 | try | ||
| 70 | run(ignorestatus(cmd)) | ||
| 71 | catch | ||
| 72 | # Windows doesn't shell out right now (complex issue), so Julia tries to run the program itself | ||
| 73 | # Julia throws an exception if it can't find the program, but the stack trace isn't useful | ||
| 74 | lasterr = current_exceptions() | ||
| 75 | lasterr = ExceptionStack([(exception = e[1], backtrace = [] ) for e in lasterr]) | ||
| 76 | invokelatest(display_error, lasterr) | ||
| 77 | end | ||
| 78 | end | ||
| 79 | nothing | ||
| 80 | end | ||
| 81 | |||
| 82 | # deprecated function--preserved for DocTests.jl | ||
| 83 | function ip_matches_func(ip, func::Symbol) | ||
| 84 | for fr in StackTraces.lookup(ip) | ||
| 85 | if fr === StackTraces.UNKNOWN || fr.from_c | ||
| 86 | return false | ||
| 87 | end | ||
| 88 | fr.func === func && return true | ||
| 89 | end | ||
| 90 | return false | ||
| 91 | end | ||
| 92 | |||
| 93 | function scrub_repl_backtrace(bt) | ||
| 94 | if bt !== nothing && !(bt isa Vector{Any}) # ignore our sentinel value types | ||
| 95 | bt = bt isa Vector{StackFrame} ? copy(bt) : stacktrace(bt) | ||
| 96 | # remove REPL-related frames from interactive printing | ||
| 97 | eval_ind = findlast(frame -> !frame.from_c && frame.func === :eval, bt) | ||
| 98 | eval_ind === nothing || deleteat!(bt, eval_ind:length(bt)) | ||
| 99 | end | ||
| 100 | return bt | ||
| 101 | end | ||
| 102 | scrub_repl_backtrace(stack::ExceptionStack) = | ||
| 103 | ExceptionStack(Any[(;x.exception, backtrace = scrub_repl_backtrace(x.backtrace)) for x in stack]) | ||
| 104 | |||
| 105 | istrivialerror(stack::ExceptionStack) = | ||
| 106 | length(stack) == 1 && length(stack[1].backtrace) ≤ 1 && !isa(stack[1].exception, MethodError) | ||
| 107 | # frame 1 = top level; assumes already went through scrub_repl_backtrace; MethodError see #50803 | ||
| 108 | |||
| 109 | function display_error(io::IO, stack::ExceptionStack) | ||
| 110 | printstyled(io, "ERROR: "; bold=true, color=Base.error_color()) | ||
| 111 | show_exception_stack(IOContext(io, :limit => true), stack) | ||
| 112 | println(io) | ||
| 113 | end | ||
| 114 | display_error(stack::ExceptionStack) = display_error(stderr, stack) | ||
| 115 | |||
| 116 | # these forms are depended on by packages outside Julia | ||
| 117 | function display_error(io::IO, er, bt) | ||
| 118 | printstyled(io, "ERROR: "; bold=true, color=Base.error_color()) | ||
| 119 | showerror(IOContext(io, :limit => true), er, bt, backtrace = bt!==nothing) | ||
| 120 | println(io) | ||
| 121 | end | ||
| 122 | display_error(er, bt=nothing) = display_error(stderr, er, bt) | ||
| 123 | |||
| 124 | function eval_user_input(errio, @nospecialize(ast), show_value::Bool) | ||
| 125 | errcount = 0 | ||
| 126 | lasterr = nothing | ||
| 127 | have_color = get(stdout, :color, false)::Bool | ||
| 128 | while true | ||
| 129 | try | ||
| 130 | if have_color | ||
| 131 | print(color_normal) | ||
| 132 | end | ||
| 133 | if lasterr !== nothing | ||
| 134 | lasterr = scrub_repl_backtrace(lasterr) | ||
| 135 | istrivialerror(lasterr) || setglobal!(Base.MainInclude, :err, lasterr) | ||
| 136 | invokelatest(display_error, errio, lasterr) | ||
| 137 | errcount = 0 | ||
| 138 | lasterr = nothing | ||
| 139 | else | ||
| 140 | ast = Meta.lower(Main, ast) | ||
| 141 | value = Core.eval(Main, ast) | ||
| 142 | setglobal!(Base.MainInclude, :ans, value) | ||
| 143 | if !(value === nothing) && show_value | ||
| 144 | if have_color | ||
| 145 | print(answer_color()) | ||
| 146 | end | ||
| 147 | try | ||
| 148 | invokelatest(display, value) | ||
| 149 | catch | ||
| 150 | @error "Evaluation succeeded, but an error occurred while displaying the value" typeof(value) | ||
| 151 | rethrow() | ||
| 152 | end | ||
| 153 | end | ||
| 154 | end | ||
| 155 | break | ||
| 156 | catch | ||
| 157 | if errcount > 0 | ||
| 158 | @error "SYSTEM: display_error(errio, lasterr) caused an error" | ||
| 159 | end | ||
| 160 | errcount += 1 | ||
| 161 | lasterr = scrub_repl_backtrace(current_exceptions()) | ||
| 162 | setglobal!(Base.MainInclude, :err, lasterr) | ||
| 163 | if errcount > 2 | ||
| 164 | @error "It is likely that something important is broken, and Julia will not be able to continue normally" errcount | ||
| 165 | break | ||
| 166 | end | ||
| 167 | end | ||
| 168 | end | ||
| 169 | isa(stdin, TTY) && println() | ||
| 170 | nothing | ||
| 171 | end | ||
| 172 | |||
| 173 | function _parse_input_line_core(s::String, filename::String) | ||
| 174 | ex = Meta.parseall(s, filename=filename) | ||
| 175 | if ex isa Expr && ex.head === :toplevel | ||
| 176 | if isempty(ex.args) | ||
| 177 | return nothing | ||
| 178 | end | ||
| 179 | last = ex.args[end] | ||
| 180 | if last isa Expr && (last.head === :error || last.head === :incomplete) | ||
| 181 | # if a parse error happens in the middle of a multi-line input | ||
| 182 | # return only the error, so that none of the input is evaluated. | ||
| 183 | return last | ||
| 184 | end | ||
| 185 | end | ||
| 186 | return ex | ||
| 187 | end | ||
| 188 | |||
| 189 | function parse_input_line(s::String; filename::String="none", depwarn=true) | ||
| 190 | # For now, assume all parser warnings are depwarns | ||
| 191 | ex = if depwarn | ||
| 192 | _parse_input_line_core(s, filename) | ||
| 193 | else | ||
| 194 | with_logger(NullLogger()) do | ||
| 195 | _parse_input_line_core(s, filename) | ||
| 196 | end | ||
| 197 | end | ||
| 198 | return ex | ||
| 199 | end | ||
| 200 | parse_input_line(s::AbstractString) = parse_input_line(String(s)) | ||
| 201 | |||
| 202 | # detect the reason which caused an :incomplete expression | ||
| 203 | # from the error message | ||
| 204 | # NOTE: the error messages are defined in src/julia-parser.scm | ||
| 205 | function fl_incomplete_tag(msg::AbstractString) | ||
| 206 | occursin("string", msg) && return :string | ||
| 207 | occursin("comment", msg) && return :comment | ||
| 208 | occursin("requires end", msg) && return :block | ||
| 209 | occursin("\"`\"", msg) && return :cmd | ||
| 210 | occursin("character", msg) && return :char | ||
| 211 | return :other | ||
| 212 | end | ||
| 213 | |||
| 214 | incomplete_tag(ex) = :none | ||
| 215 | function incomplete_tag(ex::Expr) | ||
| 216 | if ex.head !== :incomplete | ||
| 217 | return :none | ||
| 218 | elseif isempty(ex.args) | ||
| 219 | return :other | ||
| 220 | elseif ex.args[1] isa String | ||
| 221 | return fl_incomplete_tag(ex.args[1]) | ||
| 222 | else | ||
| 223 | return incomplete_tag(ex.args[1]) | ||
| 224 | end | ||
| 225 | end | ||
| 226 | incomplete_tag(exc::Meta.ParseError) = incomplete_tag(exc.detail) | ||
| 227 | |||
| 228 | function exec_options(opts) | ||
| 229 | quiet = (opts.quiet != 0) | ||
| 230 | startup = (opts.startupfile != 2) | ||
| 231 | history_file = (opts.historyfile != 0) | ||
| 232 | color_set = (opts.color != 0) # --color!=auto | ||
| 233 | global have_color = color_set ? (opts.color == 1) : nothing # --color=on | ||
| 234 | global is_interactive = (opts.isinteractive != 0) | ||
| 235 | |||
| 236 | # pre-process command line argument list | ||
| 237 | arg_is_program = !isempty(ARGS) | ||
| 238 | repl = !arg_is_program | ||
| 239 | cmds = unsafe_load_commands(opts.commands) | ||
| 240 | for (cmd, arg) in cmds | ||
| 241 | if cmd == 'e' | ||
| 242 | arg_is_program = false | ||
| 243 | repl = false | ||
| 244 | elseif cmd == 'E' | ||
| 245 | arg_is_program = false | ||
| 246 | repl = false | ||
| 247 | elseif cmd == 'L' | ||
| 248 | # nothing | ||
| 249 | elseif cmd == 'B' # --bug-report | ||
| 250 | # If we're doing a bug report, don't load anything else. We will | ||
| 251 | # spawn a child in which to execute these options. | ||
| 252 | let InteractiveUtils = load_InteractiveUtils() | ||
| 253 | InteractiveUtils.report_bug(arg) | ||
| 254 | end | ||
| 255 | return nothing | ||
| 256 | else | ||
| 257 | @warn "Unexpected command -$cmd'$arg'" | ||
| 258 | end | ||
| 259 | end | ||
| 260 | |||
| 261 | # remove filename from ARGS | ||
| 262 | global PROGRAM_FILE = arg_is_program ? popfirst!(ARGS) : "" | ||
| 263 | |||
| 264 | # Load Distributed module only if any of the Distributed options have been specified. | ||
| 265 | distributed_mode = (opts.worker == 1) || (opts.nprocs > 0) || (opts.machine_file != C_NULL) | ||
| 266 | if distributed_mode | ||
| 267 | let Distributed = require(PkgId(UUID((0x8ba89e20_285c_5b6f, 0x9357_94700520ee1b)), "Distributed")) | ||
| 268 | Core.eval(Main, :(const Distributed = $Distributed)) | ||
| 269 | Core.eval(Main, :(using .Distributed)) | ||
| 270 | end | ||
| 271 | |||
| 272 | invokelatest(Main.Distributed.process_opts, opts) | ||
| 273 | end | ||
| 274 | |||
| 275 | interactiveinput = (repl || is_interactive::Bool) && isa(stdin, TTY) | ||
| 276 | is_interactive::Bool |= interactiveinput | ||
| 277 | |||
| 278 | # load ~/.julia/config/startup.jl file | ||
| 279 | if startup | ||
| 280 | try | ||
| 281 | load_julia_startup() | ||
| 282 | catch | ||
| 283 | invokelatest(display_error, scrub_repl_backtrace(current_exceptions())) | ||
| 284 | !(repl || is_interactive::Bool) && exit(1) | ||
| 285 | end | ||
| 286 | end | ||
| 287 | |||
| 288 | # process cmds list | ||
| 289 | for (cmd, arg) in cmds | ||
| 290 | if cmd == 'e' | ||
| 291 | Core.eval(Main, parse_input_line(arg)) | ||
| 292 | elseif cmd == 'E' | ||
| 293 | invokelatest(show, Core.eval(Main, parse_input_line(arg))) | ||
| 294 | println() | ||
| 295 | elseif cmd == 'L' | ||
| 296 | # load file immediately on all processors | ||
| 297 | if !distributed_mode | ||
| 298 | include(Main, arg) | ||
| 299 | else | ||
| 300 | # TODO: Move this logic to Distributed and use a callback | ||
| 301 | @sync for p in invokelatest(Main.procs) | ||
| 302 | @async invokelatest(Main.remotecall_wait, include, p, Main, arg) | ||
| 303 | end | ||
| 304 | end | ||
| 305 | end | ||
| 306 | end | ||
| 307 | |||
| 308 | # load file | ||
| 309 | if arg_is_program | ||
| 310 | # program | ||
| 311 | if !is_interactive::Bool | ||
| 312 | exit_on_sigint(true) | ||
| 313 | end | ||
| 314 | try | ||
| 315 | if PROGRAM_FILE == "-" | ||
| 316 | include_string(Main, read(stdin, String), "stdin") | ||
| 317 | else | ||
| 318 | include(Main, PROGRAM_FILE) | ||
| 319 | end | ||
| 320 | catch | ||
| 321 | invokelatest(display_error, scrub_repl_backtrace(current_exceptions())) | ||
| 322 | if !is_interactive::Bool | ||
| 323 | exit(1) | ||
| 324 | end | ||
| 325 | end | ||
| 326 | end | ||
| 327 | if repl || is_interactive::Bool | ||
| 328 | if interactiveinput | ||
| 329 | banner = (opts.banner != 0) # --banner!=no | ||
| 330 | else | ||
| 331 | banner = (opts.banner == 1) # --banner=yes | ||
| 332 | end | ||
| 333 | 58 (100 %) |
58 (100 %)
samples spent calling
run_main_repl
run_main_repl(interactiveinput, quiet, banner, history_file, color_set)
|
|
| 334 | end | ||
| 335 | nothing | ||
| 336 | end | ||
| 337 | |||
| 338 | function _global_julia_startup_file() | ||
| 339 | # If the user built us with a specific Base.SYSCONFDIR, check that location first for a startup.jl file | ||
| 340 | # If it is not found, then continue on to the relative path based on Sys.BINDIR | ||
| 341 | BINDIR = Sys.BINDIR | ||
| 342 | SYSCONFDIR = Base.SYSCONFDIR | ||
| 343 | if !isempty(SYSCONFDIR) | ||
| 344 | p1 = abspath(BINDIR, SYSCONFDIR, "julia", "startup.jl") | ||
| 345 | isfile(p1) && return p1 | ||
| 346 | end | ||
| 347 | p2 = abspath(BINDIR, "..", "etc", "julia", "startup.jl") | ||
| 348 | isfile(p2) && return p2 | ||
| 349 | return nothing | ||
| 350 | end | ||
| 351 | |||
| 352 | function _local_julia_startup_file() | ||
| 353 | if !isempty(DEPOT_PATH) | ||
| 354 | path = abspath(DEPOT_PATH[1], "config", "startup.jl") | ||
| 355 | isfile(path) && return path | ||
| 356 | end | ||
| 357 | return nothing | ||
| 358 | end | ||
| 359 | |||
| 360 | function load_julia_startup() | ||
| 361 | global_file = _global_julia_startup_file() | ||
| 362 | (global_file !== nothing) && include(Main, global_file) | ||
| 363 | local_file = _local_julia_startup_file() | ||
| 364 | (local_file !== nothing) && include(Main, local_file) | ||
| 365 | return nothing | ||
| 366 | end | ||
| 367 | |||
| 368 | const repl_hooks = [] | ||
| 369 | |||
| 370 | """ | ||
| 371 | atreplinit(f) | ||
| 372 | |||
| 373 | Register a one-argument function to be called before the REPL interface is initialized in | ||
| 374 | interactive sessions; this is useful to customize the interface. The argument of `f` is the | ||
| 375 | REPL object. This function should be called from within the `.julia/config/startup.jl` | ||
| 376 | initialization file. | ||
| 377 | """ | ||
| 378 | atreplinit(f::Function) = (pushfirst!(repl_hooks, f); nothing) | ||
| 379 | |||
| 380 | function __atreplinit(repl) | ||
| 381 | for f in repl_hooks | ||
| 382 | try | ||
| 383 | f(repl) | ||
| 384 | catch err | ||
| 385 | showerror(stderr, err) | ||
| 386 | println(stderr) | ||
| 387 | end | ||
| 388 | end | ||
| 389 | end | ||
| 390 | _atreplinit(repl) = invokelatest(__atreplinit, repl) | ||
| 391 | |||
| 392 | function load_InteractiveUtils(mod::Module=Main) | ||
| 393 | # load interactive-only libraries | ||
| 394 | if !isdefined(mod, :InteractiveUtils) | ||
| 395 | try | ||
| 396 | let InteractiveUtils = require(PkgId(UUID(0xb77e0a4c_d291_57a0_90e8_8db25a27a240), "InteractiveUtils")) | ||
| 397 | Core.eval(mod, :(const InteractiveUtils = $InteractiveUtils)) | ||
| 398 | Core.eval(mod, :(using .InteractiveUtils)) | ||
| 399 | return InteractiveUtils | ||
| 400 | end | ||
| 401 | catch ex | ||
| 402 | @warn "Failed to import InteractiveUtils into module $mod" exception=(ex, catch_backtrace()) | ||
| 403 | end | ||
| 404 | return nothing | ||
| 405 | end | ||
| 406 | return getfield(mod, :InteractiveUtils) | ||
| 407 | end | ||
| 408 | |||
| 409 | global active_repl | ||
| 410 | |||
| 411 | # run the requested sort of evaluation loop on stdio | ||
| 412 | function run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool) | ||
| 413 | load_InteractiveUtils() | ||
| 414 | |||
| 415 | if interactive && isassigned(REPL_MODULE_REF) | ||
| 416 | 58 (100 %) |
58 (100 %)
samples spent calling
invokelatest
invokelatest(REPL_MODULE_REF[]) do REPL
|
|
| 417 | term_env = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb") | ||
| 418 | term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr) | ||
| 419 | banner && Base.banner(term) | ||
| 420 | if term.term_type == "dumb" | ||
| 421 | repl = REPL.BasicREPL(term) | ||
| 422 | quiet || @warn "Terminal not fully functional" | ||
| 423 | else | ||
| 424 | repl = REPL.LineEditREPL(term, get(stdout, :color, false), true) | ||
| 425 | repl.history_file = history_file | ||
| 426 | end | ||
| 427 | global active_repl = repl | ||
| 428 | # Make sure any displays pushed in .julia/config/startup.jl ends up above the | ||
| 429 | # REPLDisplay | ||
| 430 | pushdisplay(REPL.REPLDisplay(repl)) | ||
| 431 | _atreplinit(repl) | ||
| 432 | 58 (100 %) |
58 (100 %)
samples spent calling
run_repl
REPL.run_repl(repl, backend->(global active_repl_backend = backend))
|
|
| 433 | end | ||
| 434 | else | ||
| 435 | # otherwise provide a simple fallback | ||
| 436 | if interactive && !quiet | ||
| 437 | @warn "REPL provider not available: using basic fallback" | ||
| 438 | end | ||
| 439 | banner && Base.banner() | ||
| 440 | let input = stdin | ||
| 441 | if isa(input, File) || isa(input, IOStream) | ||
| 442 | # for files, we can slurp in the whole thing at once | ||
| 443 | ex = parse_input_line(read(input, String)) | ||
| 444 | if Meta.isexpr(ex, :toplevel) | ||
| 445 | # if we get back a list of statements, eval them sequentially | ||
| 446 | # as if we had parsed them sequentially | ||
| 447 | for stmt in ex.args | ||
| 448 | eval_user_input(stderr, stmt, true) | ||
| 449 | end | ||
| 450 | body = ex.args | ||
| 451 | else | ||
| 452 | eval_user_input(stderr, ex, true) | ||
| 453 | end | ||
| 454 | else | ||
| 455 | while isopen(input) || !eof(input) | ||
| 456 | if interactive | ||
| 457 | print("julia> ") | ||
| 458 | flush(stdout) | ||
| 459 | end | ||
| 460 | try | ||
| 461 | line = "" | ||
| 462 | ex = nothing | ||
| 463 | while !eof(input) | ||
| 464 | line *= readline(input, keep=true) | ||
| 465 | ex = parse_input_line(line) | ||
| 466 | if !(isa(ex, Expr) && ex.head === :incomplete) | ||
| 467 | break | ||
| 468 | end | ||
| 469 | end | ||
| 470 | eval_user_input(stderr, ex, true) | ||
| 471 | catch err | ||
| 472 | isa(err, InterruptException) ? print("\n\n") : rethrow() | ||
| 473 | end | ||
| 474 | end | ||
| 475 | end | ||
| 476 | end | ||
| 477 | end | ||
| 478 | nothing | ||
| 479 | end | ||
| 480 | |||
| 481 | # MainInclude exists to hide Main.include and eval from `names(Main)`. | ||
| 482 | baremodule MainInclude | ||
| 483 | using ..Base | ||
| 484 | # These definitions calls Base._include rather than Base.include to get | ||
| 485 | # one-frame stacktraces for the common case of using include(fname) in Main. | ||
| 486 | include(mapexpr::Function, fname::AbstractString) = Base._include(mapexpr, Main, fname) | ||
| 487 | function include(fname::AbstractString) | ||
| 488 | isa(fname, String) || (fname = Base.convert(String, fname)::String) | ||
| 489 | 58 (100 %) |
58 (100 %)
samples spent calling
_include
Base._include(identity, Main, fname)
|
|
| 490 | end | ||
| 491 | eval(x) = Core.eval(Main, x) | ||
| 492 | |||
| 493 | """ | ||
| 494 | ans | ||
| 495 | |||
| 496 | A variable referring to the last computed value, automatically imported to the interactive prompt. | ||
| 497 | """ | ||
| 498 | global ans = nothing | ||
| 499 | |||
| 500 | """ | ||
| 501 | err | ||
| 502 | |||
| 503 | A variable referring to the last thrown errors, automatically imported to the interactive prompt. | ||
| 504 | The thrown errors are collected in a stack of exceptions. | ||
| 505 | """ | ||
| 506 | global err = nothing | ||
| 507 | |||
| 508 | # weakly exposes ans and err variables to Main | ||
| 509 | export ans, err | ||
| 510 | |||
| 511 | end | ||
| 512 | |||
| 513 | """ | ||
| 514 | eval(expr) | ||
| 515 | |||
| 516 | Evaluate an expression in the global scope of the containing module. | ||
| 517 | Every `Module` (except those defined with `baremodule`) has its own 1-argument | ||
| 518 | definition of `eval`, which evaluates expressions in that module. | ||
| 519 | """ | ||
| 520 | MainInclude.eval | ||
| 521 | |||
| 522 | """ | ||
| 523 | include([mapexpr::Function,] path::AbstractString) | ||
| 524 | |||
| 525 | Evaluate the contents of the input source file in the global scope of the containing module. | ||
| 526 | Every module (except those defined with `baremodule`) has its own | ||
| 527 | definition of `include`, which evaluates the file in that module. | ||
| 528 | Returns the result of the last evaluated expression of the input file. During including, | ||
| 529 | a task-local include path is set to the directory containing the file. Nested calls to | ||
| 530 | `include` will search relative to that path. This function is typically used to load source | ||
| 531 | interactively, or to combine files in packages that are broken into multiple source files. | ||
| 532 | The argument `path` is normalized using [`normpath`](@ref) which will resolve | ||
| 533 | relative path tokens such as `..` and convert `/` to the appropriate path separator. | ||
| 534 | |||
| 535 | The optional first argument `mapexpr` can be used to transform the included code before | ||
| 536 | it is evaluated: for each parsed expression `expr` in `path`, the `include` function | ||
| 537 | actually evaluates `mapexpr(expr)`. If it is omitted, `mapexpr` defaults to [`identity`](@ref). | ||
| 538 | |||
| 539 | Use [`Base.include`](@ref) to evaluate a file into another module. | ||
| 540 | |||
| 541 | !!! compat "Julia 1.5" | ||
| 542 | Julia 1.5 is required for passing the `mapexpr` argument. | ||
| 543 | """ | ||
| 544 | MainInclude.include | ||
| 545 | |||
| 546 | function _start() | ||
| 547 | empty!(ARGS) | ||
| 548 | append!(ARGS, Core.ARGS) | ||
| 549 | # clear any postoutput hooks that were saved in the sysimage | ||
| 550 | empty!(Base.postoutput_hooks) | ||
| 551 | try | ||
| 552 | 58 (100 %) |
58 (100 %)
samples spent calling
exec_options
exec_options(JLOptions())
|
|
| 553 | catch | ||
| 554 | invokelatest(display_error, scrub_repl_backtrace(current_exceptions())) | ||
| 555 | exit(1) | ||
| 556 | end | ||
| 557 | if is_interactive && get(stdout, :color, false) | ||
| 558 | print(color_normal) | ||
| 559 | end | ||
| 560 | end |