That is, return ErrorOr<int>, handle fallible ops with TRY() and accept
a Main::Arguments.
Note that we do not populate the argc/argv members of Main::Arguments,
so all accesses have to go through .strings.
Note that the default shellrc is most likely not valid posix sh code, so
passing --skip-shellrc is suggested until we come up with a separate
shellrc file for the POSIX parser to use when interactive.
The parser is still very much a work-in-progress, but it can currently
parse most of the basic bits, the only *completely* unimplemented things
in the parser are:
- heredocs (io_here)
- alias expansion
- arithmetic expansion
There are a whole suite of bugs, and syntax highlighting is unreliable
at best.
For now, this is not attached anywhere, a future commit will enable it
for /bin/sh or a `Shell --posix` invocation.
Having an alias function that only wraps another one is silly, and
keeping the more obvious name should flush out more uses of deprecated
strings.
No behavior change.
We changed elapsed() to return i64 instead of int as that's what
AK::Time::to_milliseconds() returns, causing a bunch of implicit lossy
conversions in callers. Clean those up with a mix of type changes and
casts.
In 7c5e30daaa, the focus was "only" on
Userland/Libraries/, whereas this commit cleans up the remaining
headers in the repo, and any new badly-formatted include.
The builtin is based on the behaviour of the z-shell.
Namely it tries to resolve every argument one by one.
When resolving (in the order below) the following results can occur:
1. The argument is a shell built-in command. Then print it.
2. The argument is an alias. In this case we print the mapped value.
3. The argument was found in the `PATH` environment variable.
In this case we print the resolved absolute path
and try to find more occurences in the `PATH` environment variable.
4. None of the above. If no earlier argument got resolved,
we print the error `{argument} not found`.
If at least one argument got resolved we exit with exit code 0,
otherwise 1.
By not using Core::File to resolve the executable in the environment
but rather using a modified version of the code we print every
matching executable of the given name. This behaviour matches
up with the z-shell.
The builtin has the following flags to modify the behaviour according
to the users needs:
- `-p --path-only`: This skips the built-in and alias checks
(step 1 & 2)
- `-s --follow-symlink`: This follows the symlinks of an executable to
its symlink-free location.
- `-w --type`: This displays the type of the found object
without any additional descriptive information.
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.
One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
Otherwise, we end up propagating those dependencies into targets that
link against that library, which creates unnecessary link-time
dependencies.
Also included are changes to readd now missing dependencies to tools
that actually need them.
Also do this for Shell.
This greatly simplifies the CMakeLists in Lagom, replacing many glob
patterns with a big list of libraries. There are still a few special
libraries that need some help to conform to the pattern, like LibELF and
LibWebView.
It also lets us remove essentially all of the Serenity or Lagom binary
directory detection logic from code generators, as now both projects
directories enter the generator logic from the same place.
URL had properly named replacements for protocol(), set_protocol() and
create_with_file_protocol() already. This patch removes these function
and updates all call sites to use the functions named according to the
specification.
See https://url.spec.whatwg.org/#concept-url-scheme
This was present in Vector already. Clang-format fixed some const
positions automatically too.
Also removed a now-ambiguous and unnecessary constructor from Shell.
We previously had at least three different implementations for resolving
executables in the PATH, all of which had slightly different
characteristics.
Merge those into a single implementation to keep the behaviour
consistent, and maybe to make that implementation more configurable in
the future.
When |& is typed, stderr will be piped to stdout before the actual
piping happens. This behaves basically like a 2>&1 | (and the
underlying implementation transforms it to that anyway).
Replacement conditions for `requires_argument` have been chosen based
on what would be most convenient for implementing an eventual optional
argument mode.
This prevents us from needing a sv suffix, and potentially reduces the
need to run generic code for a single character (as contains,
starts_with, ends_with etc. for a char will be just a length and
equality check).
No functional changes.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
This commit moves the length calculations out to be directly on the
StringView users. This is an important step towards the goal of removing
StringView(char const*), as it moves the responsibility of calculating
the size of the string to the user of the StringView (which will prevent
naive uses causing OOB access).
StringView was used where possible. Some utilities still use libc
functions which expect null-terminated strings, so String objects were
used there instead.
The lazy resolution mechanism made it so that the variables were linked
together, causing unexpected behaviour:
true
x=$? # expected: x=0
false
echo $x # expected: 0, actual: 1
This moves all code comprehension-related code to a new library,
LibCodeComprehension.
This also moves some types related to code comprehension tasks (such as
autocomplete, find declaration) out of LibGUI and into
LibCodeComprehension.
31ca48e made this default to paths, but now that we have a few sensible
ways to complete things, let's make those work too.
For instance, prior to this `kill <tab>` would've suggested paths, but
now it will suggest processes.
Setting 'allow_commit_without_listing' to false will now make LibLine
show the suggestion before actually committing to it; this is useful for
completions that will replace all the user input, where mistakes can go
unnoticed without some visual cue.
Now that we can resolve these correctly and they're per-suggestion, we
can finally use them for their intended purpose of letting suggestions
overwrite stuff in the buffer.
The shell now expects a JSON object of the form {"kind":<kind>,...} per
line in the standard output of the completion process, where 'kind' is
one of:
- "plain": Just a plain suggestion.
- "program": Prompts the shell to complete a program name starting with
the given "name".
- "proxy": Prompts the shell to act as if a completion for "argv" was
requested.
- "path": Prompts the shell to complete a path given the "base" and
"part" (same as completing part in cwd=base).
We previously allowed globs as match pattern, but for more complex
matching needs, it's nice to have regular expressions.
And as the existing "name a part of the match" concept maps nicely to
named capture groups, we can simply reuse the same code and make groups
with names available in the match body.
For example, when typing `cd <tab>`, the shell will show a list of
files in the current directory. This behavior is similar to typing `cd
./<tab>`.
It makes it easier to `cd` into directories without having to list them
first.
This saves work in places that previously had to create a
`Vector<String>` anyway, or repeatedly cast the char* to a String.
Plus, Strings are nicer than char*. :^)
This feature needs a bit more work, so let's disable it by default.
Note that the shell will still use _complete_foo if it is defined
regardless of this setting.
This commit limits the autocomplete processes to effectively have
readonly access to the fs, and only enough pledges to get the dynamic
loader working.
A program can either respond to `--complete -- some args to complete`
directly, or add a `_complete_<program name>` invokable (i.e. shell
function, or just a plain binary in PATH) that completes the given
command and lists the completions on stdout.
Should such a completion fail or yield no results, we'll fall back to
the previous completion algorithm.
Shell can now use LibLine's `on_paste` hook to more intelligently escape
pasted data, with the following heuristics:
- If the current command is invalid, just pile the pasted string on top
- If the cursor is *after* a command node, escape the pasted data,
whichever way yields a smaller encoding
- If the cursor is at the start of or in the middle of a command name,
paste the data as-is, assuming that the user wants to paste code
- If the cursor is otherwise in some argument, escape the pasted data
according to which kind of string the cursor is in the middle of
(double-quoted, single-quoted or a simple bareword)
Previously would show the list of history items starting from
an index of 0.
This is a bit misleading though. Running `!0` would actually cause
the parser to error out and prevent you from running the command.
The "at most n bytes" behaviour of strncmp is required for this logic to
work, this was overlooked in 5b64abe when converting Strings to
StringViews, which lead to broken autocomplete.
Apologies for the enormous commit, but I don't see a way to split this
up nicely. In the vast majority of cases it's a simple change. A few
extra places can use TRY instead of manual error checking though. :^)
This makes interrupting `sleep 10; echo hi` not print `hi` anymore,
which is the expected behaviour anyway.
Also fixes the problem with fast-running loops "eating" interrupts and
not quitting.
Before this patch, `which ""` or `type ""` would say that the empty
string is `/usr/local/bin/`.
Convert callers to consistently call is_empty() on the returned string
while we're at it, to support eventually removing the is_null() String
state in the future.
Naturally, this means that a command with a failing redirection will
not start, and so will terminate the pipeline (if any).
This also applies to the `exit` run when the shell is closed, fixing a
fun bug there as well (thanks to Discord user Salanty for pointing that
out) where closing the terminal (i.e. I/O error on the tty) with a
failing `exit` command would make the shell retry executing `exit` every
time, leading to an eventual stack overflow.
Whenever the prompt is printed, we write a line's worth of space
characters to the terminal to ensure that the prompt ends up on a new
line even if there is dangling output on the current line.
We write these to the stderr, which is unbuffered, so each putc() call
would come with the overhead of a system call. Let's use a buffer
+ fwrite() instead, since heap allocation is much faster.
Previously we were simply ignoring the empty entry in '{,x}', making it
resolve to a list with a single element '(x)', this commit makes that
work as expected and resolve to '("" x)'.
This option is already enabled when building Lagom, so let's enable it
for the main build too. We will no longer be surprised by Lagom Clang
CI builds failing while everything compiles locally.
Furthermore, the stronger `-Wsuggest-override` warning is enabled in
this commit, which enforces the use of the `override` keyword in all
classes, not just those which already have some methods marked as
`override`. This works with both GCC and Clang.
This isn't a complete conversion to ErrorOr<void>, but a good chunk.
The end goal here is to propagate buffer allocation failures to the
caller, and allow the use of TRY() with formatting functions.
This commit makes the Shell check for errors after a node is run(), and
prevents further execution by unwinding until the error is cleared.
Fixes#10649.
When parse_expression looks at '$((', there are two ways it can end up
in parse_expression again, three consumed characters later. All these
ways fail, so what happened was that the parser tried all possible
combinations, hence taking potentially an exponential amount of time.
1. parse_evaluate swallows the '$(', a new invocation of
parse_expression swallows the other '(', and through
parse_list_expression we're at another parse_expression.
2. parse_evaluate swallows the '$(', but returns a SyntaxError.
parse_expression used to not recognize the error, and treated it as a
regular AST node, calling into read_concat, then a new invocation of
parse_expression swallows the other '(', and through
parse_list_expression we're at another parse_expression.
Fixes#10561.
Found by OSS Fuzz, long-standing issue
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28113
...while capturing its standard output.
As `$()` is an invalid construct, execute nodes are not supposed to
capture the output of no command being run; but it is possible to create
empty commands such as CastToCommand(Redirection(...)) or similar.
Make this a hard error instead of an unescapable select().
This was noticed in #10432, which should now error out like so:
```
Error: Cannot capture standard output when no command is being executed
0| $(<$file)
~~~~~^^^^^^^^^
1|
```
Our existing implementation did not check the element type of the other
pointer in the constructors and move assignment operators. This meant
that some operations that would require explicit casting on raw pointers
were done implicitly, such as:
- downcasting a base class to a derived class (e.g. `Kernel::Inode` =>
`Kernel::ProcFSDirectoryInode` in Kernel/ProcFS.cpp),
- casting to an unrelated type (e.g. `Promise<bool>` => `Promise<Empty>`
in LibIMAP/Client.cpp)
This, of course, allows gross violations of the type system, and makes
the need to type-check less obvious before downcasting. Luckily, while
adding the `static_ptr_cast`s, only two truly incorrect usages were
found; in the other instances, our casts just needed to be made
explicit.
And also try_create<T> => try_make_ref_counted<T>.
A global "create" was a bit much. The new name matches make<T> better,
which we've used for making single-owner objects since forever.
Only one place used this argument and it was to hold on to a strong ref
for the object. Since we already do that now, there's no need to keep
this argument around since this can be easily captured.
This commit contains no changes.
The new Statistics utility is now used when calling 'time -n' to get
some more information of the timings. For now only the standard
deviation is given in addition to the average.
This commit completely undos #9645 because everything that touched moved
into AK::Statistics.
This kinda sorta addresses the Shell side of #9655, however the fact
that `chdir` (and most other syscalls that take paths) are artifically
limited to a length of PATH_MAX remains.
You can now specify a number of iterations when timing a command.
The default value is 1 and behaves exactly as before.
If the iteration count is greater than 1, the command will be executed
that many times, and then you get a little timing report afterwards with
the average runtime per iteration, and also the average runtime
excluding the very first iteration. (Excluding the first iteration is
useful when it's slowed down by cold caches, etc.)
This is something I've been doing manually forever (running `time foo`
and then eyeballing the results to headmath an average) and this makes
that whole process so much nicer. :^)
This is primarily to be able to remove the GenericLexer include out of
Format.h as well. A subsequent commit will add AK::Result to
GenericLexer, which will cause naming conflicts with other structures
named Result. This can be avoided (for now) by preventing nearly every
file in the system from implicitly including GenericLexer.
Other changes in this commit are to add the GenericLexer include to
files where it is missing.
Heredocs have a different parse end condition than double-quoted
strings. parse_doublequoted_string_inner would assume that a string
would always end in a double quote, so let's generalize it to
parse_string_inner and have it take a StringEndCondition enum which
specifies how the string terminates.
That can happen because of anyone sending the process a SIGCONT.
Fixes an issue where continuing a process launched by the shell from
the System Monitor would cause the shell to spin on waitpid().
Since this is always set to true on the non-default constructor and
subsequently never modified, it is somewhat pointless. Furthermore,
there are arguably no invalid relative paths.
This will cause a problem when `NonnullRefPtr<T>::operator T*` will be
declared as RETURNS_NONNULL. Clang emits a warning for this pointless
null check, which breaks CI.
This commit converts naked `new`s to `AK::try_make` and `AK::try_create`
wherever possible. If the called constructor is private, this can not be
done, so we instead now use the standard-defined and compiler-agnostic
`new (nothrow)`.
This is so they can find their associated resources and it's
the same behavior as in Lagom.
This also required changing some tests so that they could
write their resources in a writable location.
Some of the code assumed that chars were always signed while that is
not the case on ARM hosts.
Also, some of the code tried to use EOF (-1) in a way similar to what
fgetc() does, however instead of storing the characters in an int
variable a char was used.
While this seemed to work it also meant that character 0xFF would be
incorrectly seen as an end-of-file.
Careful reading of fgetc() reveals that fgetc() stores character
data in an int where valid characters are in the range of 0-255 and
the EOF value is explicitly outside of that range (usually -1).