Commit graph

620 commits

Author SHA1 Message Date
ridiculousfish
cc1e4b998a Remove some dead bridge code
This was obviated after the AST was ported to Rust.
2023-08-19 16:31:42 -07:00
Fabian Boehm
53a5ce52c5 Implement FLOGF formatting
Note: This *requires* an argument after the format string:

```rust
FLOGF!(debug, "foo");
```

won't compile. I think that's okay, because in that case you should
just use FLOG.

An alternative is to make it skip the sprintf.
2023-08-19 16:56:59 +02:00
Fabian Boehm
798d7427f7 Switch broken uses of FLOGF to FLOG
"FLOGF!" is supposed to treat its first argument as a format
string (but doesn't because that part isn't implemented currently).

That means running something like

```rust
FLOGF!(term_support, "curses var", var_name, "=", value);
```

That would rightly just print "curses var", ignoring the other
arguments.

By contrast, FLOG! is the literal "just join these as a string"
version.
2023-08-19 16:56:59 +02:00
Henrik Hørlück Berg
bc29b4aee1 Move edition and MSRV to workspace 2023-08-19 15:18:38 +02:00
Henrik Hørlück Berg
c23f419af1 Use the workspace from CMake
- Make CMake use the correct target-path
- Make build.rs use the correct target dir

Workspaces place it in the project root by default, the alternative to making
this change is to add a `.cargo/config.toml` file with

```toml
[build]
target-dir = "fish-rust/target"
```

Which I think is unnecessary, as we likely want to use the new location anyways.
2023-08-19 15:18:38 +02:00
Henrik Hørlück Berg
87df7b9adf Use a cargo workspace
- This allows running `cargo fmt/clippy/test/etc` from root
- Ideally the root should be the fish-rust package instead of being virtual, but
  that requires changed to CMake/Corrosion. This change should instead be
  completely compatible with our existing setup.
- This also means we will only have on `Cargo.lock` for all current and future
  crates.
2023-08-19 15:18:38 +02:00
Henrik Hørlück Berg
1fa56972b5 Fix clippy lint in widestring-suffix 2023-08-19 15:18:38 +02:00
Fabian Boehm
566123edc6
Port builtin count to rust (#9963)
* Port builtin count to rust

* Explicitly use wstring
2023-08-18 23:18:52 +02:00
Fabian Boehm
a29aa44183 functions: Fix command name
This was "function", needs to be "function*s*".

It was only an issue in the option parsing because we set cmd there
again instead of passing it. Maybe these should just be file-level constants?
2023-08-18 17:16:44 +02:00
Henrik Hørlück Berg
88da7121af Adopt appendln 2023-08-16 18:37:27 +02:00
Henrik Hørlück Berg
dceefcdaba Add an appenln method to output_stream_t
This is an alternative to the very common pattern of

```rust
streams.err.append(output);
streams.err.append1('\n');
```

Which has negative performance implications, see https://github.com/fish-shell/fish-shell/pull/9229

It takes `Into<WString>` to hopefully avoid allocating anew when the argument is
a WString with leftover capacity
2023-08-16 18:37:27 +02:00
ridiculousfish
d47b2a7e0b Refactor the killring to make it instanced
This improves test isolation.

Also standardize on the name "killring" instead of "kill list" and remove some
dead code.
2023-08-13 13:06:06 -07:00
ridiculousfish
2b25cd1654 Complete the transition of the kill ring and remove kill.cpp
This finishes off the transition of the kill ring from C++ to Rust, and removes
the C++ bits.
2023-08-13 13:06:06 -07:00
Fabian Boehm
995f12219b Use out_is_terminal
This removes some spurious unsafe and some imports.

Note: We don't use it in `test`, because that can be asked to check
arbitrary file descriptors, while this only checks stdout specifically.
2023-08-13 14:17:52 +02:00
Fabian Boehm
6489ef5ac0 Rewrite builtin functions in rust 2023-08-13 14:17:44 +02:00
Fabian Boehm
5e78cf8c41 Add io_streams_t::out_is_terminal()
This encapsulates a "is our output going to the terminal" check we do
in a few places - functions, type, set_color, possibly test
2023-08-13 14:17:44 +02:00
Fabian Boehm
b75f901376 Fix reformat_for_screen
This had an infinite loop because it had two checks broken
2023-08-13 14:17:44 +02:00
Fabian Boehm
ee8e790aa7 Fix event::print's header printing
Turns out doing `==` on Enums with values will do a deep comparison,
including the values.

So EventDescription::Signal(SIGTERM) is !=
EventDescription::Signal(SIGWINCH).

That's not what we want here, so this does a bit of a roundabout thing.
2023-08-13 14:17:44 +02:00
Fabian Boehm
4f86f303f5 Make functions for builtin functions public
event filter names, function::set_desc, common::reformat_for_screen

This is the first use for each
2023-08-13 14:17:44 +02:00
99jte
5b136d450f
Include the target of bad redirects in the error (#9947)
Fixes #8877
2023-08-13 14:01:32 +02:00
ridiculousfish
b2ff4d6bc0 Adopt Rust PosixSpawner
This removes the C++ posix_spawner_t, adopting the Rust implementation.
2023-08-12 17:15:21 -07:00
ridiculousfish
245f7db5b3 Port PosixSpawner to Rust
PosixSpawner is our wrapper around posix_spawn.
2023-08-12 16:59:38 -07:00
Fabian Boehm
27a11ef7fe builtin builtin: Print help if run without an action to do
Fixes #9942
2023-08-09 17:26:07 +02:00
Henrik Hørlück Berg
0844247b43 Prefer os-unix prelude over importing everything separately 2023-08-09 15:00:58 +02:00
Henrik Hørlück Berg
131e249b0c Adopt the builtin prelude 2023-08-09 15:00:58 +02:00
Henrik Hørlück Berg
773bafb7c7 Add a builtin prelude
- Most builtins share a lot of similar imports
2023-08-09 15:00:58 +02:00
Henrik Hørlück Berg
fae090ea67 Adopt the wchar prelude 2023-08-09 15:00:58 +02:00
Henrik Hørlück Berg
5d58652394 Add a wchar prelude
- This will hopefully make it easier to always include WExt and ToWString, and
  make using WStr/WString more natural
2023-08-09 15:00:58 +02:00
Henrik Hørlück Berg
3a484480bf Remove premature optimization
The `impl<T> Hash for &T` hashes the string itself[^1].
It is unclear if that is actually faster than just calling `keyfunc` multiple times (they should all be linear).
For context, Rust by default uses SipHash 1-3 db1b1919ba
An alternative would be to store it as raw pointers aka `*const T`, which have a cheaper hash impl.
That has a more complicated implementation + removes lifetimes.

This commit rather removes the premature optimization.

[^1]: Source: https://doc.rust-lang.org/std/ptr/fn.hash.html
2023-08-07 21:01:11 -07:00
Henrik Hørlück Berg
4a4171c34a Forward some error messages and fix a bug
- The Err-variants will be used by e.g. wildcard, so might as well change it
  now.
- `create_directory` should now not infinitely loop until  it fails with an
  error message that isn't `EAGAIN`
2023-08-07 21:01:11 -07:00
Henrik Hørlück Berg
f4a5de1fbf Port builtins/path to Rust 2023-08-07 21:01:11 -07:00
ridiculousfish
2d779fb194 Fix additional clippy lint errors
These lint errors appear new with clippy 0.1.72.
2023-08-05 17:29:53 -07:00
ridiculousfish
8771d8f903 Remove some pub(self)s
This fixes a clippy 0.1.72 lint
2023-08-05 15:50:07 -07:00
Henrik Hørlück Berg
900a048744 Don't segfault if user has an invalid locale
Fixes #9928
2023-08-03 19:55:05 +02:00
Fabian Boehm
5de19d2e84 Remove broken &
Fixes the build
2023-08-02 21:21:46 +02:00
David Adam
35aa7636eb fds: add make_fd_{,non}blocking implementations in Rust 2023-08-01 22:56:25 +08:00
David Adam
0b291355b2 wutil: add perror implementation that takes an io::Error 2023-08-01 22:56:25 +08:00
Henrik Hørlück Berg
2ec36338f2 Very minor leftover codereview var-renaming 2023-07-27 22:00:03 -07:00
Henrik Hørlück Berg
cdc08dbb71 Add back well-backed comment
- The dermination is from commit 7988cff6bd
- See PR https://github.com/fish-shell/fish-shell/pull/9139
2023-07-27 22:00:03 -07:00
Henrik Hørlück Berg
6dd2cd2b20 Fix behaviour in the presence of non-visible width
Padding with an unprintable character is now disallowed, like it was for other
zero-length characters.

`string shorten` now ignores escape sequences and non-printable characters
when calculating the visible width of the ellipsis used (except for `\b`,
which is treated as a width of -1).
Previously `fish_wcswidth` returned a length of -1 when the ellipsis-str
contained any non-printable character, causing the command to poentially
print a larger width than expected.

This also fixes an integer overflows in `string shorten`'s
`max` and `max2`, when the cumulative sum of character widths turned negative
(e.g. with any non-printable characters, or `\b` after the changes above).
The overflow potentially caused strings containing non-printable characters
to be truncated.

This adds test that verify the fixed behaviour.
2023-07-27 22:00:03 -07:00
Henrik Hørlück Berg
20be990fd9 Port builtins/string to Rust
- Add test to verify piped string replace exit code

Ensure fields parsing error messages are the same.

Note: C++ relied upon the value of the parsed value even when `errno` was set,
that is defined behaviour we should not rely on, and cannot easilt be replicated from Rust.
Therefore the Rust version will change the following error behaviour from:

```shell
> string split --fields=a "" abc
string split: Invalid fields value 'a'
> string split --fields=1a "" abc
string split: 1a: invalid integer
```

To:

```shell
> string split --fields=a "" abc
string split: a: invalid integer
> string split --fields=1a "" abc
string split: 1a: invalid integer
```
2023-07-27 22:00:03 -07:00
ridiculousfish
ade6650599 Remove FunctionPropertiesRef type alias
Per code review, this type alias was confusing.
2023-07-23 17:18:36 -07:00
ridiculousfish
e24a16bd31 function: make inherit_vars a boxed slice instead of a hash map
Empty hash maps muck around with TLS. Per code review, use a boxed slice
of a tuple instead. This has the nice benefit of printing inherited vars
in sorted order.
2023-07-23 17:18:36 -07:00
ridiculousfish
a672edc0d5 Adopt the new function store and rewrite builtin_function
This adopts the new function store, replacing the C++ version.

It also reimplements builtin_function in Rust, as these was too coupled to
the function store to handle in a separate commit.
2023-07-23 17:18:36 -07:00
ridiculousfish
076f317c31 Implement (but do not yet adopt) fish function store in Rust
This reimplements the function module in Rust. The function module stores the
global set of fish functions, and provides information about them.
2023-07-23 17:18:36 -07:00
ridiculousfish
2a13a30807 Clean up DirIter
DirIter had a serious bug where it would crash on an invalid path. Make it more
robust and rationalize its error handling. Move it into its own module and add
tests.
2023-07-16 12:05:29 -07:00
ridiculousfish
f5e5896c70 Remove the EventDescription wrapper type
Prior to this change, we had a silly wrapper type EventDescription which wrapped
EventType, which actually described the event.

Remove this wrapper and rename EventType to EventDescription (since it describes
more than just the type of event).
2023-07-15 11:59:08 -07:00
ridiculousfish
ecfabf4db8 argparse: Use a named constant for RETURN_IN_ORDER returns
The RETURN_IN_ORDER argparse mode (enabled via leading '-') causes non-options
(i.e. positionals) to be returned intermixed with options in the original order,
instead of being permuted to the end. Such positionals are identified via the
option sentinel of char code 1. Use a real named constant for this return,
rather than weird stuff like '\u{1}'
2023-07-15 11:35:13 -07:00
Henrik Hørlück Berg
63b23713f2 Support thread-safe feature-flag-dependant tests
This also allows scoped feature tests that makes testing feature flags thread-safe.
As in you can guarantee that the test actually has the correct feature flag
value, regardless of which other tests are running in parallell.
2023-07-11 12:05:38 -07:00
Henrik Hørlück Berg
f1cd43d58b Disallow using set outside of tests, minor fixes 2023-07-11 12:05:38 -07:00
Henrik Hørlück Berg
726819e8ee Clean up feature flags API
This also cleans up and removes unnecessary usage of FFI-oriented `feature_metadata_t`,
which is only used from Rust code after `builtins/status` was ported.
2023-07-11 12:05:38 -07:00
ridiculousfish
57afaf7fb2 Restore the behavior of remembering the CWD fd in the parser
This will be important for concurrent execution, because different parsers will
have different working directories.
2023-07-10 21:30:37 +08:00
David Adam
289fbecaa9 Rewrite cd builtin in Rust
Note this is slightly incomplete - the FD is not moved into the parser, and so
will be freed at the end of each directory change. The FD saved in the parser is
never actually used in existing code, so this doesn't break anything, but will
need to be corrected once the parser is ported.
2023-07-10 21:30:37 +08:00
ridiculousfish
c1e1efd747 Pull an allocation out of the string escape test inner loop 2023-07-08 11:26:32 -07:00
ridiculousfish
98d88e06ff Use setlocale() in the test_convert test
This "fixes" (or at least hides) the intermittent test_convert failures,
as we no longer race with other setlocale calls.
2023-07-08 11:22:47 -07:00
ridiculousfish
a99fa201b6 Make escape_test an ordinary function
This did not need to be a macro.
2023-07-08 11:19:44 -07:00
Henrik Hørlück Berg
7b0f9fd5f8 Double the speed of cargo test, actually run test
- Parallelize the slow tests if possible.
- `test_convert_ascii` was missing a `#[test]` annotation
2023-07-08 11:05:55 -07:00
Henrik Hørlück Berg
47f1dbe56c Make test_convert seedable, but generate the seed 2023-07-08 11:05:55 -07:00
David Adam
87307775fc fds: add comment on O_CLOEXEC fallback being dropped 2023-07-05 10:30:27 +08:00
ridiculousfish
bee422fea2 Use a faster, deterministic RNG in the string escape tests
This shaves about 9 seconds off of the runtime, and makes the test
deterministic.

We do not touch the test_convert test because there is a known failure and we
need to track it down before making it deterministic.
2023-07-04 13:27:53 -07:00
ridiculousfish
0bfe83ce88 Replace write! calls with explicit hex formatting
Rather than relying Rust's formatting, just compute the hex chars directly.

This shaves about 6 seconds off of the test runtime.
2023-07-04 13:27:53 -07:00
ridiculousfish
c48c0bb226 Replace sprintf call with write!
This reduces the time for the Rust tests from a few minutes to ~40 seconds.

Also fix some bogus comments which were ported from C++.
2023-07-04 13:27:53 -07:00
ridiculousfish
b16f617fb3 Migrate string and lock tests into their own files
Get some stuff out of the common module, which is growing large.

Also migrate the tests into "native" Rust tests so they will run in parallel.
We have to use an explicit setlocale() call to get a multibyte locale, for the
"crazy" tests.
2023-07-04 13:27:53 -07:00
ridiculousfish
eaf8e73c42 Make escape/unescape string_var hew more closely to the C++ 2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
970ed610df Avoid string copying to speed up asan 2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
595d593732 Fully migrate to Rust escape string tests and code
Co-Authored-By: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
0a4bcf7430 Port (un)escape-tests, fix a couple bugs 2023-07-04 13:27:53 -07:00
ridiculousfish
ec28a30bd6 Fix a clippy lint warning 2023-07-04 13:26:19 -07:00
ridiculousfish
35f8f421fe topic_monitor to migrate from wperror to perror
This avoids needing to use the ffi
2023-07-04 13:26:19 -07:00
ridiculousfish
15361f62ed signal.rs to stop using wperror
This needed to cross the ffi which is annoying in tests. Use the Rust perror()
instead.
2023-07-04 13:26:19 -07:00
ridiculousfish
1076642770 Remove future_feature_flags_init
Make Features just a global. After the Rust port we can make it use atomics and
no longer be mut.

This allows feature flags to be used in Rust tests.
2023-07-04 13:26:19 -07:00
ridiculousfish
37fed01642 FLOG to stop depending on the ffi
Prior to this commit, FLOG used the ffi bridge to get the output fd. Invert
this: have fish set the output fd within main. This allows FLOG to be used in
pure Rust tests.
2023-07-04 13:26:19 -07:00
ridiculousfish
2ec482e94a Move the Option out of ParsedSourceRef, and use Arc instead of Rc
Two small fixes:

1. ParsedSourceRef, if present, should not be None; express that in the type.
2. ParsedSourceRef is intended to be shareable across threads; make it so.
2023-07-02 17:46:04 -07:00
Fabian Boehm
a996c8c7dd Fix clippy
As always: Some petty complaints of no actual use
2023-07-02 10:10:29 +02:00
ridiculousfish
12dfbc14d7 Make builtin status long options const
By using an explicit match instead of unwrap(), we can avoid the use of Lazy.
2023-07-01 16:05:10 -07:00
ridiculousfish
1c5c1993dd Make wdirname and wbasename go &wstr -> &wstr
There is no reason for either of these functions to allocate, so have
them not do it.
2023-07-01 15:41:46 -07:00
ridiculousfish
d26d4f36b0 Minor fixes to builtin status
Use as_wstr() instead of from_ffi() in a few places to avoid an allocation,
and make job_control_t work in &wstr instead of &str to reduce complexity at
the call sites.
2023-07-01 15:33:11 -07:00
Henrik Hørlück Berg
4061c7250c Replace status_cmd with an option
- Using an option makes it much clearer that the check for empty args is
  redundant.
- Also prefer implementing TryFrom only for &str, to not hide the string
  conversion and allocation happening.
2023-07-01 15:33:01 -07:00
Henrik Hørlück Berg
7b3637cd1f Port builtins/status to fish
- Also port tests of wdirname and wbasename, as they were bugged
2023-07-01 15:33:01 -07:00
ridiculousfish
37337683cb Revert "Fix Rust wdirname and wbasename and port the C++ tests"
This reverts commit 6b1c2e169c.

We're about to rework these in the builtin status changes.
2023-07-01 13:38:38 -07:00
ridiculousfish
6b1c2e169c Fix Rust wdirname and wbasename and port the C++ tests
These functions were rather buggy; add tests and fix the test failures.
2023-07-01 12:45:11 -07:00
David Adam
ce9f95128a type/command: implement optimisation for --all
This was present in the C++ version for command, though never for type.

Checking over all elements of PATH can be slow on some platforms eg
WSL2, so only do that when used with `--all`.

Based on discussion in
https://github.com/fish-shell/fish-shell/pull/9856
2023-06-30 10:05:01 +08:00
David Adam
14cfd268d8 path: drop path_get_paths_ffi
f77dc24 provides the pieces to call path_get_paths directly from Rust
code. Drop the C++ implementation and its FFI.
2023-06-30 10:05:01 +08:00
Henrik Hørlück Berg
1f67bcbb39 Update dependencies for asan to work
Rust nightly changed the name of a preview feature, which broke proc-macro2,
see https://github.com/rust-lang/rust/issues/113152
2023-06-29 20:02:43 -05:00
Fabian Boehm
c7b43b3abf Truncate builtin arguments on NUL
This restores the status quo where builtins are like external commands
in that they can't see anything after a 0x00, because that's the c-style
string terminator.
2023-06-24 21:26:44 +02:00
David Adam
78940a6026 print_help: make function public 2023-06-24 18:21:21 +08:00
Fabian Boehm
11c8d9684e
Make NULs work for builtins (#9859)
* Make NULs work for builtins

This switches from passing a c-string to output_stream_t::append to
passing a proper string.

That means a builtin that prints a NUL no longer crashes with "thread '' panicked
at 'String contained intermediate NUL character: ".

Instead, it will actually handle the NUL, even as an argument.

That means something like

`echo foo\x00bar` will now actually print a NUL instead of truncating
after the `foo` because we passed c-strings around everywhere.

The former is *necessary* for e.g. `string`, the latter is a change
that on the whole makes dealing with NULs easier, but it is a
behavioral change.

To restore the c-string behavior we would have to truncate arguments
at NUL.

See #9739.

* Use AsRef instead of trait bound
2023-06-22 20:50:22 +02:00
ridiculousfish
f77dc2451e Expose Rust EnvStack from parser_t
Prior to this change, parser_t exposed an environment_t, and Rust had to go
through that. But because we have implemented Environment in Rust, it is
better to just expose the native Environment from parser_t. Make that
change and update call sites.
2023-06-19 13:45:54 -07:00
ridiculousfish
6936c944c1 Add some fixes atop argparse
This switches to using the WExt functions, which deal directly in chars
and char indices.
2023-06-19 13:45:54 -07:00
Henrik Hørlück Berg
292f7b2be1 Port builtins/argparse to Rust 2023-06-19 13:45:54 -07:00
David Adam
6229f08200 rust/print_help: simplify use of OsStrings
See discussion in https://github.com/fish-shell/fish-shell/pull/9818#discussion_r1210829722
2023-06-19 21:57:53 +08:00
ridiculousfish
99c2e476ac Bravely remove writembs macro
The writembs macro was ported from C++, which attempted to detect when a NULL
termcap was used. However we have never gotten a bug report from this. Bravely
remove it.
2023-06-17 16:04:34 -07:00
ridiculousfish
21f08ee9fd Simplify some curses stuff and enforce that caps are nonempty
The outputter code has a lot of checks that string capabilities are non-empty;
just enforce that at the curses layer so we can remove those checks.

Also remove some types and traits, replacing them with simple functions.
2023-06-17 13:52:53 -07:00
ridiculousfish
dec5a64232 Outputter to implement Write
By implementing Write directly, we can remove some local buffers and uses of
Cursor. This both simplifies and optimizes the code.
2023-06-17 12:14:42 -07:00
ridiculousfish
64a40d2410 write_color_escape to stop returning bool
This bool return was always true, so we don't need it.
2023-06-17 12:14:42 -07:00
ridiculousfish
51a971bf16 Remove tparm0
Per code review, we think that tparm does nothing when there are no parameters,
and it is safe to remove it, even though this is a break from C++. This
simplifies some code.
2023-06-17 12:14:42 -07:00
ridiculousfish
a09947cd99 Implement builtin set_color in Rust
This rewrites the set_color builtin in Rust, restoring italics support in
iTerm2.
2023-06-17 12:14:42 -07:00
ridiculousfish
84b24d5615 Adopt the new output.rs
This switches output.cpp from C++ to Rust.
2023-06-17 12:14:42 -07:00
ridiculousfish
8f38e175ce Add from_ffi() to rgb_color_t
This allows converting a C++ rgb_color_t to a Rust RgbColor.
2023-06-17 12:14:42 -07:00
ridiculousfish
8604be9a4f Port (but do not yet adopt) output.cpp to Rust 2023-06-17 12:14:42 -07:00
ridiculousfish
76205e5b55 Port debug_thread_error() to Rust 2023-06-17 12:14:42 -07:00
Clemens Wasser
c2f58cd312 Port killring 2023-06-04 12:18:19 -07:00
ridiculousfish
cfdcaf880f Simplify scoped_push and ScopedGuard
This makes some simplifications to scoped_push and ScopeGuard:

1. ScopeGuard no longer uses ManuallyDrop; the memory management is now
   trivial and no longer requires `unsafe`.

2. The functions `cancel` and `rollback` have been removed, as
   these were unused. They can be added back later if needed.

3. `scoped_push` has been simplified in both signature and implementation.

4. `Projection` is no longer required and has been removed.

Also add some tests.
2023-06-04 12:14:53 -07:00
ridiculousfish
777ba6f9d8 Use consistent formatting in the parse_rgb test 2023-06-03 12:15:45 -07:00
ridiculousfish
1bbd60c597 Fix a bug in the color.rs port
This was incorrectly parsing FFF as 0x0F0F0F instead of 0xFFFFFF.
2023-06-03 12:13:57 -07:00
David Adam
688a28c1d2 Rewrite and adopt print_help in Rust 2023-06-01 23:17:13 +08:00
ridiculousfish
3d447dec3a Fix a multiplicative overflow in color.rs
Also add a test.
2023-05-29 13:22:46 -07:00
Mahmoud Al-Qudsi
5ecd584063 Merge VarDispatchTable tables
There was only one entry in the named table, so the previous layout was quite
wasteful. This should speed up lookups and reduce memory overhead.
2023-05-26 22:59:55 -05:00
Mahmoud Al-Qudsi
6638c78b30 Port env_dispatch to Rust and integrate with C++ code 2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
cce78eeb43 Update env_var_to_ffi() to take an Option<EnvVar>
It wasn't possible to handle cases where vars.get() returned `None` then forward
that to C++, but now we can.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
6bb2725f67 Make sure rust's fish_setlocale() inits global C++ variables
We can't just call the Rust version of `fish_setlocale()` without also either
calling the C++ version of `fish_setlocale()` or removing all `src/complete.cpp`
variables that are initialized and aliasing them to their new rust counterparts.

Since we're not interested in keeping the C++ code around, just call the C++
version of the function via ffi until we don't have *any* C++ code referencing
`src/common.h` at all.

Note that *not* doing this and then calling the rust version of
`fish_setlocale()` instead of the C++ version will cause errant behavior and
random segfaults as the C++ code will try to read and use uninitialized values
(including uninitialized pointers) that have only had their rust counterparts
init.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
c71342b933 Add safe Rust wrapper around system curses library
This is not yet used but will take eventually take the place of all (n)curses
access. The curses C library does a lot of header file magic with macro voodoo
to make it easier to perform certain tasks (such as access or override string
capabilities) but this functionality isn't actually directly exposed by the
library's ABI.

The rust wrapper eschews all of that for a more straight-forward implementation,
directly wrapping only the basic curses library calls that are required to
perform the tasks we care about. This should let us avoid the subtle
cross-platform differences between the various curses implementations that
plagued the previous C++ implementation.

All functionality in this module that requires an initialized curses TERMINAL
pointer (`cur_term`, traditionally) has been subsumed by the `Term` instance,
which once initialized with `curses::setup()` can be obtained at any time with
`curses::Term()` (which returns an Option that evaluates to `None` if `cur_term`
hasn't yet been initialized).
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
c409b1a89c Port env_dispatch dependencies to rust
Either add rust wrappers for C++ functions called via ffi or port some pure code
from C++ to rust to provide support for the upcoming `env_dispatch` rewrite.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
8a549cbb15 Port/move some code from src/environment.cpp to src/env/mod.rs
The global variables are moved (not copied) from C++ to rust and exported as
extern C integers. On the rust side they are accessed only with atomic semantics
but regular int access is preserved from the C++ side (until that code is also
ported).
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
3ab8b34b1e Use Rust version of global fallback variables 2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
3ee71772f1 Revert rename of wcwidth() to system_wcwidth()
It's not clear whether or not `system_wcwidth()` was picked solely because of
the namespace conflict (which is easily remedied) but using the most obvious
name for this function should be the way to go.

We already have our own overload of `wcwidth()` (`fish_wcwidth()`) so it should
be more obvious which is the bare system call and which isn't.

(I do want to move this w/ some of the other standalone extern C wrappers to the
unix module later.)
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
1a88c55b71 Clean up FISH_EMOJI_WIDTH and FISH_AMBIGUOUS_WIDTH defines
Pull in the correct descriptions merged from across the various C++ header and
source files and get rid of the getter function that's only used in one place
but causes us to split the documentation for FISH_EMOJI_WIDTH across multiple
declarations.
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
e154391f32 Add WCharExt::find() method to perform substring search 2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
77dda2cdef Add ToCString trait
This can be used for functions that accept non-Unicode content (i.e. &CStr or
CString) but are often used in our code base with a UTF-8 or UTF-32 string
on-hand.

When such a function is passed a CString, it's passed through as-is and
allocation-free. But when, as is often the case, we have a static string we can
now pass it in directly with all the nice ergonomics thereof instead of having
to manually create and unwrap a CString at the call location.

There's an upstream request to add this functionality to the standard library:
https://github.com/rust-lang/rust/issues/71448
2023-05-25 16:54:07 -05:00
Mahmoud Al-Qudsi
b17124d8d2 Add rsconf build system and check for gettext symbols
This is more complicated than it needs to be thanks to the presence of CMake and
the C++ ffi in the picture. rsconf can correctly detect the required libraries
and instruct rustc to link against them, but since we generate a static rust
library and have CMake link it against the C++ binaries, we are still at the
mercy of CMake picking up the symbols we want.

Unfortunately, we could detect the gettext symbols but discover at runtime that
they weren't linked in because CMake was compiled with `-DWITH_GETTEXT=0` or
similar (as the macOS CI runner does). This means we also need to pass state
between CMake and our build script to communicate which CMake options were
enabled.
2023-05-25 16:54:03 -05:00
Mahmoud Al-Qudsi
6fc8940097 Simplify ScopeGuard and scoped_push() with Projection<T>
Delegate the `view` and `view_mut` to the newly added `Projection<T>`, which
makes everything oh so much clearer and cleaner. Add comments to clarify what is
happening.
2023-05-25 16:47:59 -05:00
Mahmoud Al-Qudsi
d32fee74f9 Add Projection type
This can be used when you primarily want to return a reference but in order for
that reference to live long enough it must be returned with an object.

i.e. given `Mutex<Foo { bar }>` you want a function to lock the mutex and return
a reference to `bar` but you can't return that reference since it has a lifetime
dependency on `MutexGuard` (which only derefs to all of `Foo` and not just
`bar`). You can return a `Projection` owning the `MutexGuard<Foo>` and set it up
to deref to `&bar`.
2023-05-25 16:47:59 -05:00
Fabian Boehm
90713dd221 build.rs: Remove miette dependency
This wasn't providing a lot of value, and the license compatibility is iffy.

There's a bit of weirdness in that this now uses a `Box<dyn Error>`,
but since currently nothing actually errors out let's punt that for
later.
2023-05-25 17:46:03 +02:00
Fabian Boehm
9897f4f18d fileid: Just use unix::fs::metadataext
These should be the same, except without the "st_" prefix
2023-05-23 17:43:23 +02:00
Fabian Boehm
f2e5f02a8a fileid: Use freebsd metadata
This is a terrible way of going about things,
and means we're currently broken on any unix that isn't specifically listed.

But at least it'll build and allow us to keep the FreeBSD CI running.
2023-05-23 17:37:48 +02:00
ridiculousfish
d0aba9d42c Port builtin_test tests to Rust
fish_tests has a bunch of tests for the 'test' builtin. Port these to Rust.
2023-05-21 11:50:24 -07:00
ridiculousfish
cdb77a6176 Adopt the Rust test builtin
This switches the builtin test implementation from C++ to Rust
2023-05-21 11:50:24 -07:00
ridiculousfish
10a7de03e2 Implement builtin test in Rust
This implements (but does not yet adopt) builtin test in Rust.
2023-05-21 11:50:24 -07:00
ridiculousfish
a20985c738 Implement FileID in Rust
FileID tracks a File's identity, including its inode, device, and creation and
modification times.
2023-05-21 11:50:24 -07:00
ridiculousfish
dec3976a1f wcstoi: remove the consume_all / consumed_all machinery
Nothing sets these, so they can be removed. Also remove CharsLeft
for the same reason.
2023-05-14 18:38:24 -07:00
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
ridiculousfish
e71b75e0e4 Reimplement environment and the environment stack in Rust
This reimplements the environment stack in Rust.
2023-05-07 15:15:56 -07:00
ridiculousfish
8ec1467dda Implement (but do not yet adopt) Environment in Rust
This implements the primary environment stack, and other environments such
as the null and snapshot environments, in Rust. These are used to implement
the push and pop from block scoped commands such as `for` and `begin`, and
also function calls.
2023-05-07 15:15:56 -07:00
ridiculousfish
0681b6b53a Make C++ env_var_t wrap Rust EnvVar
This reimplements C++'s env_var_t to reference a Rust EnvVar.
The C++ env_var_t is now just a thin wrapper.
2023-05-07 15:15:56 -07:00
ridiculousfish
10ee87eb28 Reimplement owning_null_terminated_array in Rust
owning_null_terminated_array is used for environment variables, where we need to
provide envp for child processes. This switches the implementation from C++ to
Rust.

We retain the C++ owning_null_terminated_array_t; it simply wraps the Rust
version now.
2023-05-07 15:15:56 -07:00
AsukaMinato
e2fdc63cdb
simplify some logic (#9777)
* simplify some logic

* simplify a &*
2023-05-07 08:39:34 -05:00
Mahmoud Al-Qudsi
6a301381c8 Fix compilation on 32-bit non-Linux platforms
The `u64::from(buf.f_flag)` was needed in two places. The existing handled macOS
which always has a 32-bit statfs::f_flag, but statvfs::f_flag is an `unsigned
long` which means it needs to be coerced to 64-bits on 32-bit targets.
2023-05-05 19:35:17 -05:00
Mahmoud Al-Qudsi
7d617d7d58 Support cross-compilation w/ detect_bsd() check
Also assert that the code works as expected by asserting the result under known
BSD systems.
2023-05-05 19:03:23 -05:00
Mahmoud Al-Qudsi
d55b65a8d2
Merge pull request #9771 from mqudsi/asan_take5
Rework ASAN integration
2023-05-04 19:43:37 -05:00
Mahmoud Al-Qudsi
8bd5183944 Remove unnecessary UTF-8 decode in is_wsl() 2023-05-02 14:58:44 -05:00
Mahmoud Al-Qudsi
d3abd5d600 Fix inverted is_console_session() logic
The $TERM matching logic was inverted.
2023-05-02 14:55:04 -05:00
Mahmoud Al-Qudsi
c94fce75e5 Add multi-byte test for wcscasecmp()
The lowercase of İ is two bytes, making it a good test candidate.
2023-05-02 14:18:43 -05:00
Mahmoud Al-Qudsi
8668ce336c Fix common::wcscasecmp() for multi-byte lowercase strings 2023-05-02 14:10:12 -05:00
Mahmoud Al-Qudsi
6c8409fd45 Remove unnecessary use of static mut.
Atomic don't need to be `mut` to change since they use interior mutability.
2023-05-02 13:22:39 -05:00
Mahmoud Al-Qudsi
f71a75f3bb Avoid unnecessary vector shift in re::regex_make_anchored()
There's no reason to inject prefix into our newly allocated str after storing
pattern in there. Just allocate with the needed capacity up front and then
insert in the correct order.
2023-05-02 13:15:02 -05:00
Mahmoud Al-Qudsi
40be27c002 Avoid unnecessary vector shift in re::regex_make_anchored()
There's no reason to inject prefix into our newly allocated str after storing
pattern in there. Just allocate with the needed capacity up front and then
insert in the correct order.
2023-05-02 13:13:11 -05:00
Xiretza
1dafb77cda Use bitflags for ParseTreeFlags + ParserTestErrorBits
For consistency with simlar code.
2023-05-02 19:03:51 +02:00
Mahmoud Al-Qudsi
91485c90ca Also free ncurses terminal state when exiting under ASAN 2023-05-02 11:52:42 -05:00
Mahmoud Al-Qudsi
3651e0e9d8 Actually report ASAN memory leaks
The new asan exit handlers are called to get proper ASAN leak reports (as
calling _exit(0) skips the LSAN reporting stage and exits with success every
time).

They are no-ops when not compiled for ASAN.
2023-05-02 11:52:41 -05:00
Mahmoud Al-Qudsi
cb368f70ee Fix rust formatting for BSD signal tests 2023-05-02 11:51:56 -05:00
Mahmoud Al-Qudsi
6a3ece6766 Rename Sigchecker to SigChecker to be more idiomatic
Idiomatic rust naming for types is "PascalCase" and this was more "Pascalcase".
2023-05-02 11:29:18 -05:00
Mahmoud Al-Qudsi
55c3df7f41 Fix BSD test failure regression
Nothing major. Introduced in 1ecf9d013d.
2023-05-02 11:23:11 -05:00
Xiretza
afe2e9d8db builtins/printf: avoid string copies by formatting directly to buffer
Closes #9765.
2023-05-01 13:32:44 -05:00
ridiculousfish
4771f25102 Adopt the new Rust signal implementation
This switches the signals implementation from C++ to Rust.
2023-04-30 16:22:57 -07:00
ridiculousfish
1ecf9d013d Port (but do not adopt) signal handling bits in Rust
This ports some signal setup and handling bits to Rust.

The signal handling machinery requires walking over the list of known signals;
that's not supported by the Signal type. Rather than duplicate the list of
signals yet again, switch back to a table, as we had in C++.

This also adds two further pieces which were neglected by the Signal struct:

1. Localize signal descriptions
2. Support for integers as the signal name
2023-04-30 16:22:55 -07:00
ridiculousfish
603a2d6973 Rename sigchecker_t to Sigchecker
This matches Rust naming conventions
2023-04-30 11:32:18 -07:00
ridiculousfish
2848be6b73 Add an empty test case to the join_strings tests 2023-04-29 17:02:18 -07:00
Xiretza
81cdd51597 Update printf-compat 2023-04-29 19:57:33 +02:00
Mahmoud Al-Qudsi
ecf1676601 Add and use type-erased RAII callback wrapper for ffi
This allows the rust code to free up C++ resources allocated for a callback even
when the callback isn't executed (as opposed to requiring the callback to run
and at the end of the callback cleaning up all allocated resources).

Also add type-erased destructor registration to callback_t. This allows for
freeing variables allocated by the callback for debounce_t's
perform_with_callback() that don't end up having their completion called due to
a timeout.
2023-04-29 11:02:59 -05:00
Mahmoud Al-Qudsi
6cd2d0ffed Integrate threads.rs w/ legacy C++ code
Largely routine but for the trampolines in iothread.h and iothread.cpp which
were a real PITA to get correct w/ all their variants.

Integration is complete with all old code ripped out and the tests using the
rust version of the code.
2023-04-29 11:02:59 -05:00
Mahmoud Al-Qudsi
7f9a942f1d Port remainder of iothreads from C++ 2023-04-29 11:02:59 -05:00
Mahmoud Al-Qudsi
85d8f2b27f Fix HAS_WORKING_TTY_TIMESTAMPS in rust
Like the WSL check, this was incorrectly assuming WSL implies
cfg(windows) when it's actually picked up as Linux.

Also, improve over the C++ code by not relying on the build-time WSL
status to determine if we are running on WSL at runtime since it's often
the case that the fish binaries are built on a non-WSL host (for
packaging) then executed on a WSL only at runtime.

(But it's ok to assume if fish has been built for Windows or not Linux
that it will either be run or not run on top of a Win32 character device
system.)

Also, port of the comment and relevant WSL and fish issue links over
from the CPP codebase for posterity.
2023-04-26 16:05:24 -05:00
Mahmoud Al-Qudsi
67124dfb11 Slightly refactor unescape_string_xxx() functions
* Since we already have an allocation of length wstr.len(), it's
  probably better to allocate the result (which is strictly less than or
  equal to the input length) up-front rather than risk thrashing the Vec
  allocation,
* There's no need to compare c2 against '\0' since that will just cause
  to_digit(16) to return None anyway,
* Our convert_hex() specialization of to_digit(16) that only checks
  capital letters A-F without also checking lowercase a-f isn't
  significantly faster than just use to_digit(16), and we already assert
  that the input *wasn't* a lowercase a-f before making the call, so
  there's no point in using a special function to handle that.
2023-04-26 15:18:27 -05:00
ridiculousfish
d0c902a548 Adopt wstr::split in more places
This simplifies some code that was written before wstr::split existed.
2023-04-23 19:34:52 -07:00
ridiculousfish
fa39113bc6 Tweak the behavior of wstr::split to better match C++
Prior to this change, wstr::split had two weird behaviors:

1. Splitting an empty string would yield nothing, rather than an empty
   string.
2. Splitting a string with the separator character as last character
   would not yield an empty string.

For example L!("x:y:").split(':') would return ["x", "y"] instead of
what it does in C++, which is ["x", "y", ""].

Fix these.
2023-04-23 19:33:10 -07:00
ridiculousfish
de8288634a Remove Arc from the global abbreviation set
This wasn't needed.
2023-04-23 15:35:05 -07:00
ridiculousfish
705874f2e4 Revert "Warn about unescape_string_xxx() behavior (and tweak slightly)"
This reverts commit 76dc849fca.

The warning added in that commit is incorrect. The functions
unescape_string_url and unescape_string_var will not panic, because
char_at() return 0 if the index is equal to its length.
2023-04-23 15:28:46 -07:00
ridiculousfish
009650b7b5 Revert "Remove unsafe from exit_without_destructors()"
This reverts commit f9c92753c4.

This commit attempted to replace exit_without_destructors() with
std::process::exit; however this is wrong for two reasons:

1. std::process::exit() runs Rust runtime cleanup stuff we don't want
2. std::process::exit() invokes destructors, meaning atexit handlers,
   which we don't want.
2023-04-23 15:23:12 -07:00
Mahmoud Al-Qudsi
76dc849fca Warn about unescape_string_xxx() behavior (and tweak slightly)
The type system no longer guarantees that the input string is nul-terminated,
meaning accessing beyond the range-checked `i` a char-at-a-time is no longer
safe. (In C++, we would either be using a plain C string which is always
nul-terminated or we would be using (w)string::cstr() which similarly grants
access to its nul-terminated buffer.)

Aside from that, there's no need to explicitly check `if c2 == '\0'` because
'\0' is not a valid hex digit so the `?` tacked on to `convert_hex_digit(c2)?`
will abort and return `None` anyway.

convert_hex_digit() is not appreciably faster than char::to_digit(16) and makes
the code less maintainable since it encodes certain assumptions; since it's also
not used consistently just drop it in favor of the std fn.

Since the output string (per the decode logic) is always shorter than or equal
to the input string, just reserve the input string size upfront to prevent vec
reallocations.
2023-04-23 15:04:37 -05:00
Mahmoud Al-Qudsi
f9c92753c4 Remove unsafe from exit_without_destructors()
std::process::exit() already does what we need and and it is safe to call (since
it is not unsafe for destructors not to be called).
2023-04-23 13:05:56 -05:00
Mahmoud Al-Qudsi
3a2033b992
Fix rust version of is_wsl() check (#9746)
Somewhat counter-intuitively, this code is active when compiling under *Linux*
and is always false when compiling under Windows. The logic was incorrectly
reversed before (it's easier to reason about when you realize that fish doesn't
even compile under Windows because it uses tons of libc functions).

As the code was actually never compiled, it wasn't actually tested for validity
either and there were some issues that prevented it from compiling that have
since been fixed. The logic has also been adjusted a bit to make it possible to
use the rust-native int parsing instead of `libc::strtod()`.

The code has been changed to use `once_cell::race::OnceBool` instead of
`once_cell::sync::Lazy<T>` which imposes a greater runtime burden with locking
and other overhead. We don't care if the code runs more than once on init (if
calls were to race, though they probably don't) - just that the code isn't
subsequently executed on each call. The `once_cell::race` module is a better fit
here, though it doesn't expose the ergonomic `Lazy<T>` façade around its types.
2023-04-23 12:28:23 -05:00
Mahmoud Al-Qudsi
ff28f29e8f
Move thread stuff out of common.rs (#9745)
is_main_thread() and co were previously ported to threads.rs, so remove the
duplicate code and move everything else related to threads there as well. No
need for common.rs to be as long as our old common.cpp!

I left #[deprecated] stubs in common.rs to help redirect anyone porting code
over that we can remove after the port has finished.

Additionally, the fork guards had previously been left as a todo!() item but I
ported that over. They're all called from the now-central threads::init()
function so there isn't a need to call each individual thread-management-fn
manually.

The decision was made a while back to try and embrace/use the native rust thread
functionality and utilities so the manual thread management code has been ripped
out and was replaced with code that marshals the native rust values instead. The
values won't line up with what the C++ code sees, but it never lined up anyway
since each was using a separate counter to keep track of the values.
2023-04-23 12:26:10 -05:00
Johannes Altmanninger
0fbefc6be2 Make IO buffer struct elements public again 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
1bffa823d8 Allow to pass slices of owned strings to trace_if_enabled 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
05ec1039ed Rename autoclose_pipes_t to AutoClosePipes 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
48e728e9fb event: make some types public again 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
6c07af9343 Shorthand for escaping with default options
Should probably do this on the C++ side too.
2023-04-22 22:25:34 +02:00
Johannes Altmanninger
19fe0f6a91 AST: implement try_source_range for union fields
Still not sure where the union fields are going.
I don't think they should implement Node.
2023-04-22 22:25:34 +02:00
Johannes Altmanninger
4c46faea99 Make ParsedSource members public again 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
29891cf771 Finish and fix DirIter API 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
07cc33e7aa parse_util: deduplicate append_syntax_error macro 2023-04-22 22:25:34 +02:00
Johannes Altmanninger
56ad7fe0e5 Silence some more clippy lints
They are at odds with some direct translations.
2023-04-22 22:25:34 +02:00
Johannes Altmanninger
ec176dc07e Port path.h 2023-04-21 13:57:29 +02:00
Johannes Altmanninger
629cbe0115 Env stubs for path port 2023-04-21 13:57:29 +02:00
Johannes Altmanninger
eb1598ea9a Port parser_keywords
This drops some of the optimizations, we should probably add them back.
2023-04-21 13:57:29 +02:00
Johannes Altmanninger
12ce42a2f9 Rename kw() to keyword() also in C++ 2023-04-19 22:43:36 +02:00
Johannes Altmanninger
09ffac5a0a Port parse_util_compute_indents 2023-04-19 10:35:22 +02:00
Johannes Altmanninger
c25cc8df5d Adopt rusty parse_util_unescape_wildcards 2023-04-19 10:32:16 +02:00
Johannes Altmanninger
12afb320a3 Port parse_util
Except for the indent visitor bits.

Tests for parse_util_detect_errors* are not ported yet because they depend
on expand.h (and operation_context.h which depends on env.h).
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
36ba912779 Make some names public 2023-04-19 01:03:16 +02:00
Johannes Altmanninger
dc6aead17b ast.rs: add Leaf::has_source() convenience function for now
This is exposed by our FFI bridge for convenience, so this makes porting
easier.
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
966dc0d997 Fix how we pass error list output parameter when parsing AST
This makes it more convenient to pass None.
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
22c8e9f60d Don't leak ParseErrorList FFI crutch type into Rust
Just like 16ea4380c (redirection.rs: don't leak FFI type into Rust code,
2023-04-09).
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
fc5e97e55e Expose u32 source offsets as usize
Computations should use usize, so this makes things more convenient.
Post-FFI we can make SourceRange fields private, to enforce this even easier.
2023-04-19 01:03:16 +02:00
Johannes Altmanninger
2ca27d2c5b Implement Iterator for Tokenizer 2023-04-19 01:03:16 +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
Johannes Altmanninger
fdeb0d9f06 Port the rest of wcstringutil 2023-04-18 12:54:19 +02:00
Fabian Boehm
3bfe798dbb Fix read_blocked
This caused math to assert out because it never wrote into the buffer.

Now, presumably it wrote somewhere but I don't know where, so fixing
this seems like a good idea.

Fixes #9735.
2023-04-17 17:28:24 +02:00
ridiculousfish
1bf29a5e13 Support constructing a wcstring_list_ffi_t from Rust
This allows passing a vector of strings from Rust to C++
2023-04-16 13:36:13 -07:00
ridiculousfish
f0360efbfa Add path_make_canonical in Rust 2023-04-16 13:36:13 -07:00
ridiculousfish
eecc796b04 Add a widestring split() function
This allows splitting widestrings about a char, similar to C++
split_string.
2023-04-16 13:36:13 -07:00
ridiculousfish
621a3a6a8b Add Rust support for null terminated arrays
This adds support for "null-terminated arrays of nul-terminated strings"
as used in execve, etc.
2023-04-16 13:36:13 -07:00
Xiretza
ed3fdaa665 Change read_blocked parameter type to RawFd for clarity 2023-04-16 22:26:46 +02:00
Xiretza
14fc11b5b8 wcstod: adjust tests for new implementation 2023-04-16 22:26:46 +02:00
Xiretza
aab2f660a7 Port math builtin, tinyexpr and wcstod_underscores to Rust 2023-04-16 22:26:46 +02:00
Xiretza
cc744d30c0 io: add FFI wrappers for io_streams_t fields 2023-04-16 22:26:46 +02:00
Xiretza
ba5e1dfb69 builtins: port more error messages 2023-04-16 22:26:46 +02:00
Xiretza
be2ea8edf0 wcstod: extract wcstod_inner()
This function can be called with any char iterator, not just IntoCharIter
values.
2023-04-16 22:26:46 +02:00
Xiretza
6b687adb40 Implement IntoCharIter for &[char] 2023-04-16 22:26:46 +02:00
Fabian Boehm
a91689e211 Remove unneeded & 2023-04-16 22:22:04 +02:00
ridiculousfish
ead329db60 Replace a bunch of from_ffi with as_wstr calls
from_ffi copies a CxxWString into a new Rust WString, but as_wstr simply
gets the slice of chars directly.

Too many string types!
2023-04-16 12:50:53 -07:00
Johannes Altmanninger
971d257e67 Port AST to Rust
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.

Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.

Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now.  In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t".  This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.

Alternatively, we could define FFI wrappers for recursive AST traversal.

Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:

The only client that requires mutable access is the populator.  To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.

The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).

Like in the C++ implementation, the AST nodes themselves are largely defined
via macros.  Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.

This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList".  To make this work
we need to manually define "ExternType".

There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.

One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.

Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.

The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:

    $ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
    Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
      Time (mean ± σ):     195.5 ms ±   2.9 ms    [User: 190.1 ms, System: 4.4 ms]
      Range (min … max):   193.2 ms … 205.1 ms    15 runs

    Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
      Time (mean ± σ):     677.5 ms ±  62.0 ms    [User: 665.4 ms, System: 10.0 ms]
      Range (min … max):   611.7 ms … 805.5 ms    10 runs

    Summary
      './fish.old -c 'source ../share/completions/git.fish'' ran
        3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''

Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
  changed since  it's not user visible.
2023-04-16 17:46:56 +02:00
Johannes Altmanninger
915db44fbd Implement printf formatting for some parser types 2023-04-16 17:46:56 +02:00
Johannes Altmanninger
dc4cb84ffc Derive Debug for some parser types 2023-04-16 17:46:56 +02:00
Johannes Altmanninger
912f10ceb0 Port io 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
ecb0ab5f34 common.rs: remove G_ prefix from globals 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
238d9bf3a5 Minor cleanup of JobId::acquire 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
4036b1ab95 Make Event::caller_exit take a JobId, not an i32
A JobId is not supposed to convert to other types.

Since this type is defined as NonZeroU32 (which cannot be -1), we need to
add some conversion functions to match the C++ behavior.

Overall, it would have been better to keep using the C++ type.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
37a7fe6738 event.rs: use libc::c_int for signal numbers, not usize
This makes porting easier. Once everything is done, we can apply such
changes globally.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
f5d8087bc6 job_group.rs: use our canonical string type 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
da45bfab6b wait_handle.rs: implement Rusty set_status_and_complete
This function didn't exists in LastC++11 but given that "status" is private
I did not see an obvious alternative.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
141dcde498 signal.rs: crash a bit earlier when signal number is negative
The conversion to usize is used for array accesses, so negative values
would cause crashes either way. Let's do it earlier so we can get rid of
the suspect C-style cast.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
11df0bf54b signal.rs: use wide strings for string conversion
This makes it play better with the rest of the system,
in particular summary_command() from proc.h.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
f9a48dc946 flog.rs: allow trailing commas 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
91008acd3e fd_monitor.rs: make NativeCallback public
The upcoming io.rs calls "FdMonitorItem::new".  We cannot pass a closure,
we must pass an object of type NativeCallback.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
7069455e68 topic_monitor.rs: minor touch-up 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
483f893613 fds.rs: port the open_cloexec family 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
a5cae59082 Replace ScopedPush with scoped_push which is underpinned by ScopeGuard
This allows us to use the scoped push in more scenarios by appeasing the
borrow checker.

Use it in a couple of places instead of ScopeGuard. Hopefully this is makes
porting easier.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
2d4fbc290b Teach ScopeGuard to expose a custom view on deref()
This allows the upcoming scoped_push to stuff internal data into the context,
but not expose it to the user.
(This change is a bit ugly, needs polish)
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
a696f16aa1 compat.c: wrapper to access ncurses cur_term 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
9d436ee5e9 common.rs: port get_by_sorted_name() 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
c6b8b7548f common.rs: add fwprintf and fwputs for convenience
We should get rid of them but this helps with porting.
Not sure if they are fully correct.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
f53aa6f2e3 Port the rest of wutil 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
d3a7e3ffd9 Allow to call join_strings with a &[WString] 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
8e972dbab0 Move wrealpath and normalize_path to match C++ structure 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
b7638b50e4 common.rs: convenience function to convert to OsString
Even though we generally dont' want to use this type (because it's immutable),
it can be advantageous when working with the std::fs API.  This is because
it implements "AsRef<Path>" which neither of CString and Vec<u8> do.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
bfe68e6a83 common.rs: helper to convert from C-string of unknown length to wide
On the C++ side we have an overload that called std::wcslen(), this is the
equivalent one.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
3163efb87f Port most of fallback 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
1426d1bcb0 Port widecharwidth 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
8bbf663dee common.rs: make some functions public 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
bff0caf1d8 common.rs: remove typedefs that have been ported to elsewhere
In general we should keep the existing structure, to minimize surprise.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
16ea4380c5 redirection.rs: don't leak FFI type into Rust code 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
807d1578c3 redirection.rs: make redirection spec fields public like in C++ 2023-04-16 17:21:54 +02:00
Johannes Altmanninger
11e16ef6df env.rs: rename flags::EnvMode to EnvMode
The "flags" module was introduced when these where standalone constants.
Now that we define them as bitflags, we no longer need the extra namespace.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
8e5adbf237 Use borrowing syntax instead of std::ptr::addr_of where possible
We usually don't need to cast; this looks simpler.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
ed2b98dd9a lib.rs: group common.rs before other modules, because it exports macros
This allows us to keep the next group sorted.
2023-04-16 17:21:54 +02:00
Johannes Altmanninger
85ae1861fa common.rs: fix leftover comment 2023-04-16 17:21:54 +02:00
Xiretza
61028f020c cargo update
This fixes an issue with rust-analyzer always rebuilding even without changes,
which was introduced by b8189da011.
2023-04-16 17:21:54 +02:00
Fabian Boehm
bf0ebd3967 Actually add builtin.rs 2023-04-16 11:41:41 +02:00
Fabian Boehm
72a32f1a12 Rewrite "builtin" builtin in Rust
This is very simple and basically a subset of type.
2023-04-16 11:30:31 +02:00