Skip to content

Commit

Permalink
Add support for determining name of script #14109
Browse files Browse the repository at this point in the history
Note that PROGRAM_FILE was chosen as the name for this variable as it
matches the help for the Julia CLI.
  • Loading branch information
omus committed Jan 27, 2016
1 parent 5ac7f75 commit ffb3458
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 23 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ New language features

* `@__LINE__` special macro now available to reflect invocation source line number ([#12727]).

* `PROGRAM_FILE` global is now available for determining the name of the running script ([#14114]).

Language changes
----------------

Expand Down Expand Up @@ -1768,3 +1770,4 @@ Too numerous to mention.
[#14413]: https://github.com/JuliaLang/julia/issues/14413
[#14424]: https://github.com/JuliaLang/julia/issues/14424
[#14759]: https://github.com/JuliaLang/julia/issues/14759
[#14114]: https://github.com/JuliaLang/julia/issues/14114
15 changes: 7 additions & 8 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,9 @@ end
# try to include() a file, ignoring if not found
try_include(path::AbstractString) = isfile(path) && include(path)

function process_options(opts::JLOptions, args::Vector{UTF8String})
if !isempty(args)
arg = first(args)
idxs = find(x -> x == "--", args)
function process_options(opts::JLOptions)
if !isempty(ARGS)
idxs = find(x -> x == "--", ARGS)
if length(idxs) > 1
println(STDERR, "julia: redundant option terminator `--`")
exit(1)
Expand Down Expand Up @@ -234,15 +233,15 @@ function process_options(opts::JLOptions, args::Vector{UTF8String})
eval(Main, parse_input_line(bytestring(opts.postboot)))
end
# load file
if !isempty(args) && !isempty(args[1])
if !isempty(ARGS) && !isempty(ARGS[1])
# program
repl = false
# remove filename from ARGS
shift!(ARGS)
global PROGRAM_FILE = UTF8String(shift!(ARGS))
if !is_interactive
ccall(:jl_exit_on_sigint, Void, (Cint,), 1)
end
include(args[1])
include(PROGRAM_FILE)
end
break
end
Expand Down Expand Up @@ -298,7 +297,7 @@ function _start()
append!(ARGS, Core.ARGS)
opts = JLOptions()
try
(quiet,repl,startup,color_set,history_file) = process_options(opts,copy(ARGS))
(quiet,repl,startup,color_set,history_file) = process_options(opts)

local term
global active_repl
Expand Down
5 changes: 3 additions & 2 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8368,8 +8368,9 @@ graphemes
"""
@__FILE__ -> AbstractString
`@__FILE__` expands to a string with the absolute path and file name of the script being
run. Returns `nothing` if run from a REPL or an empty string if evaluated by `julia -e <expr>`.
`@__FILE__` expands to a string with the absolute file path of the file containing the
macro. Returns `nothing` if run from a REPL or an empty string if evaluated by
`julia -e <expr>`. Alternatively see [`PROGRAM_FILE`](:data:`PROGRAM_FILE`).
"""
:@__FILE__

Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export
JULIA_HOME,
LOAD_PATH,
OS_NAME,
PROGRAM_FILE,
STDERR,
STDIN,
STDOUT,
Expand Down
1 change: 1 addition & 0 deletions base/initdefs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## initdefs.jl - initialization and runtime management definitions

PROGRAM_FILE = UTF8String("")
const ARGS = UTF8String[]

exit(n) = ccall(:jl_exit, Void, (Int32,), n)
Expand Down
15 changes: 9 additions & 6 deletions doc/manual/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,22 @@ argument to the julia command::

As the example implies, the following command-line arguments to julia
are taken as command-line arguments to the program ``script.jl``, passed
in the global constant ``ARGS``. ``ARGS`` is also set when script code
is given using the ``-e`` option on the command line (see the ``julia``
help output below). For example, to just print the arguments given to a
script, you could do this::
in the global constant ``ARGS``. The name of the script itself is passed
in as the global ``PROGRAM_FILE``. Note that ``ARGS`` is also set when script
code is given using the ``-e`` option on the command line (see the ``julia``
help output below) but ``PROGRAM_FILE`` will be empty. For example, to just
print the arguments given to a script, you could do this::

$ julia -e 'println(PROGRAM_FILE); for x in ARGS; println(x); end' foo bar

$ julia -e 'for x in ARGS; println(x); end' foo bar
foo
bar

Or you could put that code into a script and run it::

$ echo 'for x in ARGS; println(x); end' > script.jl
$ echo 'println(PROGRAM_FILE); for x in ARGS; println(x); end' > script.jl
$ julia script.jl foo bar
script.jl
foo
bar

Expand Down
5 changes: 5 additions & 0 deletions doc/stdlib/constants.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Constants
A symbol representing the name of the operating system. Possible values
are ``:Linux``, ``:Darwin`` (OS X), or ``:Windows``.

.. data:: PROGRAM_FILE

A string containing the script name passed to Julia from the command line. Note that the
script name remains unchanged from within included files. Alternatively see :data:`@__FILE__`.

.. data:: ARGS

An array of the command line arguments passed to Julia, as strings.
Expand Down
2 changes: 1 addition & 1 deletion doc/stdlib/file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@

.. Docstring generated from Julia source
``@__FILE__`` expands to a string with the absolute path and file name of the script being run. Returns ``nothing`` if run from a REPL or an empty string if evaluated by ``julia -e <expr>``\ .
``@__FILE__`` expands to a string with the absolute file path of the file containing the macro. Returns ``nothing`` if run from a REPL or an empty string if evaluated by ``julia -e <expr>``. Alternatively see :data:`PROGRAM_FILE`.

.. function:: @__LINE__ -> Int

Expand Down
37 changes: 31 additions & 6 deletions test/cmdlineargs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -204,24 +204,49 @@ let exename = `$(joinpath(JULIA_HOME, Base.julia_exename())) --precompiled=yes`
# --worker takes default / custom as arugment (default/custom arguments tested in test/parallel.jl, test/examples.jl)
@test !success(`$exename --worker=true`)

escape(str) = replace(str, "\\", "\\\\")

# test passing arguments
let testfile = tempname()
try
# write a julia source file that just prints ARGS to STDOUT and exits
# write a julia source file that just prints ARGS to STDOUT
write(testfile, """
println(ARGS)
exit(0)
""")
@test readchomp(`$exename $testfile foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]"
@test readchomp(`$exename $testfile -- foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]"
@test readchomp(`$exename -L $testfile -- foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]"
@test readchomp(`$exename $testfile foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]"
@test readchomp(`$exename $testfile -- foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]"
@test readchomp(`$exename -L $testfile -e 'exit(0)' -- foo -bar --baz`) == "UTF8String[\"foo\",\"-bar\",\"--baz\"]"
@test split(readchomp(`$exename -L $testfile $testfile`), '\n') == ["UTF8String[\"$(escape(testfile))\"]", "UTF8String[]"]
@test !success(`$exename --foo $testfile`)
@test !success(`$exename -L $testfile -- foo -bar -- baz`)
@test !success(`$exename -L $testfile -e 'exit(0)' -- foo -bar -- baz`)
finally
rm(testfile)
end
end

# test the script name
let a = tempname(), b = tempname()
try
write(a, """
println(@__FILE__)
println(PROGRAM_FILE)
println(length(ARGS))
include(\"$(escape(b))\")
""")
write(b, """
println(@__FILE__)
println(PROGRAM_FILE)
println(length(ARGS))
""")
@test split(readchomp(`$exename $a`), '\n') == ["$a", "$a", "0", "$b", "$a", "0"]
@test split(readchomp(`$exename -L $b -e 'exit(0)'`), '\n') == ["$(realpath(b))", "", "0"]
@test split(readchomp(`$exename -L $b $a`), '\n') == ["$(realpath(b))", "", "1", "$a", "$a", "0", "$b", "$a", "0"]
finally
rm(a)
rm(b)
end
end

# issue #10562
@test readchomp(`$exename -e 'println(ARGS);' ''`) == "UTF8String[\"\"]"

Expand Down

0 comments on commit ffb3458

Please sign in to comment.