expand_variables() is slightly confused about how to handle last_idx. On
input, it expects it to be the index to start processing at, but when
called recursively it always passes the current index. This means that
it may sometimes pass an index 1 past the end of the input string.
Notably, that happens when typing something like
> echo "$foo
(where "foo" is any string that is not a prefix of some existing
variable name)
Fix this by explicitly defining last_idx as being the last processed
index, meaning the next index to process is actually last_idx-1. This
means we should call it with next.size() instead of next.size()-1.
The span now properly points at the token that was invalid, rather than
the start of the slice.
Also fix the span for `()[1]` and `()[d]`, which were previously
reporting no source location at all.
When a variable is parsed as being empty, parse out the slice and
validate the indexes anyway, behaving for slicing purposes as if the
variable had a single empty value.
Besides providing errors when expected, this also fixes the following:
set -l foo
echo "$foo[1]"
This used to print "[1]", now it properly prints nothing.
Double expansions of variables had the following issues:
* `"$$foo"` threw an error no matter what the value of `$foo` was.
* `set -l foo ''; echo $$foo` threw an error because of the expansion of
`$foo` to `''`.
With this change, double expansion always works properly. When
double-expanding a multi-valued variable, in a double-quoted string the
first word of the inner expansion is used for the outer expansion, and
outside of a quoted string every word is used for the double-expansion
in each of the arguments.
> set -l foo bar baz
> set -l bar one two
> set -l baz three four
> echo "$$foo"
one two baz
> echo $$foo
one two three four
parse_error_list_t through all of the expand functions, enabling them to
report errors more directly. Improve aspects of error reporting for
expansion failures.
Conditionally uninitialized:
- builtin_commandline.cpp:577
- expand.cpp:869
- parse_util.cpp:1036
Initialization of POD structs:
- event.cpp:61
- autoload.cpp:22
References used with va_start:
- common.cpp:608:18
Found with clang-3.4's awesome -Wconditional-uninitialized,
-Wmissing-field-initializers and -Wvarargs.
1. Use Bash-like expansion for empty searches (when you just use a '%' by
itself).
'%' will now *only* match the last valid backgrounded process.
If there are no such processes, an expansion error will be generated.
'%' by itself would previously match either *all* backgrounded
processes, or failing that, all processes owned by your user. If you
ever tried to run `kill -9 %`, it would either kill all backgrounded
processes or *all* of your processes. I'm not sure why anyone would ever
want that to be a single keystroke away. You could almost typo it.
As a result, `fg %`, `bg %`, `kill %`, etc will all operate on the last
process touched by job control.
2. Don't run 'by-name' matches when the search term is numeric.
This prevents you from running a command like `kill %1` and accidentally
killing a process named something like "1Command". Overloaded behavior
can be dangerous, and we probably shouldn't play fast and loose with
expansion characters that generate process IDs.