Commit Graph

315 Commits

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