crate splitting: create fish-common crate

Dependencies between crates must form a DAG. This means that breaking up
the large library crate requires breaking dependency cycles. The goal of
this commit is creating a crate which contains some of the main crate's
functionality, without depending on the main crate.

To start off, we only move things required for extracting `src/wchar.rs`
and `src/wchar_ext.rs`, which will happen in a subsequent commit.

Part of #12182
This commit is contained in:
Daniel Rainer
2025-12-17 23:14:13 +01:00
committed by Johannes Altmanninger
parent e1a6b7ea5a
commit 5a35acf2e7
11 changed files with 61 additions and 42 deletions

5
Cargo.lock generated
View File

@@ -160,6 +160,7 @@ dependencies = [
"errno",
"fish-build-helper",
"fish-build-man-pages",
"fish-common",
"fish-gettext",
"fish-gettext-extraction",
"fish-gettext-mo-file-parser",
@@ -200,6 +201,10 @@ dependencies = [
"rsconf",
]
[[package]]
name = "fish-common"
version = "0.0.0"
[[package]]
name = "fish-gettext"
version = "0.0.0"

View File

@@ -17,6 +17,7 @@ cfg-if = "1.0.3"
errno = "0.3.0"
fish-build-helper = { path = "crates/build-helper" }
fish-build-man-pages = { path = "crates/build-man-pages" }
fish-common = { path = "crates/common" }
fish-gettext = { path = "crates/gettext" }
fish-gettext-extraction = { path = "crates/gettext-extraction" }
fish-gettext-maps = { path = "crates/gettext-maps" }
@@ -90,6 +91,7 @@ cfg-if.workspace = true
errno.workspace = true
fish-build-helper.workspace = true
fish-build-man-pages = { workspace = true, optional = true }
fish-common.workspace = true
fish-gettext = { workspace = true, optional = true }
fish-gettext-extraction = { workspace = true, optional = true }
fish-printf.workspace = true

10
crates/common/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "fish-common"
edition.workspace = true
rust-version.workspace = true
version = "0.0.0"
repository.workspace = true
license.workspace = true
[lints]
workspace = true

28
crates/common/src/lib.rs Normal file
View File

@@ -0,0 +1,28 @@
// These are in the Unicode private-use range. We really shouldn't use this
// range but have little choice in the matter given how our lexer/parser works.
// We can't use non-characters for these two ranges because there are only 66 of
// them and we need at least 256 + 64.
//
// If sizeof(wchar_t))==4 we could avoid using private-use chars; however, that
// would result in fish having different behavior on machines with 16 versus 32
// bit wchar_t. It's better that fish behave the same on both types of systems.
//
// Note: We don't use the highest 8 bit range (0xF800 - 0xF8FF) because we know
// of at least one use of a codepoint in that range: the Apple symbol (0xF8FF)
// on Mac OS X. See http://www.unicode.org/faq/private_use.html.
pub const ENCODE_DIRECT_BASE: char = '\u{F600}';
pub const ENCODE_DIRECT_END: char = char_offset(ENCODE_DIRECT_BASE, 256);
pub const fn char_offset(base: char, offset: u32) -> char {
match char::from_u32(base as u32 + offset) {
Some(c) => c,
None => panic!("not a valid char"),
}
}
pub fn subslice_position<T: Eq>(a: &[T], b: &[T]) -> Option<usize> {
if b.is_empty() {
return Some(0);
}
a.windows(b.len()).position(|aw| aw == b)
}

View File

@@ -17,6 +17,7 @@
use crate::wildcard::{ANY_CHAR, ANY_STRING, ANY_STRING_RECURSIVE};
use crate::wutil::fish_iswalnum;
use bitflags::bitflags;
use fish_common::{ENCODE_DIRECT_END, char_offset, subslice_position};
use libc::{SIG_IGN, SIGTTOU, STDIN_FILENO};
use once_cell::sync::OnceCell;
use std::cell::{Cell, RefCell};
@@ -61,21 +62,6 @@
// Unicode range for our needs.
const _: () = assert!(WILDCARD_RESERVED_END <= RESERVED_CHAR_END);
// These are in the Unicode private-use range. We really shouldn't use this
// range but have little choice in the matter given how our lexer/parser works.
// We can't use non-characters for these two ranges because there are only 66 of
// them and we need at least 256 + 64.
//
// If sizeof(wchar_t))==4 we could avoid using private-use chars; however, that
// would result in fish having different behavior on machines with 16 versus 32
// bit wchar_t. It's better that fish behave the same on both types of systems.
//
// Note: We don't use the highest 8 bit range (0xF800 - 0xF8FF) because we know
// of at least one use of a codepoint in that range: the Apple symbol (0xF8FF)
// on Mac OS X. See http://www.unicode.org/faq/private_use.html.
pub const ENCODE_DIRECT_BASE: char = '\u{F600}';
pub const ENCODE_DIRECT_END: char = char_offset(ENCODE_DIRECT_BASE, 256);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EscapeStringStyle {
Script(EscapeFlags),
@@ -1016,13 +1002,6 @@ pub fn read_unquoted_escape(
Some(in_pos)
}
pub const fn char_offset(base: char, offset: u32) -> char {
match char::from_u32(base as u32 + offset) {
Some(c) => c,
None => panic!("not a valid char"),
}
}
/// Exits without invoking destructors (via _exit), useful for code after fork.
pub fn exit_without_destructors(code: libc::c_int) -> ! {
unsafe { libc::_exit(code) };
@@ -1468,13 +1447,6 @@ fn slice_contains_slice<T: Eq>(a: &[T], b: &[T]) -> bool {
subslice_position(a, b).is_some()
}
pub fn subslice_position<T: Eq>(a: &[T], b: &[T]) -> Option<usize> {
if b.is_empty() {
return Some(0);
}
a.windows(b.len()).position(|aw| aw == b)
}
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
pub enum WSL {
Any,
@@ -2024,14 +1996,15 @@ macro_rules! env_stack_set_from_env {
#[cfg(test)]
mod tests {
use super::{
ENCODE_DIRECT_BASE, ENCODE_DIRECT_END, ESCAPE_TEST_CHAR, EscapeFlags, EscapeStringStyle,
ScopeGuard, ScopedCell, ScopedRefCell, UnescapeStringStyle, bytes2wcstring, escape_string,
ENCODE_DIRECT_END, ESCAPE_TEST_CHAR, EscapeFlags, EscapeStringStyle, ScopeGuard,
ScopedCell, ScopedRefCell, UnescapeStringStyle, bytes2wcstring, escape_string,
truncate_at_nul, unescape_string, wcs2bytes,
};
use crate::{
util::get_seeded_rng,
wchar::{L, WString, wstr},
};
use fish_common::ENCODE_DIRECT_BASE;
use rand::{Rng, RngCore};
#[test]

View File

@@ -806,11 +806,11 @@ fn skip_spaces(mut s: &wstr) -> &wstr {
#[cfg(test)]
mod tests {
use fish_common::ENCODE_DIRECT_BASE;
use fish_common::char_offset;
use fish_tempfile::TempDir;
use crate::common::ENCODE_DIRECT_BASE;
use crate::common::bytes2wcstring;
use crate::common::char_offset;
use crate::common::wcs2osstring;
use crate::env::{EnvVar, EnvVarFlags, VarTable};
use crate::env_universal_common::{EnvUniversal, UvarFormat};

View File

@@ -9,8 +9,8 @@
};
use crate::common::{
EXPAND_RESERVED_BASE, EXPAND_RESERVED_END, EscapeFlags, EscapeStringStyle, UnescapeFlags,
UnescapeStringStyle, char_offset, charptr2wcstring, escape, escape_string,
escape_string_for_double_quotes, unescape_string, valid_var_name_char, wcs2zstring,
UnescapeStringStyle, charptr2wcstring, escape, escape_string, escape_string_for_double_quotes,
unescape_string, valid_var_name_char, wcs2zstring,
};
use crate::complete::{CompleteFlags, Completion, CompletionList, CompletionReceiver};
use crate::env::{EnvVar, Environment};
@@ -30,6 +30,7 @@
use crate::wildcard::{wildcard_expand_string, wildcard_has_internal};
use crate::wutil::{Options, normalize_path, wcstoi_partial};
use bitflags::bitflags;
use fish_common::char_offset;
use std::mem::MaybeUninit;
bitflags! {

View File

@@ -5,11 +5,10 @@
time::{Duration, SystemTime, UNIX_EPOCH},
};
use fish_common::subslice_position;
use super::{HistoryItem, PersistenceMode};
use crate::{
common::{bytes2wcstring, subslice_position},
flog::flog,
};
use crate::{common::bytes2wcstring, flog::flog};
// Our history format is nearly-valid YAML (but isn't quite). Here it is:
//

View File

@@ -4,7 +4,7 @@
//! - wstr: a string slice without a nul terminator. Like `&str` but wide chars.
//! - WString: an owning string without a nul terminator. Like `String` but wide chars.
use crate::common::{ENCODE_DIRECT_BASE, ENCODE_DIRECT_END};
use fish_common::{ENCODE_DIRECT_BASE, ENCODE_DIRECT_END};
pub use widestring::{Utf32Str as wstr, Utf32String as WString};
/// Pull in our extensions.

View File

@@ -2,9 +2,9 @@
use crate::{
L,
common::subslice_position,
wchar::{WString, wstr},
};
use fish_common::subslice_position;
use widestring::utfstr::CharsUtf32;
/// Helpers to convert things to widestring.

View File

@@ -1,5 +1,6 @@
// Enumeration of all wildcard types.
use fish_common::char_offset;
use libc::X_OK;
use once_cell::sync::Lazy;
use std::cmp::Ordering;
@@ -7,7 +8,7 @@
use std::os::unix::fs::MetadataExt;
use crate::common::{
UnescapeFlags, UnescapeStringStyle, WILDCARD_RESERVED_BASE, WSL, char_offset,
UnescapeFlags, UnescapeStringStyle, WILDCARD_RESERVED_BASE, WSL,
is_windows_subsystem_for_linux, unescape_string,
};
use crate::complete::{CompleteFlags, Completion, CompletionReceiver, PROG_COMPLETE_SEP};