Commit Graph

71 Commits

Author SHA1 Message Date
Henrik Hørlück Berg
0844247b43 Prefer os-unix prelude over importing everything separately 2023-08-09 15:00:58 +02:00
Henrik Hørlück Berg
fae090ea67 Adopt the wchar prelude 2023-08-09 15:00:58 +02:00
ridiculousfish
2d779fb194 Fix additional clippy lint errors
These lint errors appear new with clippy 0.1.72.
2023-08-05 17:29:53 -07:00
Henrik Hørlück Berg
20be990fd9 Port builtins/string to Rust
- Add test to verify piped string replace exit code

Ensure fields parsing error messages are the same.

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

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

To:

```shell
> string split --fields=a "" abc
string split: a: invalid integer
> string split --fields=1a "" abc
string split: 1a: invalid integer
```
2023-07-27 22:00:03 -07:00
ridiculousfish
076f317c31 Implement (but do not yet adopt) fish function store in Rust
This reimplements the function module in Rust. The function module stores the
global set of fish functions, and provides information about them.
2023-07-23 17:18:36 -07:00
ridiculousfish
0bfe83ce88 Replace write! calls with explicit hex formatting
Rather than relying Rust's formatting, just compute the hex chars directly.

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

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

Also migrate the tests into "native" Rust tests so they will run in parallel.
We have to use an explicit setlocale() call to get a multibyte locale, for the
"crazy" tests.
2023-07-04 13:27:53 -07:00
ridiculousfish
eaf8e73c42 Make escape/unescape string_var hew more closely to the C++ 2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
970ed610df Avoid string copying to speed up asan 2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
595d593732 Fully migrate to Rust escape string tests and code
Co-Authored-By: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
0a4bcf7430 Port (un)escape-tests, fix a couple bugs 2023-07-04 13:27:53 -07:00
Henrik Hørlück Berg
7b3637cd1f Port builtins/status to fish
- Also port tests of wdirname and wbasename, as they were bugged
2023-07-01 15:33:01 -07:00
ridiculousfish
8604be9a4f Port (but do not yet adopt) output.cpp to Rust 2023-06-17 12:14:42 -07:00
ridiculousfish
76205e5b55 Port debug_thread_error() to Rust 2023-06-17 12:14:42 -07:00
ridiculousfish
cfdcaf880f Simplify scoped_push and ScopedGuard
This makes some simplifications to scoped_push and ScopeGuard:

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

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

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

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

Also add some tests.
2023-06-04 12:14:53 -07:00
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
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
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
AsukaMinato
e2fdc63cdb
simplify some logic (#9777)
* simplify some logic

* simplify a &*
2023-05-07 08:39:34 -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
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
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
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
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
36ba912779 Make some names public 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
Xiretza
ed3fdaa665 Change read_blocked parameter type to RawFd for clarity 2023-04-16 22:26:46 +02:00
Johannes Altmanninger
ecb0ab5f34 common.rs: remove G_ prefix from globals 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
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
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
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
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
85ae1861fa common.rs: fix leftover comment 2023-04-16 17:21:54 +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