diff --git a/Cargo.lock b/Cargo.lock index a1f973b9e..1425d029d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 5dee653d3..7285b5aac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml new file mode 100644 index 000000000..cd49d4c49 --- /dev/null +++ b/crates/common/Cargo.toml @@ -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 diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs new file mode 100644 index 000000000..ebcc63853 --- /dev/null +++ b/crates/common/src/lib.rs @@ -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(a: &[T], b: &[T]) -> Option { + if b.is_empty() { + return Some(0); + } + a.windows(b.len()).position(|aw| aw == b) +} diff --git a/src/common.rs b/src/common.rs index f6476f4d4..915d8d213 100644 --- a/src/common.rs +++ b/src/common.rs @@ -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(a: &[T], b: &[T]) -> bool { subslice_position(a, b).is_some() } -pub fn subslice_position(a: &[T], b: &[T]) -> Option { - 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] diff --git a/src/env_universal_common.rs b/src/env_universal_common.rs index c1c43c9a3..94cb747bc 100644 --- a/src/env_universal_common.rs +++ b/src/env_universal_common.rs @@ -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}; diff --git a/src/expand.rs b/src/expand.rs index a3dd60607..8711ae7e2 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -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! { diff --git a/src/history/yaml_backend.rs b/src/history/yaml_backend.rs index c385817f7..a8c89e488 100644 --- a/src/history/yaml_backend.rs +++ b/src/history/yaml_backend.rs @@ -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: // diff --git a/src/wchar.rs b/src/wchar.rs index efcf3dc60..56b29d720 100644 --- a/src/wchar.rs +++ b/src/wchar.rs @@ -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. diff --git a/src/wchar_ext.rs b/src/wchar_ext.rs index 2b9c1d39c..f2cbe11cf 100644 --- a/src/wchar_ext.rs +++ b/src/wchar_ext.rs @@ -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. diff --git a/src/wildcard.rs b/src/wildcard.rs index 725a5cb9b..f08605c23 100644 --- a/src/wildcard.rs +++ b/src/wildcard.rs @@ -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};