mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 09:39:52 +08:00
Use Rust for executables
Use Rust for executables Drops the C++ entry points and restructures the Rust package into a library and three binary crates. Renames the fish-rust package to fish. At least on Ubuntu, "fish_indent" is built before "fish". Make sure export CURSES_LIBRARY_LIST to all binaries to make sure that "cached-curses-libnames" is populated. Closes #10198
This commit is contained in:
parent
4a2edbf97e
commit
1683e720a8
|
@ -138,7 +138,9 @@ include(cmake/PCRE2.cmake)
|
|||
|
||||
# Define a function to link dependencies.
|
||||
function(FISH_LINK_DEPS_AND_SIGN target)
|
||||
target_link_libraries(${target} fishlib)
|
||||
# Tell Cargo where our build directory is so it can find config.h.
|
||||
corrosion_set_env_vars(${target} ${VARS_FOR_CARGO})
|
||||
corrosion_link_libraries(${target} fishlib)
|
||||
codesign_on_mac(${target})
|
||||
endfunction(FISH_LINK_DEPS_AND_SIGN)
|
||||
|
||||
|
@ -146,25 +148,18 @@ endfunction(FISH_LINK_DEPS_AND_SIGN)
|
|||
add_library(fishlib STATIC ${FISH_SRCS})
|
||||
target_sources(fishlib PRIVATE ${FISH_HEADERS})
|
||||
target_link_libraries(fishlib
|
||||
fish-rust
|
||||
${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS}
|
||||
${PCRE2_LIB} ${Intl_LIBRARIES} ${ATOMIC_LIBRARY}
|
||||
"fish-rust")
|
||||
${PCRE2_LIB} ${Intl_LIBRARIES} ${ATOMIC_LIBRARY})
|
||||
target_include_directories(fishlib PRIVATE
|
||||
${CURSES_INCLUDE_DIRS})
|
||||
|
||||
# Define fish.
|
||||
add_executable(fish src/fish.cpp)
|
||||
fish_link_deps_and_sign(fish)
|
||||
|
||||
# Define fish_indent.
|
||||
add_executable(fish_indent
|
||||
src/fish_indent.cpp)
|
||||
fish_link_deps_and_sign(fish_indent)
|
||||
|
||||
# Define fish_key_reader.
|
||||
add_executable(fish_key_reader
|
||||
src/fish_key_reader.cpp)
|
||||
fish_link_deps_and_sign(fish_key_reader)
|
||||
|
||||
# Set up the docs.
|
||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -95,7 +95,7 @@ version = "0.2.0"
|
|||
source = "git+https://github.com/fish-shell/fast-float-rust?branch=fish#9590c33a3f166a3533ba1cbb7a03e1105acec034"
|
||||
|
||||
[[package]]
|
||||
name = "fish-rust"
|
||||
name = "fish"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
|
|
16
Cargo.toml
16
Cargo.toml
|
@ -14,7 +14,7 @@ edition = "2021"
|
|||
overflow-checks = true
|
||||
|
||||
[package]
|
||||
name = "fish-rust"
|
||||
name = "fish"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
@ -50,10 +50,22 @@ cc = "1.0.83"
|
|||
rsconf = "0.1.1"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
crate-type = ["rlib"]
|
||||
path = "fish-rust/src/lib.rs"
|
||||
doctest = false
|
||||
|
||||
[[bin]]
|
||||
name = "fish"
|
||||
path = "fish-rust/src/bin/fish.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "fish_indent"
|
||||
path = "fish-rust/src/bin/fish_indent.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "fish_key_reader"
|
||||
path = "fish-rust/src/bin/fish_key_reader.rs"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
benchmark = []
|
||||
|
|
|
@ -77,7 +77,7 @@ function(FISH_TRY_CREATE_DIRS)
|
|||
endforeach()
|
||||
endfunction(FISH_TRY_CREATE_DIRS)
|
||||
|
||||
install(TARGETS ${PROGRAMS}
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS ${PROGRAMS}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
DESTINATION ${bindir})
|
||||
|
|
|
@ -21,7 +21,7 @@ else()
|
|||
)
|
||||
endif()
|
||||
|
||||
set(fish_rust_target "fish-rust")
|
||||
set(fish_rust_target "fish")
|
||||
|
||||
set(FISH_CRATE_FEATURES)
|
||||
if(NOT DEFINED CARGO_FLAGS)
|
||||
|
@ -36,7 +36,7 @@ endif()
|
|||
|
||||
corrosion_import_crate(
|
||||
MANIFEST_PATH "${CMAKE_SOURCE_DIR}/Cargo.toml"
|
||||
CRATES "fish-rust"
|
||||
CRATES "fish"
|
||||
"${FISH_CRATE_FEATURES}"
|
||||
FLAGS "${CARGO_FLAGS}"
|
||||
)
|
||||
|
@ -56,7 +56,6 @@ endif()
|
|||
|
||||
# CMAKE_BINARY_DIR can include symlinks, since we want to compare this to the dir fish is executed in we need to canonicalize it.
|
||||
file(REAL_PATH "${CMAKE_BINARY_DIR}" fish_binary_dir)
|
||||
|
||||
string(JOIN "," CURSES_LIBRARY_LIST ${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY})
|
||||
|
||||
# Tell Cargo where our build directory is so it can find config.h.
|
||||
|
@ -72,5 +71,3 @@ set(VARS_FOR_CARGO
|
|||
"LOCALEDIR=${CMAKE_INSTALL_FULL_LOCALEDIR}"
|
||||
"CURSES_LIBRARY_LIST=${CURSES_LIBRARY_LIST}"
|
||||
)
|
||||
|
||||
corrosion_set_env_vars(${fish_rust_target} ${VARS_FOR_CARGO})
|
||||
|
|
|
@ -159,7 +159,7 @@ endif()
|
|||
|
||||
add_test(
|
||||
NAME "cargo-test"
|
||||
COMMAND env ${VARS_FOR_CARGO} cargo test ${CARGO_FLAGS} --package fish-rust --target-dir ${rust_target_dir} ${cargo_target_opt}
|
||||
COMMAND env ${VARS_FOR_CARGO} cargo test ${CARGO_FLAGS} --package fish --target-dir ${rust_target_dir} ${cargo_target_opt}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
set_tests_properties("cargo-test" PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
|
||||
|
|
|
@ -45,7 +45,7 @@ ENV \
|
|||
RUSTFLAGS=-Zsanitizer=address \
|
||||
CC=clang \
|
||||
CXX=clang++ \
|
||||
CXXFLAGS="-fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -DFISH_CI_SAN" \
|
||||
CXXFLAGS=-DFISH_CI_SAN \
|
||||
ASAN_OPTIONS=check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1 \
|
||||
LSAN_OPTIONS=verbosity=0:log_threads=0:use_tls=1:print_suppressions=0:suppressions=/fish-source/build_tools/lsan_suppressions.txt \
|
||||
FISH_CI_SAN=1
|
||||
|
|
|
@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
use fish::{
|
||||
ast::Ast,
|
||||
builtins::shared::{
|
||||
BUILTIN_ERR_MISSING, BUILTIN_ERR_UNKNOWN, STATUS_CMD_OK, STATUS_CMD_UNKNOWN,
|
||||
|
@ -25,17 +25,19 @@ use crate::{
|
|||
common::{
|
||||
escape, exit_without_destructors, get_executable_path,
|
||||
restore_term_foreground_process_group_for_exit, save_term_foreground_process_group,
|
||||
scoped_push_replacer, str2wcstring, wcs2string, PROFILING_ACTIVE, PROGRAM_NAME,
|
||||
scoped_push_replacer, str2wcstring, wcs2string, PACKAGE_NAME, PROFILING_ACTIVE,
|
||||
PROGRAM_NAME,
|
||||
},
|
||||
env::Statuses,
|
||||
env::{
|
||||
environment::{env_init, EnvStack, Environment},
|
||||
ConfigPaths, EnvMode,
|
||||
},
|
||||
eprintf,
|
||||
event::{self, Event},
|
||||
fds::set_cloexec,
|
||||
flog::{self, activate_flog_categories_by_pattern, set_flog_file_fd, FLOG, FLOGF},
|
||||
function, future_feature_flags as features, history,
|
||||
fprintf, function, future_feature_flags as features, history,
|
||||
history::start_private_mode,
|
||||
io::IoChain,
|
||||
libc::setlinebuf,
|
||||
|
@ -45,6 +47,7 @@ use crate::{
|
|||
parse_util::parse_util_detect_errors_in_ast,
|
||||
parser::{BlockType, Parser},
|
||||
path::path_get_config,
|
||||
printf,
|
||||
proc::{
|
||||
get_login, is_interactive_session, mark_login, mark_no_exec, proc_init,
|
||||
set_interactive_session,
|
||||
|
@ -65,11 +68,6 @@ use std::path::{Path, PathBuf};
|
|||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
// FIXME: when the crate is actually called fish and not fish-rust, read this from cargo
|
||||
// See: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
|
||||
// for reference
|
||||
pub const PACKAGE_NAME: &str = "fish"; // env!("CARGO_PKG_NAME");
|
||||
|
||||
// FIXME: the following should just use env!(), this is to make `cargo test` work without CMake for now
|
||||
const DOC_DIR: &str = {
|
||||
match option_env!("DOCDIR") {
|
||||
|
@ -341,7 +339,7 @@ fn run_command_list(parser: &Parser, cmds: &[OsString]) -> i32 {
|
|||
}
|
||||
|
||||
fn fish_parse_opt(args: &mut [WString], opts: &mut FishCmdOpts) -> usize {
|
||||
use crate::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t::*};
|
||||
use fish::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t::*};
|
||||
|
||||
const RUSAGE_ARG: char = 1 as char;
|
||||
const PRINT_DEBUG_CATEGORIES_ARG: char = 2 as char;
|
||||
|
@ -436,7 +434,7 @@ fn fish_parse_opt(args: &mut [WString], opts: &mut FishCmdOpts) -> usize {
|
|||
'v' => {
|
||||
printf!(
|
||||
"%s",
|
||||
wgettext_fmt!("%s, version %s\n", PACKAGE_NAME, crate::BUILD_VERSION)
|
||||
wgettext_fmt!("%s, version %s\n", PACKAGE_NAME, fish::BUILD_VERSION)
|
||||
);
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
@ -491,8 +489,7 @@ fn cstr_from_osstr(s: &OsStr) -> CString {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn fish_main() -> i32 {
|
||||
fn main() {
|
||||
let mut args: Vec<WString> = env::args_os()
|
||||
.map(|osstr| str2wcstring(osstr.as_bytes()))
|
||||
.collect();
|
||||
|
@ -633,7 +630,7 @@ extern "C" fn fish_main() -> i32 {
|
|||
}
|
||||
features::set_from_string(opts.features.as_utfstr());
|
||||
proc_init();
|
||||
crate::env::misc_init();
|
||||
fish::env::misc_init();
|
||||
reader_init();
|
||||
|
||||
let parser = Parser::principal_parser();
|
||||
|
@ -706,7 +703,7 @@ extern "C" fn fish_main() -> i32 {
|
|||
"no-execute mode enabled and no script given. Exiting"
|
||||
);
|
||||
// above line should always exit
|
||||
return libc::EXIT_FAILURE;
|
||||
std::process::exit(libc::EXIT_FAILURE);
|
||||
}
|
||||
res = reader_read(parser, libc::STDIN_FILENO, &IoChain::new());
|
||||
} else {
|
|
@ -7,37 +7,40 @@ use std::sync::atomic::Ordering;
|
|||
|
||||
use libc::{LC_ALL, STDOUT_FILENO};
|
||||
|
||||
use crate::ast::{
|
||||
use fish::ast::{
|
||||
self, Ast, Category, Leaf, List, Node, NodeVisitor, SourceRangeList, Traversal, Type,
|
||||
};
|
||||
use crate::builtins::shared::{STATUS_CMD_ERROR, STATUS_CMD_OK};
|
||||
use crate::common::{
|
||||
use fish::builtins::shared::{STATUS_CMD_ERROR, STATUS_CMD_OK};
|
||||
use fish::common::{
|
||||
str2wcstring, unescape_string, wcs2string, wcs2zstring, UnescapeFlags, UnescapeStringStyle,
|
||||
PROGRAM_NAME,
|
||||
};
|
||||
use crate::env::env_init;
|
||||
use crate::env::environment::Environment;
|
||||
use crate::env::EnvStack;
|
||||
use crate::expand::INTERNAL_SEPARATOR;
|
||||
use crate::fds::set_cloexec;
|
||||
use fish::env::env_init;
|
||||
use fish::env::environment::Environment;
|
||||
use fish::env::EnvStack;
|
||||
use fish::eprintf;
|
||||
use fish::expand::INTERNAL_SEPARATOR;
|
||||
use fish::fds::set_cloexec;
|
||||
use fish::fprintf;
|
||||
#[allow(unused_imports)]
|
||||
use crate::future::{IsOkAnd, IsSomeAnd, IsSorted};
|
||||
use crate::global_safety::RelaxedAtomicBool;
|
||||
use crate::highlight::{colorize, highlight_shell, HighlightRole, HighlightSpec};
|
||||
use crate::libc::setlinebuf;
|
||||
use crate::operation_context::OperationContext;
|
||||
use crate::parse_constants::{ParseTokenType, ParseTreeFlags, SourceRange};
|
||||
use crate::parse_util::parse_util_compute_indents;
|
||||
use crate::print_help::print_help;
|
||||
use crate::threads;
|
||||
use crate::tokenizer::{TokenType, Tokenizer, TOK_SHOW_BLANK_LINES, TOK_SHOW_COMMENTS};
|
||||
use crate::topic_monitor::topic_monitor_init;
|
||||
use crate::wchar::prelude::*;
|
||||
use crate::wcstringutil::count_preceding_backslashes;
|
||||
use crate::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t};
|
||||
use crate::wutil::perror;
|
||||
use crate::wutil::{fish_iswalnum, write_to_fd};
|
||||
use crate::{
|
||||
use fish::future::{IsOkAnd, IsSomeAnd, IsSorted};
|
||||
use fish::global_safety::RelaxedAtomicBool;
|
||||
use fish::highlight::{colorize, highlight_shell, HighlightRole, HighlightSpec};
|
||||
use fish::libc::setlinebuf;
|
||||
use fish::operation_context::OperationContext;
|
||||
use fish::parse_constants::{ParseTokenType, ParseTreeFlags, SourceRange};
|
||||
use fish::parse_util::parse_util_compute_indents;
|
||||
use fish::print_help::print_help;
|
||||
use fish::printf;
|
||||
use fish::threads;
|
||||
use fish::tokenizer::{TokenType, Tokenizer, TOK_SHOW_BLANK_LINES, TOK_SHOW_COMMENTS};
|
||||
use fish::topic_monitor::topic_monitor_init;
|
||||
use fish::wchar::prelude::*;
|
||||
use fish::wcstringutil::count_preceding_backslashes;
|
||||
use fish::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t};
|
||||
use fish::wutil::perror;
|
||||
use fish::wutil::{fish_iswalnum, write_to_fd};
|
||||
use fish::{
|
||||
flog::{self, activate_flog_categories_by_pattern, set_flog_file_fd},
|
||||
future_feature_flags,
|
||||
};
|
||||
|
@ -728,8 +731,7 @@ fn char_is_escaped(text: &wstr, idx: usize) -> bool {
|
|||
count_preceding_backslashes(text, idx) % 2 == 1
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn fish_indent_main() -> i32 {
|
||||
fn main() {
|
||||
PROGRAM_NAME.set(L!("fish_indent")).unwrap();
|
||||
|
||||
topic_monitor_init();
|
||||
|
@ -804,7 +806,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
'P' => DUMP_PARSE_TREE.store(true),
|
||||
'h' => {
|
||||
print_help("fish_indent");
|
||||
return STATUS_CMD_OK.unwrap();
|
||||
std::process::exit(STATUS_CMD_OK.unwrap());
|
||||
}
|
||||
'v' => {
|
||||
printf!(
|
||||
|
@ -812,10 +814,10 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
wgettext_fmt!(
|
||||
"%s, version %s\n",
|
||||
PROGRAM_NAME.get().unwrap(),
|
||||
crate::BUILD_VERSION
|
||||
fish::BUILD_VERSION
|
||||
)
|
||||
);
|
||||
return STATUS_CMD_OK.unwrap();
|
||||
std::process::exit(STATUS_CMD_OK.unwrap());
|
||||
}
|
||||
'w' => output_type = OutputType::File,
|
||||
'i' => do_indent = false,
|
||||
|
@ -838,7 +840,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
'o' => {
|
||||
debug_output = Some(w.woptarg.unwrap());
|
||||
}
|
||||
_ => return STATUS_CMD_ERROR.unwrap(),
|
||||
_ => std::process::exit(STATUS_CMD_ERROR.unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -854,7 +856,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
if file.is_null() {
|
||||
eprintf!("Could not open file %s\n", debug_output);
|
||||
perror("fopen");
|
||||
return -1;
|
||||
std::process::exit(-1);
|
||||
}
|
||||
let fd = unsafe { libc::fileno(file) };
|
||||
set_cloexec(fd, true);
|
||||
|
@ -876,11 +878,11 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
PROGRAM_NAME.get().unwrap()
|
||||
)
|
||||
);
|
||||
return STATUS_CMD_ERROR.unwrap();
|
||||
std::process::exit(STATUS_CMD_ERROR.unwrap());
|
||||
}
|
||||
match read_file(stdin()) {
|
||||
Ok(s) => src = s,
|
||||
Err(()) => return STATUS_CMD_ERROR.unwrap(),
|
||||
Err(()) => std::process::exit(STATUS_CMD_ERROR.unwrap()),
|
||||
}
|
||||
} else {
|
||||
let arg = args[i];
|
||||
|
@ -888,7 +890,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
Ok(file) => {
|
||||
match read_file(file) {
|
||||
Ok(s) => src = s,
|
||||
Err(()) => return STATUS_CMD_ERROR.unwrap(),
|
||||
Err(()) => std::process::exit(STATUS_CMD_ERROR.unwrap()),
|
||||
}
|
||||
output_location = arg;
|
||||
}
|
||||
|
@ -897,7 +899,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
"%s",
|
||||
wgettext_fmt!("Opening \"%s\" failed: %s\n", arg, err.to_string())
|
||||
);
|
||||
return STATUS_CMD_ERROR.unwrap();
|
||||
std::process::exit(STATUS_CMD_ERROR.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -942,7 +944,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
err.to_string()
|
||||
)
|
||||
);
|
||||
return STATUS_CMD_ERROR.unwrap();
|
||||
std::process::exit(STATUS_CMD_ERROR.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -972,7 +974,7 @@ extern "C" fn fish_indent_main() -> i32 {
|
|||
let _ = write_to_fd(&colored_output, STDOUT_FILENO);
|
||||
i += 1;
|
||||
}
|
||||
retval
|
||||
std::process::exit(retval)
|
||||
}
|
||||
|
||||
static DUMP_PARSE_TREE: RelaxedAtomicBool = RelaxedAtomicBool::new(false);
|
|
@ -15,16 +15,19 @@ use std::{
|
|||
use libc::{STDIN_FILENO, TCSANOW, VEOF, VINTR};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use crate::future::IsSomeAnd;
|
||||
use crate::{
|
||||
use fish::future::IsSomeAnd;
|
||||
use fish::{
|
||||
builtins::shared::BUILTIN_ERR_UNKNOWN,
|
||||
common::{scoped_push_replacer, shell_modes, str2wcstring, PROGRAM_NAME},
|
||||
env::env_init,
|
||||
eprintf,
|
||||
fallback::fish_wcwidth,
|
||||
fprintf,
|
||||
input::input_terminfo_get_name,
|
||||
input_common::{CharEvent, InputEventQueue, InputEventQueuer},
|
||||
parser::Parser,
|
||||
print_help::print_help,
|
||||
printf,
|
||||
proc::set_interactive_session,
|
||||
reader::{
|
||||
check_exit_loop_maybe_warning, reader_init, reader_test_and_clear_interrupted,
|
||||
|
@ -335,7 +338,7 @@ fn parse_flags(continuous_mode: &mut bool, verbose: &mut bool) -> bool {
|
|||
wgettext_fmt!(
|
||||
"%ls, version %s\n",
|
||||
PROGRAM_NAME.get().unwrap(),
|
||||
crate::BUILD_VERSION
|
||||
fish::BUILD_VERSION
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -366,19 +369,18 @@ fn parse_flags(continuous_mode: &mut bool, verbose: &mut bool) -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn fish_key_reader_main() -> i32 {
|
||||
fn main() {
|
||||
PROGRAM_NAME.set(L!("fish_key_reader")).unwrap();
|
||||
let mut continuous_mode = false;
|
||||
let mut verbose = false;
|
||||
|
||||
if !parse_flags(&mut continuous_mode, &mut verbose) {
|
||||
return 1;
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if unsafe { libc::isatty(STDIN_FILENO) } == 0 {
|
||||
eprintf!("Stdin must be attached to a tty.\n");
|
||||
return 1;
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
setup_and_process_keys(continuous_mode, verbose);
|
|
@ -31,6 +31,8 @@ use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};
|
|||
use std::sync::{Arc, Mutex, MutexGuard, TryLockError};
|
||||
use std::time;
|
||||
|
||||
pub const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
|
||||
|
||||
// Highest legal ASCII value.
|
||||
pub const ASCII_MAX: char = 127 as char;
|
||||
|
||||
|
@ -1177,7 +1179,7 @@ pub fn cstr2wcstring(input: &[u8]) -> WString {
|
|||
str2wcstring(&input[0..strlen])
|
||||
}
|
||||
|
||||
pub fn charptr2wcstring(input: *const libc::c_char) -> WString {
|
||||
pub(crate) fn charptr2wcstring(input: *const libc::c_char) -> WString {
|
||||
let input: &[u8] = unsafe {
|
||||
let strlen = libc::strlen(input);
|
||||
slice::from_raw_parts(input.cast(), strlen)
|
||||
|
@ -2144,21 +2146,24 @@ macro_rules! err {
|
|||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fprintf {
|
||||
($fd:expr, $format:expr $(, $arg:expr)* $(,)?) => {
|
||||
{
|
||||
let wide = crate::wutil::sprintf!($format, $( $arg ),*);
|
||||
crate::wutil::wwrite_to_fd(&wide, $fd);
|
||||
let wide = $crate::wutil::sprintf!($format, $( $arg ),*);
|
||||
$crate::wutil::wwrite_to_fd(&wide, $fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! printf {
|
||||
($format:expr $(, $arg:expr)* $(,)?) => {
|
||||
fprintf!(libc::STDOUT_FILENO, $format $(, $arg)*)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! eprintf {
|
||||
($format:expr $(, $arg:expr)* $(,)?) => {
|
||||
fprintf!(libc::STDERR_FILENO, $format $(, $arg)*)
|
||||
|
|
|
@ -724,7 +724,7 @@ fn fork_child_for_process(
|
|||
job.job_id().as_num(),
|
||||
narrow_cmd.as_ptr(),
|
||||
narrow_argv0.as_ptr(),
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,12 +172,13 @@ pub fn flog_impl(s: &str) {
|
|||
}
|
||||
|
||||
/// The entry point for flogging.
|
||||
#[macro_export]
|
||||
macro_rules! FLOG {
|
||||
($category:ident, $($elem:expr),+ $(,)*) => {
|
||||
if crate::flog::categories::$category.enabled.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
if $crate::flog::categories::$category.enabled.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
#[allow(unused_imports)]
|
||||
use crate::flog::{FloggableDisplay, FloggableDebug};
|
||||
let mut vs = vec![format!("{}:", crate::flog::categories::$category.name)];
|
||||
use $crate::flog::{FloggableDisplay, FloggableDebug};
|
||||
let mut vs = vec![format!("{}:", $crate::flog::categories::$category.name)];
|
||||
$(
|
||||
{
|
||||
vs.push($elem.to_flog_str())
|
||||
|
@ -186,26 +187,28 @@ macro_rules! FLOG {
|
|||
// We don't use locking here so we have to append our own newline to avoid multiple writes.
|
||||
let mut v = vs.join(" ");
|
||||
v.push('\n');
|
||||
crate::flog::flog_impl(&v);
|
||||
$crate::flog::flog_impl(&v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! FLOGF {
|
||||
($category:ident, $fmt: expr, $($elem:expr),+ $(,)*) => {
|
||||
crate::flog::FLOG!($category, crate::wutil::sprintf!($fmt, $($elem),*))
|
||||
$crate::flog::FLOG!($category, $crate::wutil::sprintf!($fmt, $($elem),*))
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! should_flog {
|
||||
($category:ident) => {
|
||||
crate::flog::categories::$category
|
||||
$crate::flog::categories::$category
|
||||
.enabled
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use {should_flog, FLOG, FLOGF};
|
||||
pub use {should_flog, FLOG, FLOGF};
|
||||
|
||||
/// For each category, if its name matches the wildcard, set its enabled to the given sense.
|
||||
fn apply_one_wildcard(wc_esc: &wstr, sense: bool) {
|
||||
|
|
|
@ -46,7 +46,7 @@ fn strlen_safe(s: *const libc::c_char) -> usize {
|
|||
}
|
||||
|
||||
/// Report the error code for a failed setpgid call.
|
||||
pub fn report_setpgid_error(
|
||||
pub(crate) fn report_setpgid_error(
|
||||
err: i32,
|
||||
is_parent: bool,
|
||||
pid: pid_t,
|
||||
|
@ -243,7 +243,7 @@ pub fn execute_fork() -> pid_t {
|
|||
exit_without_destructors(1)
|
||||
}
|
||||
|
||||
pub fn safe_report_exec_error(
|
||||
pub(crate) fn safe_report_exec_error(
|
||||
err: i32,
|
||||
actual_cmd: *const c_char,
|
||||
argvv: *const *const c_char,
|
||||
|
|
|
@ -162,7 +162,7 @@ impl PosixSpawner {
|
|||
}
|
||||
|
||||
// Attempt to spawn a new process.
|
||||
pub fn spawn(
|
||||
pub(crate) fn spawn(
|
||||
&mut self,
|
||||
cmd: *const c_char,
|
||||
argv: *const *mut c_char,
|
||||
|
|
|
@ -28,83 +28,80 @@ pub const BUILD_VERSION: &str = match option_env!("FISH_BUILD_VERSION") {
|
|||
};
|
||||
|
||||
#[macro_use]
|
||||
mod common;
|
||||
pub mod common;
|
||||
|
||||
mod abbrs;
|
||||
mod ast;
|
||||
mod autoload;
|
||||
mod builtins;
|
||||
mod color;
|
||||
mod complete;
|
||||
mod curses;
|
||||
mod editable_line;
|
||||
mod env;
|
||||
mod env_dispatch;
|
||||
mod env_universal_common;
|
||||
mod event;
|
||||
mod exec;
|
||||
mod expand;
|
||||
mod fallback;
|
||||
mod fd_monitor;
|
||||
mod fd_readable_set;
|
||||
mod fds;
|
||||
mod fish;
|
||||
mod fish_indent;
|
||||
mod fish_key_reader;
|
||||
mod flog;
|
||||
mod fork_exec;
|
||||
mod function;
|
||||
mod future;
|
||||
mod future_feature_flags;
|
||||
mod global_safety;
|
||||
mod highlight;
|
||||
mod history;
|
||||
mod input;
|
||||
mod input_common;
|
||||
mod io;
|
||||
mod job_group;
|
||||
mod kill;
|
||||
pub mod abbrs;
|
||||
pub mod ast;
|
||||
pub mod autoload;
|
||||
pub mod builtins;
|
||||
pub mod color;
|
||||
pub mod complete;
|
||||
pub mod curses;
|
||||
pub mod editable_line;
|
||||
pub mod env;
|
||||
pub mod env_dispatch;
|
||||
pub mod env_universal_common;
|
||||
pub mod event;
|
||||
pub mod exec;
|
||||
pub mod expand;
|
||||
pub mod fallback;
|
||||
pub mod fd_monitor;
|
||||
pub mod fd_readable_set;
|
||||
pub mod fds;
|
||||
pub mod flog;
|
||||
pub mod fork_exec;
|
||||
pub mod function;
|
||||
pub mod future;
|
||||
pub mod future_feature_flags;
|
||||
pub mod global_safety;
|
||||
pub mod highlight;
|
||||
pub mod history;
|
||||
pub mod input;
|
||||
pub mod input_common;
|
||||
pub mod io;
|
||||
pub mod job_group;
|
||||
pub mod kill;
|
||||
#[allow(non_snake_case)]
|
||||
mod libc;
|
||||
mod locale;
|
||||
mod nix;
|
||||
mod null_terminated_array;
|
||||
mod operation_context;
|
||||
mod output;
|
||||
mod pager;
|
||||
mod parse_constants;
|
||||
mod parse_execution;
|
||||
mod parse_tree;
|
||||
mod parse_util;
|
||||
mod parser;
|
||||
mod parser_keywords;
|
||||
mod path;
|
||||
mod pointer;
|
||||
mod print_help;
|
||||
mod proc;
|
||||
mod re;
|
||||
mod reader;
|
||||
mod reader_history_search;
|
||||
mod redirection;
|
||||
mod screen;
|
||||
mod signal;
|
||||
mod termsize;
|
||||
mod threads;
|
||||
mod timer;
|
||||
mod tinyexpr;
|
||||
mod tokenizer;
|
||||
mod topic_monitor;
|
||||
mod trace;
|
||||
mod universal_notifier;
|
||||
mod util;
|
||||
mod wait_handle;
|
||||
mod wchar;
|
||||
mod wchar_ext;
|
||||
mod wcstringutil;
|
||||
mod wgetopt;
|
||||
mod widecharwidth;
|
||||
mod wildcard;
|
||||
mod wutil;
|
||||
pub mod libc;
|
||||
pub mod locale;
|
||||
pub mod nix;
|
||||
pub mod null_terminated_array;
|
||||
pub mod operation_context;
|
||||
pub mod output;
|
||||
pub mod pager;
|
||||
pub mod parse_constants;
|
||||
pub mod parse_execution;
|
||||
pub mod parse_tree;
|
||||
pub mod parse_util;
|
||||
pub mod parser;
|
||||
pub mod parser_keywords;
|
||||
pub mod path;
|
||||
pub mod pointer;
|
||||
pub mod print_help;
|
||||
pub mod proc;
|
||||
pub mod re;
|
||||
pub mod reader;
|
||||
pub mod reader_history_search;
|
||||
pub mod redirection;
|
||||
pub mod screen;
|
||||
pub mod signal;
|
||||
pub mod termsize;
|
||||
pub mod threads;
|
||||
pub mod timer;
|
||||
pub mod tinyexpr;
|
||||
pub mod tokenizer;
|
||||
pub mod topic_monitor;
|
||||
pub mod trace;
|
||||
pub mod universal_notifier;
|
||||
pub mod util;
|
||||
pub mod wait_handle;
|
||||
pub mod wchar;
|
||||
pub mod wchar_ext;
|
||||
pub mod wcstringutil;
|
||||
pub mod wgetopt;
|
||||
pub mod widecharwidth;
|
||||
pub mod wildcard;
|
||||
pub mod wutil;
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(unused_imports)] // Easy way to suppress warnings while we have two testing modes.
|
||||
|
|
|
@ -127,7 +127,7 @@ impl OwningNullTerminatedArray {
|
|||
}
|
||||
|
||||
/// Return the length of a null-terminated array of pointers to something.
|
||||
pub fn null_terminated_array_length<T>(mut arr: *const *const T) -> usize {
|
||||
pub(crate) fn null_terminated_array_length<T>(mut arr: *const *const T) -> usize {
|
||||
let mut len = 0;
|
||||
// Safety: caller must ensure that arr is null-terminated.
|
||||
unsafe {
|
||||
|
|
|
@ -10,24 +10,25 @@ pub use widestring::{Utf32Str as wstr, Utf32String as WString};
|
|||
/// Pull in our extensions.
|
||||
pub use crate::wchar_ext::IntoCharIter;
|
||||
|
||||
pub(crate) mod prelude {
|
||||
pub(crate) use crate::{
|
||||
pub mod prelude {
|
||||
pub use crate::{
|
||||
wchar::{wstr, IntoCharIter, WString, L},
|
||||
wchar_ext::{ToWString, WExt},
|
||||
wutil::{sprintf, wgettext, wgettext_fmt, wgettext_maybe_fmt, wgettext_str},
|
||||
};
|
||||
pub(crate) use widestring_suffix::widestrs;
|
||||
pub use widestring_suffix::widestrs;
|
||||
}
|
||||
|
||||
/// Creates a wstr string slice, like the "L" prefix of C++.
|
||||
/// The result is of type wstr.
|
||||
/// It is NOT nul-terminated.
|
||||
#[macro_export]
|
||||
macro_rules! L {
|
||||
($string:expr) => {
|
||||
widestring::utf32str!($string)
|
||||
};
|
||||
}
|
||||
pub(crate) use L;
|
||||
pub use L;
|
||||
|
||||
/// A proc-macro for creating wide string literals using an L *suffix*.
|
||||
/// Example usage:
|
||||
|
|
|
@ -2,8 +2,7 @@ use std::collections::HashMap;
|
|||
use std::ffi::CString;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::common::{charptr2wcstring, truncate_at_nul, wcs2zstring};
|
||||
use crate::fish::PACKAGE_NAME;
|
||||
use crate::common::{charptr2wcstring, truncate_at_nul, wcs2zstring, PACKAGE_NAME};
|
||||
#[cfg(test)]
|
||||
use crate::tests::prelude::*;
|
||||
use crate::wchar::prelude::*;
|
||||
|
@ -130,38 +129,41 @@ pub fn wgettext_str(s: &wstr) -> &'static wstr {
|
|||
|
||||
/// Get a (possibly translated) string from a string literal.
|
||||
/// This returns a &'static wstr.
|
||||
#[macro_export]
|
||||
macro_rules! wgettext {
|
||||
($string:expr) => {
|
||||
crate::wutil::gettext::wgettext_static_str(widestring::utf32str!($string))
|
||||
$crate::wutil::gettext::wgettext_static_str(widestring::utf32str!($string))
|
||||
};
|
||||
}
|
||||
pub(crate) use wgettext;
|
||||
pub use wgettext;
|
||||
|
||||
/// Like wgettext, but applies a sprintf format string.
|
||||
/// The result is a WString.
|
||||
#[macro_export]
|
||||
macro_rules! wgettext_fmt {
|
||||
(
|
||||
$string:expr, // format string
|
||||
$($args:expr),+ // list of expressions
|
||||
$(,)? // optional trailing comma
|
||||
) => {
|
||||
crate::wutil::sprintf!(&crate::wutil::wgettext!($string), $($args),+)
|
||||
$crate::wutil::sprintf!(&$crate::wutil::wgettext!($string), $($args),+)
|
||||
};
|
||||
}
|
||||
pub(crate) use wgettext_fmt;
|
||||
pub use wgettext_fmt;
|
||||
|
||||
/// Like wgettext_fmt, but doesn't require an argument to format.
|
||||
/// For use in macros.
|
||||
#[macro_export]
|
||||
macro_rules! wgettext_maybe_fmt {
|
||||
(
|
||||
$string:expr // format string
|
||||
$(, $args:expr)* // list of expressions
|
||||
$(,)? // optional trailing comma
|
||||
) => {
|
||||
crate::wutil::sprintf!(&crate::wutil::wgettext!($string), $($args),*)
|
||||
$crate::wutil::sprintf!(&$crate::wutil::wgettext!($string), $($args),*)
|
||||
};
|
||||
}
|
||||
pub(crate) use wgettext_maybe_fmt;
|
||||
pub use wgettext_maybe_fmt;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
|
|
|
@ -20,8 +20,8 @@ use crate::wchar::{wstr, WString, L};
|
|||
use crate::wchar_ext::WExt;
|
||||
use crate::wcstringutil::{join_strings, split_string, wcs2string_callback};
|
||||
use errno::errno;
|
||||
pub(crate) use gettext::{wgettext, wgettext_fmt, wgettext_maybe_fmt, wgettext_str};
|
||||
pub(crate) use printf::sprintf;
|
||||
pub use gettext::{wgettext, wgettext_fmt, wgettext_maybe_fmt, wgettext_str};
|
||||
pub use printf::sprintf;
|
||||
use std::ffi::{CStr, OsStr};
|
||||
use std::fs::{self, canonicalize};
|
||||
use std::io::{self, Write};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Re-export sprintf macro.
|
||||
pub(crate) use printf_compat::sprintf;
|
||||
pub use printf_compat::sprintf;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
extern "C" int fish_main();
|
||||
|
||||
int main() { return fish_main(); }
|
|
@ -1,3 +0,0 @@
|
|||
extern "C" int fish_indent_main();
|
||||
|
||||
int main() { return fish_indent_main(); }
|
|
@ -1,3 +0,0 @@
|
|||
extern "C" int fish_key_reader_main();
|
||||
|
||||
int main() { return fish_key_reader_main(); }
|
Loading…
Reference in New Issue
Block a user