Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add support for determining name of script #14114

Merged
merged 1 commit into from
Jan 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to run julia doc/NEWS-update.jl to update the cross-reference links.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Is there some Julia contribution documentation that mentions this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it isn't mentioned somewhere in CONTRIBUTING.md it probably should be

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I just noticed that this was accidentally added to the Julia 0.4 NEWS, not the Julia 0.5 NEWS...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 47c29a9


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