Commit Graph

308 Commits

Author SHA1 Message Date
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
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
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
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
Johannes Altmanninger
76145145fd global_safety: port RelaxedAtomicBool 2023-03-26 19:35:57 +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
ridiculousfish
99c6c76c5e Add the category name back to FLOG output in Rust
This went missing.
2023-03-19 16:04:57 -07: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
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
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
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
ridiculousfish
a3970c1661 Improve FLOG output
Prior to this fix, the Rust FLOG output was regressed from C++, because
it put quotes around strings. However if we used Display, we would fail
to FLOG non-display types like ThreadIDs.

There is apparently no way in Rust to write a function which formats a
value preferentially using Display, falling back to Debug.

Fix this by introducing two new traits, FloggableDisplay and
FloggableDebug. FloggableDisplay is implemented for all Display types,
and FloggableDebug can be "opted into" for any Debug type:

    impl FloggableDebug for MyType {}

Both traits have a 'to_flog_str' function. FLOG brings them both into
scope, and Rust figures out which 'to_flog_str' gets called.
2023-03-04 11:35:21 -08:00
Clemens Wasser
17c1fa9d64
Port bg builtin to Rust (#9621)
* bg: Port bg builtin to Rust
2023-02-28 16:42:12 -06:00
Victor Song
c7ea768a74
Rewrite wrealpath from wutil in Rust (#9613)
* wutil: Rewrite `wrealpath` in Rust

* Reduce use of FFI types in `wrealpath`

* Addressed PR comments regarding allocation

* Replace let binding assignment with regular comparison
2023-02-26 20:13:40 -07:00
Clemens Wasser
6f5be9bae4 block: Port block builtin to Rust
Closes #9612.
2023-02-26 14:16:55 -06:00
Xiretza
dff7db2f16
Run rustfmt and clippy in CI (#9616)
* Add machine-readable MSRV to Cargo.toml
* Fix clippy warnings
* CI: add rustfmt and clippy checks
2023-02-26 13:20:20 -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
Neeraj Jaiswal
b0ed37c2e0 format: support whitespace padding in str formatting 2023-02-25 12:24:58 +01:00
Neeraj Jaiswal
e384e63b24 re: port regex make anchored to rust and helper ffi funtions for regex 2023-02-25 12:24:57 +01:00
Neeraj Jaiswal
6851d52924 env: port env constants to rust 2023-02-25 12:24:32 +01:00
Neeraj Jaiswal
7bab4c4dda common: pass c_str in ffi escape string 2023-02-25 12:24:32 +01:00
Johannes Altmanninger
5394ca1f96 Address clippy lints 2023-02-25 12:24:25 +01:00
Johannes Altmanninger
0d6b53bc3e Address clippy lints
We want to keep the cast because tv_sec is not always 64 bits, see b5ff175b4
(Fix timer.rs cross-platform compilation, 2023-02-14).
It would be nice to avoid the clippy exemption, perhaps using something like

    #[cfg(target_pointer_width = "32")]
    let seconds = val.tv_sec as i64;
    #[cfg(not(target_pointer_width = "32"))]
    let seconds = val.tv_sec;

but I'm not sure if "target_pointer_width" is the right criteria.
2023-02-25 12:24:25 +01:00
Johannes Altmanninger
30d40c1d49 ffi.rs: sort includes in include_cpp
If we sort includes as we add them instead of adding them at the end, we'll
have fewer conflicts.
2023-02-25 12:24:25 +01:00
Neeraj Jaiswal
3b60bc1de0 contains: port contains builtin to rust 2023-02-22 18:32:27 +01:00
Mahmoud Al-Qudsi
aca7dedf33 Fix Tokenizer::parse_fd() on x86
Upsizing to `usize` from `i32` doesn't work if `usize` is only 32-bits.
I changed the code to use the `FromStr` impl on `i32`, but we could have also
just used `u64` instead of `i32`.

Also, we should get in the habit of using the appropriate type aliases where
possible (`i32` should be `RawFd`).
2023-02-20 13:41:11 -06:00