Commit Graph

417 Commits

Author SHA1 Message Date
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
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