Commit graph

229 commits

Author SHA1 Message Date
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
Fabian Boehm
b65a53a2a6 Rewrite "command" builtin in Rust
This is basically a subset of type, so we might as well.

To be clear this is `command -s` and friends, if you do `command grep` that's
handled as a keyword.

One issue here is that we can't get "one path or not" because I don't
know how to translate a maybe_t? Do we need to make it a shared_ptr instead?
2023-04-16 11:27:08 +02:00
Fabian Boehm
662a4740e2 Rewrite the type builtin in rust 2023-04-16 11:27:08 +02:00
Fabian Boehm
7c37b681b2 Expose out_is_redirected to rust 2023-04-16 11:27:08 +02:00
Fabian Boehm
31d65de26c function: Add a bunch of awkward helper functions
This makes function_properties_ref_t not const, in order to work
around cxx
2023-04-16 11:27:08 +02:00
ridiculousfish
15c8f08458 Eliminate to_rust_string_vec
This can just use wcstring_list_ffi_t now.
2023-04-15 18:15:37 -07:00
ridiculousfish
dee969bf3a Introduce wcstring_list_ffi_t
wcstring_list_ffi_t is an autocxx-friendly type for passing lists of
strings from C++ to Rust.
2023-04-15 17:53:52 -07:00
Johannes Altmanninger
9983c32a57 Port over builtin exit codes
They used to live in common.h but they are mostly used by builtins so I
grudgingly accept the early move.
2023-04-11 09:29:28 +02:00
Mahmoud Al-Qudsi
d728b884dd Update pinned cxx dependency
Pulls in fish-shell/cxx 00536f3b771c9741bc325b37e7627d52052240a3 which
implements `VectorElement` for `CxxWString`.
2023-04-10 20:51:07 -05:00
ridiculousfish
169f90448a Stop generating autoccx ffi wrappers for pcre2 regex
We have "native" FFI wrappers for these now via the pcre2 crate.
2023-04-08 19:05:08 -07:00
ridiculousfish
a487b1ecf2 Revert "Revert "Implement builtin_printf in Rust""
This reverts commit 9f7e6a6cd1.

Add additional fixes from code review.
2023-04-06 15:54:09 -07:00
ridiculousfish
14c5c94d01 Use hexponent to implement hex float parsing in wcstod
This teaches wcstod to parse hex floats like 0x1.5p3 via a forked
version of hexponent. This support is necessary for printf.
2023-04-06 14:29:18 -07:00
ridiculousfish
74104f76ad wcstod() to skip leading whitespace
This matches the C implementation.
2023-04-06 14:29:18 -07:00
Mahmoud Al-Qudsi
3932ed118e Update cxx dependency
The let_cxx_wstring!() macro now works and can be used to avoid needing an extra
ffi call to obtain a (pinned) wstring object.
2023-04-03 22:03:08 -05:00
Johannes Altmanninger
a3e6353c05 Remove redundant comment, fish targets Unix-like systems 2023-04-02 15:17:06 +02:00
Johannes Altmanninger
ad5c86604b Simplify string narrowing logic 2023-04-02 15:17:06 +02:00
Johannes Altmanninger
735d6a53a5 common.rs: implement string escaping
This is duplicated (but need not be).
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
05bad5eda1 Port common.{h,cpp} to Rust
Most of it is duplicated, hence untested.

Functions like mbrtowc are not exposed by the libc crate, so declare them
ourselves.
Since we don't know the definition of C macros, add two big hacks to make
this work:
1. Replace MB_LEN_MAX and mbstate_t with values (resp types) that should
   be large enough for any implementation.
2. Detect the definition of MB_CUR_MAX in the build script. This requires
   more changes for each new libc. We could also use this approach for 1.

Additionally, this commit brings a small behavior change to
read_unquoted_escape(): we cannot decode surrogate code points like \UDE01
into a Rust char, so use � (\UFFFD, replacement character) instead.
Previously, we added such code points to a wcstring; looks like they were
ignored when printed.
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
998cb7f1cd New wcs2zstring to explicitly convert to zero-terminated strings
wcs2string converts a wide string to a narrow one.  The result is
null-terminated and may also contain interior null-characters.
std::string allows this.

Rust's null-terminated string, CString, does not like interior null-characters.
This means we will need to use Vec<u8> or OsString for the places where we
use interior null-characters.
On the other hand, we want to use CString for places that require a
null-terminator, because other Rust types don't guarantee the null-terminator.

Turns out there is basically no overlap between the two use cases, so make
it two functions. Their equivalents in Rust will have the same name, so
we'll only need to adjust the type when porting.
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
746019e4ad common.rs: reorder to match C++ companion
This makes it easier to check that we ported everything.
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
ed3a0b2bc3 Move join_strings into wcstringutil.rs
On the C++ side it lives in wcstringutil.cpp.  We should probably keep
it there until we have ported the entirety of that file.
2023-04-02 15:17:06 +02:00
Johannes Altmanninger
4f14b8dc7b Rename byte encoding helper
Existing C++ code didn't use a function for this but simply added
ENCODE_DIRECT_BASE. In Rust that's more verbose because char won't do
arithmetics, hence the function.

We'll add a dual function for decoding, so let's rename this.

BTW we should get rid of the "wchar" naming, it's just "char" in Rust.
2023-04-02 15:17:06 +02:00
Clemens Wasser
3ae16a5b95 trace: Port trace to Rust 2023-03-28 20:11:42 -07:00
ridiculousfish
9f7e6a6cd1 Revert "Implement builtin_printf in Rust"
This reverts PR #9666. This had outstanding review comments and should
not have been committed.
2023-03-27 22:03:30 -07:00
ridiculousfish
b0a3e14832 Collapse duplicate ENCODE_DIRECT_BASE and ENCODE_DIRECT_END
Credit to @Xiretza for spotting this.
2023-03-27 13:42:38 -07:00
ridiculousfish
3eb6f2ac74 Implement builtin_printf in Rust
This implements builtin_printf in Rust.
2023-03-26 17:40:24 -07:00
ridiculousfish
558baf4957 Implement some locale pieces
This adds locale.rs, which maintains a locale struct sufficient to
support printf.
2023-03-26 17:40:24 -07:00
ridiculousfish
dad1290337 Replace the printf implementation
The existing printf implementation is too buggy to back the printf
builtin. Switch to the new implementation based on printf-compat.
2023-03-26 14:07:29 -07:00
ridiculousfish
389d25e30f Allow sprintf! to work with literal format strings
Now sprintf! has two modes:

- Literal format string
- Widechar runtime-format string
2023-03-26 13:39:23 -07:00
ridiculousfish
aa46e7b27c Correct wcstoi for "leading zeros"
Prior to this change, wcstoi("0x") would fail with missing digits.
However strtoul will "backtrack" to return just the 0 and leave the x as
the remainder. Implement this behavior.
2023-03-26 13:39:23 -07:00
ridiculousfish
f4fa0171f2 wcstoi to match strtoul for unsigned types and negative input
Prior to this change, wcstoi() would return an error if the requested
type were unsigned, and the input had a leading minus sign. However this
causes problems for printf, which expects strtoul behavior.

Add "modulo base" behavior which wraps the negative value to positive.
Factor this into an option; the default is False (but code which
previously used strtoull directly should set it to true).
2023-03-26 13:39:23 -07:00
ridiculousfish
dc8aab3f52 Introduce fish_wcstoi_partial
fish_wcstoi_partial is like fish_wcstoi: it converts from a string to an
int optionally inferring the radix. fish_wcstoi_partial also returns the
number of characters consumed.
2023-03-26 13:39:22 -07:00
ridiculousfish
7729d3206a Implement wcstod() in Rust
This is built around fast-float.

Factor the error type from this and wcstoi() together into a shared
type.
2023-03-26 13:38:58 -07:00
ridiculousfish
0e68405ccd Add our fast-float crate
This adds a dependency on https://github.com/fish-shell/fast-float-rust
which is our forked fast-float crate for parsing.
2023-03-26 13:38:09 -07:00
Johannes Altmanninger
76145145fd global_safety: port RelaxedAtomicBool 2023-03-26 19:35:57 +02:00
Johannes Altmanninger
a0eed3760e Cargo.toml: sort dependencies 2023-03-26 17:24:45 +02:00
Johannes Altmanninger
eb377d3c65 common.rs: implement Default for EscapeFlags 2023-03-26 17:17:37 +02:00
Johannes Altmanninger
981e470a2e common.rs: use bitflags for escape flags
See this discussion:
https://github.com/fish-shell/fish-shell/pull/9636#discussion_r1125640395
2023-03-26 17:17:37 +02:00
Johannes Altmanninger
b64c3eb79b termsize.rs: export Termsize 2023-03-26 17:17:37 +02:00
Johannes Altmanninger
d073b7140b lib.rs: sort modules 2023-03-26 17:17:37 +02:00
Johannes Altmanninger
16fa942074 parse_constants.rs: stop decoding UTF-8 when parsing keywords
Unfortunately we cannot use wide string literals in match statements
(not sure if there's an easy fix).
Because of this, I converted the input to UTF-8 so we could use the match
statement. This conversion is confusing, let's skip it.
2023-03-26 17:17:37 +02:00
ridiculousfish
b8189da011 Use the rust-pcre2 crate for regex
This adds support for our (forked) rust-pcre2 crate.
2023-03-25 17:01:50 -07:00
Mahmoud Al-Qudsi
fb74f77c86 Use bsd feature for signals
Signals present in 4.4BSD can be assumed present on all modern BSD derivatives.
2023-03-20 20:28:25 -05:00
Mahmoud Al-Qudsi
f2cf54608d Migrate existing rust code to Signal type
Everything but signal handlers has been changed to use `Signal` instead of
`c_int` or `i32` signal values.

Event handlers are using `usize` to match C++, at least for now.
2023-03-20 16:17:28 -05:00
Mahmoud Al-Qudsi
1f4c233dfb Add Signal newtype
Signal is a newtype around NonZeroI32. We could use NonZeroU8 since all signal
values comfortably fit, but using i32 lets us avoid a fallible attempt at
narrowing values returned from the system as integers to the narrower u8 type.

Known signals are explicitly defined as constants and can be matched against
with equality or with pattern matching in a `match` block. Unknown signal values
are passed-through without causing any issues.

We're using per-OS targeting to enable certain libc SIGXXX values - we could
change this to dynamically detecting what's available in build.rs but then it
might not match what libc exposes, still giving us build failures.
2023-03-20 16:17:28 -05:00
AsukaMinato
2e66bb19da use $( ... )* syntax 2023-03-20 11:20:12 -07:00
ridiculousfish
732f7284d4 Adopt the new termsize
This eliminates the C++ version.
2023-03-19 16:13:41 -07:00
ridiculousfish
6ec35ce182 Reimplement termsize in Rust
This is not yet adopted by fish.
2023-03-19 16:13:41 -07:00
Mahmoud Al-Qudsi
3fab931e86 Fix build.rs formatting and prep it for further feature detections 2023-03-19 18:12:50 -05:00
ridiculousfish
99c6c76c5e Add the category name back to FLOG output in Rust
This went missing.
2023-03-19 16:04:57 -07:00
Mahmoud Al-Qudsi
34a4c7de7f Add BSD feature
This should be used in lieu of manually targeting individual operating systems
when using features shared by all BSD families.

e.g. instead of

   #[cfg(any(target_os = "freebsd", target_os = "dragonflybsd", ...))]
   fn foo() { }

you would use

    #[cfg(feature = "bsd")]
    fn foo() { }

This feature is automatically detected at build-time (see build.rs changes) and
should *not* be enabled manually. Additionally, this feature may not be used to
conditionally require any other dependency, as that isn't supported for
auto-enabled features.
2023-03-19 17:55:22 -05:00
ridiculousfish
57f4571a01 Rewrite wait handles and wait handle store in Rust 2023-03-18 18:53:04 -07:00
AsukaMinato
14d6b1c3de Simplify Default impl for ParseError
By implementing `Default` for `ParseErrorCode`, `ParseError` can just
`#[derive(Default)]` instead.

Closes #9637.
2023-03-17 19:59:52 -05:00
Xiretza
b39715434b ScopeGuard: remove memory leak
Calling ScopeGuard::rollback() would leak the `on_drop` callable; this is
a problem for Box<dyn FnOnce> or closures containing Drop data.
2023-03-13 11:54:05 -05:00
ridiculousfish
dea18b34aa Add tests for normalize_path and fix some bugs 2023-03-12 19:50:35 -07:00
ridiculousfish
33fd679f68 Use char_at instead of to_char_slice() 2023-03-12 19:50:35 -07:00
ridiculousfish
f54a45d09c Add missing builtin_print_help in realpath
This got dropped in the port.
2023-03-12 19:50:35 -07:00
Victor Song
88e0c2137a Added constants for expansions 2023-03-12 19:50:35 -07:00
Victor Song
80c8bc75e6 Switch to errno crate 2023-03-12 19:50:35 -07:00
Victor Song
3dfc9082e6 Use std::io::Error::last_os_error() for errno 2023-03-12 19:50:35 -07:00
Victor Song
ca494778e4 builtins: Port realpath to Rust 2023-03-12 19:50:35 -07:00
Mahmoud Al-Qudsi
47b4e3d067 fixup! Switch signals from usize to i32
Just address two clippy lints that are fallout from changing the signal type.
There's no longer any need to convert these (which gets rid of an unwrap).
2023-03-12 21:38:24 -05:00
Mahmoud Al-Qudsi
4f30993dbb Use ScopeGuard to replace manually saved-and-restored variables 2023-03-12 21:32:35 -05:00
Mahmoud Al-Qudsi
11766cf56f Add a proper rust ScopeGuard
Due to limitations imposed by the borrow checker, there are very few places
where we will be able to use the `ScopedPush` class ported over from the C++
codebase (once you capture the value w/ a `ScopedPush` you can't access the
value - or the mutable reference you used to reach it! - until the `ScopedPush`
object goes out of scope).

This alternative requires binding the previous values to a variable and manually
restoring them in the callback passed to the `ScopeGuard` constructor, but will
work with rust's borrow and `&mut` paradigm.
2023-03-12 21:32:35 -05:00
Victor Song
06547aef54 Detect rust-analyzer in build script to enable autocxx completions
Currently the `autocxx` generated code does not produce any code intelligence
because `rust-analyzer` can't find the generated code since it's not in the
workspace. Here, we detect `rust-analyzer` by checking for a `RUSTC_WRAPPER`
environment variable containing `rust-analyzer` and changing (or avoid changing)
the output directory accordingly.

Closes #9654.
2023-03-12 21:31:28 -05:00
ridiculousfish
409bf2995d Switch signals from usize to i32
This eliminates some conversions.
2023-03-12 17:08:35 -07:00
ridiculousfish
161734f310 Remove bitset module
This was added to support signals; however we are unlikely to use this
for anything else. Remove it; just use a u64 to report signals that have
been set.
2023-03-12 16:58:22 -07:00
Mahmoud Al-Qudsi
8e9dc74a02 Simplify EventType matching slightly 2023-03-12 16:24:04 -05:00
Victor Song
77fe9933e2 builtins: Rewrite pwd in Rust
Closes #9625.
2023-03-12 15:18:15 -05:00
Mahmoud Al-Qudsi
6809a8dfbc Use a bit set for pending signals
This optimizes over both the rust rewrite and the original C++ code. The rust
rewrite saw `std::bitset` replaced with `[bool; 65]` which could result in a
lot of memory copy bandwidth each time we checked for and received no signals.
The original C++ code would iterate over all signal slots to see if any were
set. The code now returns a single u64 and only checks slots that are known to
have signals via an intelligent `Iterator` impl.
2023-03-12 14:55:50 -05: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
Mahmoud Al-Qudsi
c8d2f7a0da Add trait to convert FFI reference to &wstr
You can now use a reference to CxxWString or an allocated UniquePtr<CxxWString>
to get an &wstr temporary to use without having to allocate again (e.g. via
`from_ffi()`).
2023-03-12 14:55:50 -05:00
ridiculousfish
5197bf75cd Point fish autocxx and similar dependencies at new fish-shell location
These crates have been moved into fish-shell org; update Cargo.toml to
reflect that.
2023-03-09 21:01:49 -08:00
Johannes Altmanninger
c6756e9324 Canonicalize some wide string imports
wchar.rs should not import let alone reexport FFI strings.
Stop re-exporting utf32str! because we use L! instead.

In wchar_ffi.rs, stop re-exporting cxx::CxxWString because that hasn't
seen adoption.

I think we should use re-exports only for aliases like "wstr" or for aliases
into internal modules.
So I'd probably remove `pub use wchar_ffi::wcharz_t = crate::ffi::wcharz_t`
as well.
2023-03-05 10:32:20 +01:00
Johannes Altmanninger
e6994ea3ac Remove obsolete clippy suppression
This type has been extracted to an alias, so it is okay now.
2023-03-05 10:32:20 +01:00
Mahmoud Al-Qudsi
d839fea748 Silence some more clippy lints
bool_assert_comparison is stupid, the reason they give is "it's shorter". Well,
`assert!(!foo)` is nowhere near as readable as `assert_eq!(foo, false)` because
of the ! noise from the macro.

Uninlined format args is a stupid lint that Rust actually walked back when they
made it an official warning because you still have to use a mix of inlined and
un-inlined format args (the latter of which won't complain) since only idents
can be inlined.
2023-03-05 00:54:17 -06:00
Mahmoud Al-Qudsi
4828346f8b Implement and use Read and Write traits for AutoCloseFd
This lets us use any std::io functions that build on top of these, such as
`write_all()` in place of our own `write_loop()`.
2023-03-05 00:33:54 -06:00
Mahmoud Al-Qudsi
455b744bca Port fd_monitor tests to rust
This shows some of the ugliness of the rust borrow checker when it comes to
safely implementing any sort of recursive access and the need to be overly
explicit about which types are actually used across threads and which aren't.

We're forced to use an `Arc` for `ItemMaker` (née `item_maker_t`) because
there's no other way to make it clear that its lifetime will last longer than
the FdMonitor's. But once we've created an `Arc<T>` we can't call
`Arc::get_mut()` to get an `&mut T` once we've created even a single weak
reference to the Arc (because that weak ref could be upgraded to a strong ref at
any time). This means we need to finish configuring any non-atomic properties
(such as `ItemMaker::always_exit`) before we initialize the callback (which
needs an `Arc<ItemMaker>` to do its thing).

Because rust doesn't like self-referential types and because of the fact that we
now need to create both the `ItemMaker` and the `FdMonitorItem` separately
before we set the callback (at which point it becomes impossible to get a
mutable reference to the `ItemMaker`), `ItemMaker::item` is dropped from the
struct and we instead have the "constructor" for `ItemMaker` take a reference to
an `FdMonitor` instance and directly add itself to the monitor's set, meaning we
don't need to move the item out of the `ItemMaker` in order to add it to the
`FdMonitor` set later.
2023-03-05 00:33:53 -06:00
Mahmoud Al-Qudsi
83a220a532 Make fd_monitor types useable from native code
We were only using their ffi implementations which are automatically
exported/public, but the actual functions we would need if we were to use
FdMonitor and co. in native rust code were either private or missing convenient
wrappers.
2023-03-05 00:23:01 -06:00
Mahmoud Al-Qudsi
78a78a834c Port read_loop() and write_loop() to rust
The existing code is kept, but a rusty version of these functions is added for
code that needs them.

These should only be temporarily used when porting 1-to-1 from C++; we should
use the std library's `read()` and `write_all()` methods instead in the future.
2023-03-05 00:22:56 -06:00
Mahmoud Al-Qudsi
f2f7d1d183 Simplify assert_sorted_by_name! macro
By extracting the equivalent of i32::cmp() into its own const function,
it becomes a lot easier to see what is happening and the logic can be
more direct.
2023-03-04 17:05:11 -06:00
Johannes Altmanninger
2c331e9c69 Implement more bitwise operation for parser bitfields
These will be used in the parser.

Maybe this type should be a struct with boolean fields. The current way has
the upside that the usage is exactly the same as in C++.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
b92313b79d Allow using wgettext_fmt without comma from macros
Otherwise we'd get this error when using it from another macro

        Some(wgettext_fmt!($fmt $(, $args)*))
                               ^ missing tokens in macro arguments
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
7ec27617ae Support widestring macro on non-literal strings
This enables usage in macros like

        L!(stringify!($snake_case_name))

in the upcoming AST port.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
be89793669 Fix buffer overflow accessing error source in ParseError::describe()
For some reason this error is triggered by tests after the Rust port of
ast.cpp. Might want to get to the bottom of this but moving it back
to match the original C++ logic fixes it.
2023-03-04 22:24:22 +01:00
Johannes Altmanninger
386f952c53 Implement constructors for some parser types 2023-03-04 22:24:22 +01:00
Johannes Altmanninger
913eeffa7e Derive Copy for some parser types 2023-03-04 22:24:22 +01:00
Johannes Altmanninger
bb1c64b202 Make some parser types public 2023-03-04 22:24:22 +01:00
Johannes Altmanninger
d0bda9893b Silence -Wcomment warnings in cxx compiler runs
This is one of the few warnings we disable due to false positives.  Let's also
disable it in the preprocessing steps needed for the Rust build.

Other warnings we ignore are -Wno-address -Wunused-local-typedefs and
-Wunused-macros. I didn't add them here because I don't expect that they
will be triggered by the headers we give to cxx.
2023-03-04 22:24:22 +01:00
Xiretza
8427e05bf7 Move escape_string tests to Rust
This way, both the Rust FFI wrapper and the actual C++ implementation are
tested.
2023-03-04 12:42:06 -08:00
Xiretza
7585ddf926 Port color.cpp to Rust 2023-03-04 11:46:46 -08:00
Xiretza
a23de237a6 Port ASSERT_SORTED_BY_NAME to Rust 2023-03-04 11:46:46 -08:00