Commit Graph

167 Commits

Author SHA1 Message Date
ridiculousfish
60d439ab22 Rationalize fish_wcstoi/d and friends
Historically fish has used the functions `fish_wcstol`, `fish_wcstoi`, and
`fish_wcstoul` (and some long long variants) for most integer conversions.
These have semantics that are deliberately different from the libc
functions, such as consuming trailing whitespace, and disallowing `-` in
unsigned versions.

fish has started to drift away from these semantics; some divergence from
C++ has crept in.

Rename the existing `fish_wcs*` functions in Rust to remove the fish
prefix, to express that they attempt to mirror libc semantics; then
introduce `fish_` wrappers which are ported from C++. Also fix some
miscellaneous bugs which have crept in, such as missing range checks.
2023-05-14 18:03:52 -07:00
Johannes Altmanninger
33f51b45e4 Tease apart parser.eval() overloads
The most common overload takes a string and an io chain so let that one keep
its name.
2023-04-21 13:57:29 +02:00
Johannes Altmanninger
6ede7f8009 Delete wcstring_list_t
We don't want it in Rust. Remove it to smoothen the transition.
2023-04-19 01:03:16 +02:00
Clemens Wasser
3ae16a5b95 trace: Port trace to Rust 2023-03-28 20:11:42 -07:00
ridiculousfish
6ec35ce182 Reimplement termsize in Rust
This is not yet adopted by fish.
2023-03-19 16:13:41 -07:00
ridiculousfish
57f4571a01 Rewrite wait handles and wait handle store in Rust 2023-03-18 18:53:04 -07:00
Xiretza
9ac6cbefb1 Port event.cpp to rust
Port src/event.cpp to fish-rust/event.rs and some needed functions.

Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
2023-03-12 14:55:50 -05:00
Johannes Altmanninger
0410bacdf6 clang-format C++ files 2023-03-04 22:24:22 +01:00
Clemens Wasser
17c1fa9d64
Port bg builtin to Rust (#9621)
* bg: Port bg builtin to Rust
2023-02-28 16:42:12 -06:00
Clemens Wasser
6f5be9bae4 block: Port block builtin to Rust
Closes #9612.
2023-02-26 14:16:55 -06:00
Clemens Wasser
330e8a86c7 block: Use an integer to count blocks 2023-02-26 14:12:57 -06:00
Mahmoud Al-Qudsi
562eeac43e
Port job_group to rust (#9608)
More ugliness with types that cxx bridge can't recognize as being POD. Using
pointers to get/set `termios` values with an assert to make sure we're using
identical definitions on both sides (in cpp from the system headers and in rust
from the libc crate as exported).

I don't know why cxx bridge doesn't allow `SharedPtr<OpaqueRustType>` but we can
work around it in C++ by converting a `Box<T>` to a `shared_ptr<T>` then convert
it back when it needs to be destructed. I can't find a clean way of doing it
from the cxx bridge wrapper so for now it needs to be done manually in the C++
code.

Types/values that are drop-in ready over ffi are renamed to match the old cpp
names but for types that now differ due to ffi difficulties I've left the `_ffi`
in the function names to indicate that this isn't the "correct" way of using the
types/methods.
2023-02-25 16:42:45 -06:00
Neeraj Jaiswal
f52569a800 abbr: port abbreviation and abbr builtin to rust 2023-02-25 12:24:58 +01:00
Xiretza
77a474ee37 Move POD components of library_data_t to separate struct
This allows them to be accessed as regular fields from Rust, rather than having
to create setter/getter methods for each of them.
2023-02-20 11:32:12 +01:00
Neeraj Jaiswal
1adfce18ee builtins: port return/exit to rust 2023-02-18 18:53:40 +01:00
ridiculousfish
d843b67d2d Initial Rust commit 2023-02-02 19:34:47 -07:00
Aaron Gyes
daf5e11179 Spelling fixes
Found with scspell
2022-10-28 20:10:09 -07:00
Aaron Gyes
b2a4a50daf Run include-what-you-use 2022-10-26 19:58:40 -07:00
Mahmoud Al-Qudsi
7133285c88 Move parser status vars to their own struct
Instead of using an enum + array, just use a struct and drop the getter and
setter methods from `parser_t`.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
6ac18defd2 Add status current-commandline
Makes it possible to retrieve the currently executing command line as
opposed to the currently executing command (`status current-command`).

Closes #8905.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
e01eb2e615 Add proper way of storing value for status current-command
There should be no functional changes in this commit.

The global variable `$_` set in the parser variables by `reader.cpp` and
read by the `status` builtin was deprecated in fish 2.0 but kept around
internally because there's no good way to store/share/forward parser
variables.

A new enum is added that identifies the status variable and they are
stored in a private array in the parser. There is no need for
synchronization because they are only set during job init and never
thereafter. This is currently asserted via ASSERT_IS_MAIN_THREAD() but
that assert can be dropped in the interest of making the parser possible
to clone and use from worker threads.

The old `$_` global variable is still kept for backwards compatibility,
though it will be dropped in a future release.
2022-10-26 12:15:02 -05:00
Mahmoud Al-Qudsi
175caab583 Prevent stack overflow from eval/substitution recursion
It seems to have originally been thought that the only possible way a stack
overflow could happen is via function calls, but there are other possibilities.

Issue #9302 reports how `eval` can be abused to recursively execute a string
substitution ad infinitum, triggering a stack overflow in fish.

This patch extends the stack overflow check to also check the current
`eval_level` against a new constant `FISH_MAX_EVAL_DEPTH`, currently set to a
conservative but hopefully still fair limit of 500. For future reference, with
the default stack size for the main/foreground thread of 8 MiB, we actually have
room for a stack depth around 2800, but that's only with extremely minimal state
stored in each stack frame.

I'm not entirely sure why we don't check `eval_depth` regardless of block type;
it can't be for performance reasons since it's just a simple integer comparison
- and a ridiculously easily one for the branch predictor handle, at that - but
maybe it's to try and support non-recursive nested execution blocks of greater
than `FISH_MAX_STACK_DEPTH`? But even without recursion, the stack can still
overflow so may be we should just bump the limit up some (to 500 like the new
`FISH_MAX_EVAL_DEPTH`?) and check it all the time?

Closes #9302.
2022-10-25 13:40:21 -05:00
Mahmoud Al-Qudsi
e7bf98adc1 Make block_t moveable
The presence of the explicit constructor (even though it did nothing) prevented
the compiler from generating a move constructor for `block_t`.
2022-10-24 22:06:30 -05:00
Mahmoud Al-Qudsi
84b53b4cae Significantly reduce size of block_t
A `block_t` instance is allocated for each live block type in memory when
executing a script or snippet of fish code. While many of the items in a
`block_t` class are specific to a particular type of block, the overhead of
`maybe_t<event_t>` that's unused except in the relatively extremely rare case of
an event block is more significant than the rest, given that 88 out of the 216
bytes of a `block_t` are set aside for this field that is rarely used.

This patch reorders the `block_t` members by order of decreasing alignment,
bringing down the size to 208 bytes, then changes `maybe_t<event_t>` to
`shared_ptr<event_t>` instead of allocating room for the event on the stack.
This brings down the runtime memory size of a `block_t` to 136 bytes for a 37%
reduction in size.

I would like to investigate using inheritance and virtual methods to have a
`block_t` only include the values that actually make sense for the block rather
than always allocating some sort of storage for them and then only sometimes
using it. In addition to further reducing the memory, I think this could also be
a safer and saner approach overall, as it would make it very clear when and
where we can expect each block_type_type_t-dependent member to be present and
hold a value.
2022-10-24 21:04:17 -05:00
Aaron Gyes
14d2a6d8ff IWYU-guided #include rejiggering.
Let's hope this doesn't causes build failures for e.g. musl: I just
know it's good on macOS and our Linux CI.

It's been a long time.

One fix this brings, is I discovered we #include assert.h or cassert
in a lot of places. If those ever happen to be in a file that doesn't
include common.h, or we are before common.h gets included, we're
unawaringly working with the system 'assert' macro again, which
may get disabled for debug builds or at least has different
behavior on crash. We undef 'assert' and redefine it in common.h.

Those were all eliminated, except in one catch-22 spot for
maybe.h: it can't include common.h. A fix might be to
make a fish_assert.h that *usually* common.h exports.
2022-08-20 23:55:18 -07:00
ridiculousfish
082f074bb1 Switch filenames from intern'd strings to shared_ptr
We store filenames in function definitions to indicate where the
function comes from. Previously these were intern'd strings. Switch them
to a shared_ptr<wcstring>, intending to remove intern'd strings.
2022-08-13 12:51:36 -07:00
ridiculousfish
0230420983 Stop initializing principal parser at global scope
Avoid the risk of global constructors by making this a function-level
static.
2022-06-20 12:31:36 -07:00
ridiculousfish
50f6b06251 Replace a bunch of ASSERT_IS_MAIN_THREAD
Switch these to a new function parser.assert_can_execute(), in
preparation for allowing execution off of the main thread.
2022-06-20 12:31:36 -07:00
ridiculousfish
f45e16e59d Try to rationalize universal variable syncing
Prior to this commit, setting a universal variable may trigger syncing
against the file which will modify other universal variables. But if we
want to support multiple environments we need the parser to decide when to
sync uvars. Shift the decision of when to sync to the parser itself. When a
universal variable is modified, now we just set a flag and it's up to the
(main) parser when to pick it up. This is hopefully just a refactoring with
no user-visible changes.
2022-05-30 14:09:06 -07:00
Aaron Gyes
0118eafee1 Remove unused functions, members (and a variable)
If we ever need any of these... they're in this commit:

fish_wcswidth_visible()
status_cmd_opts_t::feature_name
completion_t::is_naturally_less_than()
parser_t::set_empty_var_and_fire()
parser_t::get_block_desc()
parser_keywords_skip_arguments()
parser_keywords_is_block()
job_t::has_internal_proc()
fish_wcswidth_visible()
2022-04-09 10:10:44 -07:00
ridiculousfish
ac888ac6af Migrate 'within_fish_init' to a parser-local variable
We need special handling when reporting backtraces for commands run
during startup, i.e. config.fish. Previously we had a global variable;
make it local to the parser to eliminate a global.

No functional change here.
2022-03-24 21:43:58 -07:00
ridiculousfish
1763e7d3bc Remove some dead code
These functions were unused.
2022-03-20 14:48:44 -07:00
ridiculousfish
0c06ca3c3f Mark parser_t::principal as const 2021-09-24 21:09:28 -07:00
Rosen Penev
90f006b1cd clang-tidy: use delete
The clang warning for pending_signals_t was about the operator=
return type being wrong (misc-unconventional-assign-operator).

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-20 01:33:33 +02:00
ridiculousfish
2ca66cff53 Disable job control inside command substitutions
This disables job control inside command substitutions. Prior to this
change, a cmdsub might get its own process group. This caused it to fail
to cancel loops properly. For example:

    while true ; echo (sleep 5) ; end

could not be control-C cancelled, because the signal would go to sleep,
and so the loop would continue on. The simplest way to fix this is to
match other shells and not use job control in cmdsubs.

Related is #1362
2021-08-18 22:20:03 +08:00
ridiculousfish
32e23c84f4 Clean up parser_t::push_block
Fix some unnecessary copying and unused variables.
2021-07-28 15:37:34 -07:00
ridiculousfish
789261a40c Stop storing is_breakpoint inside the parser
This can also be trivially computed from the block list.
2021-07-28 13:56:33 -07:00
ridiculousfish
b914c94cc1 Stop storing 'is_block' inside the parser
is_block is a field which supports 'status is-block', and also controls
whether notifications get posted. However there is no reason to store
this as a distinct field since it is trivially computed from the block
list. Stop storing it. No functional changes in this commit.
2021-07-28 13:56:33 -07:00
ridiculousfish
938879a85a Remove a stale comment and add a missing initializer 2021-07-23 11:22:45 -07:00
ridiculousfish
ccd1b4e4f4 Clean up of get_function_name
Have it return a real string, instead of a pointer with uncertain
lifetime.
2021-07-15 11:36:43 -07:00
ridiculousfish
bad1b84513 Remove the index parameter from parser_t::is_function
It was always 0 in practice.
2021-07-15 11:04:06 -07:00
ridiculousfish
82fd8fe9fb Refactor wait handles
In preparation for using wait handles in --on-process-exit events, factor
wait handles into their own wait handle store. Also switch them to
per-process instead of per-job, which is a simplification.
2021-05-17 15:25:21 -07:00
ridiculousfish
632e150152 Introduce notion of "wait handles"
This is preparing to address the problem where fish cannot wait on a
reaped job, because it only looks at the active job list. Introduce the
idea of a "wait handle," which is a thing that `wait` can use to check if
a job is finished. A job may produce its wait handle on demand, and
parser_t will save the wait handle from wait-able jobs at the point they
are reaped.

This change merely introduces the idea; the next change makes builtin_wait
start using it.
2021-05-15 20:20:50 -07:00
ridiculousfish
aeabc76b2e Use internal job ids in builtin_wait
This avoids any potential issues due to recycled job IDs.
No user visible change.
2021-05-13 12:11:00 -07:00
Fabian Homborg
594d51e7eb Add a separate --profile-startup option to profile startup
This goes to a separate file because that makes option parsing easier
and allows profiling both at the same time.

The "normal" profile now contains only the profile data of the actual
run, which is much more useful - you can now profile a function by
running

   fish -C 'source /path/to/thing' --profile /tmp/thefunction.prof -c 'thefunction'

and won't need to filter out extraneous information.
2021-01-29 20:46:34 +01:00
Johannes Altmanninger
45e7c709f4 Consolidate complete cycle detection and always report error on cycle
Detect recursive calls to builtin complete and the internal completion in
the same place.

In 0a0149cc2 (Prevent infinite recursion when completion wraps variable assignment)
we don't print an error when completing certain aliases like:

	alias vim "A=B vim"

But we also gave no completions.
We could make this case work, but I think that trying to salvage situations
like this one is way too complex. Instead, let the user know by printing an
error. Not sure if the style of the error fits.

We could add some heuristic to alias to not add --wraps in some cyclic cases.
2020-09-26 14:56:03 +02:00
Fabian Homborg
30b2dc2b97 Don't enqueue a repaint in the middle of one
This can easily lead to an infinite loop, if a variable handler
triggers a repaint and the variable is set in the prompt, e.g. some of
the git variables.

A simple way to reproduce:

    function fish_mode_prompt
        commandline -f repaint
    end

Repainting executes the mode prompt, which triggers a repaint, which
triggers the mode prompt, ....

So we just set a flag and check it.

Fixes #7324.
2020-09-11 19:23:26 +02:00
ridiculousfish
b0182183d4 Rework exit command
Prior to this fix, the `exit` command would set a global variable in the
reader, which parse_execution would check. However in concurrent mode you
may have multiple scripts being sourced at once, and 'exit' should only
apply to the current script.

Switch to using a variable in the parser's libdata instead.
2020-08-15 16:06:54 -07:00
Soumya
a2b2bcef6e Add a $status_generation variable that's incremented for each interactive command that produces a status.
This can be used to determine whether the previous command produced a real status, or just carried over the status from the command before it. Backgrounded commands and variable assignments will not increment status_generation, all other commands will.
2020-08-05 12:23:49 -07:00
ridiculousfish
bae64f8a8a Modest cleanup of profiling
This is a set of miscellaneous cleanup for profiling.

An errant newline has been removed from 'if' statement output, which got
introduced with the new ast.
Switch from storing unique_ptr to a deque, which allocates less.
Collapse "parse" and "exec" times into just a single value "duration". The
"parse" time no longer makes sense, as we now parse ahead of time.
2020-07-24 11:53:07 -07:00