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