mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-22 13:18:59 +08:00
Remove parser library_data_pod_t
ffi workaround
We don't need to separate POD fields from the main parser libdata any more.
This commit is contained in:
parent
abf92fcbd1
commit
d90d924c8c
|
@ -253,9 +253,9 @@ fn source_config_in_directory(parser: &Parser, dir: &wstr) -> bool {
|
|||
|
||||
let cmd: WString = L!("builtin source ").to_owned() + escaped_pathname.as_utfstr();
|
||||
|
||||
parser.libdata_mut().pods.within_fish_init = true;
|
||||
parser.libdata_mut().within_fish_init = true;
|
||||
let _ = parser.eval(&cmd, &IoChain::new());
|
||||
parser.libdata_mut().pods.within_fish_init = false;
|
||||
parser.libdata_mut().within_fish_init = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -652,7 +652,7 @@ fn throwing_main() -> i32 {
|
|||
list.iter().map(|s| s.to_owned()).collect(),
|
||||
);
|
||||
res = run_command_list(parser, &opts.batch_cmds);
|
||||
parser.libdata_mut().pods.exit_current_script = false;
|
||||
parser.libdata_mut().exit_current_script = false;
|
||||
} else if my_optind == args.len() {
|
||||
// Implicitly interactive mode.
|
||||
if opts.no_exec && isatty(libc::STDIN_FILENO) {
|
||||
|
|
|
@ -330,7 +330,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
|||
// Don't enqueue a repaint if we're currently in the middle of one,
|
||||
// because that's an infinite loop.
|
||||
if matches!(cmd, rl::RepaintMode | rl::ForceRepaint | rl::Repaint) {
|
||||
if parser.libdata().pods.is_repaint {
|
||||
if parser.libdata().is_repaint {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -496,12 +496,9 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
|
|||
});
|
||||
|
||||
// Prevent accidental recursion (see #6171).
|
||||
if !parser.libdata().pods.builtin_complete_current_commandline {
|
||||
if !parser.libdata().builtin_complete_current_commandline {
|
||||
if !have_do_complete_param {
|
||||
parser
|
||||
.libdata_mut()
|
||||
.pods
|
||||
.builtin_complete_current_commandline = true;
|
||||
parser.libdata_mut().builtin_complete_current_commandline = true;
|
||||
}
|
||||
|
||||
let (mut comp, _needs_load) = crate::complete::complete(
|
||||
|
@ -556,10 +553,7 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
|
|||
streams.out.append(faux_cmdline_with_completion);
|
||||
}
|
||||
|
||||
parser
|
||||
.libdata_mut()
|
||||
.pods
|
||||
.builtin_complete_current_commandline = false;
|
||||
parser.libdata_mut().builtin_complete_current_commandline = false;
|
||||
}
|
||||
} else if path.is_empty()
|
||||
&& gnu_opt.is_empty()
|
||||
|
|
|
@ -25,7 +25,7 @@ pub fn eval(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> Opt
|
|||
// buffer in that case.
|
||||
let mut stdout_fill = None;
|
||||
if streams.out_is_piped {
|
||||
match IoBufferfill::create_opts(parser.libdata().pods.read_limit, STDOUT_FILENO) {
|
||||
match IoBufferfill::create_opts(parser.libdata().read_limit, STDOUT_FILENO) {
|
||||
Err(_) => {
|
||||
// We were unable to create a pipe, probably fd exhaustion.
|
||||
return STATUS_CMD_ERROR;
|
||||
|
@ -40,7 +40,7 @@ pub fn eval(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> Opt
|
|||
// Of course the same applies to stderr.
|
||||
let mut stderr_fill = None;
|
||||
if streams.err_is_piped {
|
||||
match IoBufferfill::create_opts(parser.libdata().pods.read_limit, STDERR_FILENO) {
|
||||
match IoBufferfill::create_opts(parser.libdata().read_limit, STDERR_FILENO) {
|
||||
Err(_) => {
|
||||
// We were unable to create a pipe, probably fd exhaustion.
|
||||
return STATUS_CMD_ERROR;
|
||||
|
|
|
@ -12,7 +12,7 @@ pub fn exit(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> Opt
|
|||
// TODO: in concurrent mode this won't successfully exit a pipeline, as there are other parsers
|
||||
// involved. That is, `exit | sleep 1000` may not exit as hoped. Need to rationalize what
|
||||
// behavior we want here.
|
||||
parser.libdata_mut().pods.exit_current_script = true;
|
||||
parser.libdata_mut().exit_current_script = true;
|
||||
|
||||
return Some(retval);
|
||||
}
|
||||
|
|
|
@ -133,8 +133,8 @@ fn parse_cmd_opts(
|
|||
let e: EventDescription;
|
||||
if opt == 'j' && woptarg == "caller" {
|
||||
let libdata = parser.libdata();
|
||||
let caller_id = if libdata.pods.is_subshell {
|
||||
libdata.pods.caller_id
|
||||
let caller_id = if libdata.is_subshell {
|
||||
libdata.caller_id
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
|
|
@ -237,7 +237,7 @@ fn read_interactive(
|
|||
|
||||
let mline = {
|
||||
let _interactive = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_interactive, new_value),
|
||||
true,
|
||||
);
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ pub fn r#return(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) ->
|
|||
|
||||
// If we're not in a function, exit the current script (but not an interactive shell).
|
||||
if !has_function_block {
|
||||
let ld = &mut parser.libdata_mut().pods;
|
||||
let ld = &mut parser.libdata_mut();
|
||||
if !ld.is_interactive {
|
||||
ld.exit_current_script = true;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ pub fn r#return(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) ->
|
|||
}
|
||||
|
||||
// Mark a return in the libdata.
|
||||
parser.libdata_mut().pods.returning = true;
|
||||
parser.libdata_mut().returning = true;
|
||||
|
||||
return Some(retval);
|
||||
}
|
||||
|
|
|
@ -889,7 +889,7 @@ fn builtin_break_continue(
|
|||
}
|
||||
|
||||
// Mark the status in the libdata.
|
||||
parser.libdata_mut().pods.loop_status = if is_break {
|
||||
parser.libdata_mut().loop_status = if is_break {
|
||||
LoopStatus::breaks
|
||||
} else {
|
||||
LoopStatus::continues
|
||||
|
|
|
@ -466,7 +466,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> O
|
|||
}
|
||||
}
|
||||
STATUS_IS_COMMAND_SUB => {
|
||||
if parser.libdata().pods.is_subshell {
|
||||
if parser.libdata().is_subshell {
|
||||
return STATUS_CMD_OK;
|
||||
} else {
|
||||
return STATUS_CMD_ERROR;
|
||||
|
|
|
@ -620,7 +620,7 @@ impl<'ctx> Completer<'ctx> {
|
|||
// wraps "A=B x" (#3474, #7344). No need to do that when there is no parser: this happens only
|
||||
// for autosuggestions where we don't evaluate command substitutions or variable assignments.
|
||||
let _decrement = if let Some(parser) = self.ctx.maybe_parser() {
|
||||
let level = &mut parser.libdata_mut().pods.complete_recursion_level;
|
||||
let level = &mut parser.libdata_mut().complete_recursion_level;
|
||||
if *level >= 24 {
|
||||
FLOG!(
|
||||
error,
|
||||
|
@ -631,7 +631,7 @@ impl<'ctx> Completer<'ctx> {
|
|||
*level += 1;
|
||||
|
||||
Some(ScopeGuard::new((), |()| {
|
||||
let level = &mut parser.libdata_mut().pods.complete_recursion_level;
|
||||
let level = &mut parser.libdata_mut().complete_recursion_level;
|
||||
*level -= 1;
|
||||
}))
|
||||
} else {
|
||||
|
@ -1157,8 +1157,8 @@ impl<'ctx> Completer<'ctx> {
|
|||
let is_autosuggest = self.flags.autosuggestion;
|
||||
|
||||
let saved_state = if let Some(parser) = self.ctx.maybe_parser() {
|
||||
let saved_interactive = parser.libdata().pods.is_interactive;
|
||||
parser.libdata_mut().pods.is_interactive = false;
|
||||
let saved_interactive = parser.libdata().is_interactive;
|
||||
parser.libdata_mut().is_interactive = false;
|
||||
|
||||
Some((saved_interactive, parser.get_last_statuses()))
|
||||
} else {
|
||||
|
@ -1175,7 +1175,7 @@ impl<'ctx> Completer<'ctx> {
|
|||
|
||||
if let Some(parser) = self.ctx.maybe_parser() {
|
||||
let (saved_interactive, status) = saved_state.unwrap();
|
||||
parser.libdata_mut().pods.is_interactive = saved_interactive;
|
||||
parser.libdata_mut().is_interactive = saved_interactive;
|
||||
parser.set_last_statuses(status);
|
||||
}
|
||||
|
||||
|
|
19
src/event.rs
19
src/event.rs
|
@ -456,23 +456,18 @@ pub fn get_function_handlers(name: &wstr) -> EventHandlerList {
|
|||
/// allocated/initialized unless needed.
|
||||
fn fire_internal(parser: &Parser, event: &Event) {
|
||||
assert!(
|
||||
parser.libdata().pods.is_event >= 0,
|
||||
parser.libdata().is_event >= 0,
|
||||
"is_event should not be negative"
|
||||
);
|
||||
|
||||
// Suppress fish_trace during events.
|
||||
let is_event = parser.libdata().pods.is_event;
|
||||
let is_event = parser.libdata().is_event;
|
||||
let _inc_event = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_event, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_event, new_value),
|
||||
is_event + 1,
|
||||
);
|
||||
let _suppress_trace = scoped_push_replacer(
|
||||
|new_value| {
|
||||
std::mem::replace(
|
||||
&mut parser.libdata_mut().pods.suppress_fish_trace,
|
||||
new_value,
|
||||
)
|
||||
},
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().suppress_fish_trace, new_value),
|
||||
true,
|
||||
);
|
||||
|
||||
|
@ -504,11 +499,11 @@ fn fire_internal(parser: &Parser, event: &Event) {
|
|||
// Event handlers are not part of the main flow of code, so they are marked as
|
||||
// non-interactive.
|
||||
let saved_is_interactive =
|
||||
std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, false);
|
||||
std::mem::replace(&mut parser.libdata_mut().is_interactive, false);
|
||||
let saved_statuses = parser.get_last_statuses();
|
||||
let _cleanup = ScopeGuard::new((), |()| {
|
||||
parser.set_last_statuses(saved_statuses);
|
||||
parser.libdata_mut().pods.is_interactive = saved_is_interactive;
|
||||
parser.libdata_mut().is_interactive = saved_is_interactive;
|
||||
});
|
||||
|
||||
FLOG!(
|
||||
|
@ -536,7 +531,7 @@ fn fire_internal(parser: &Parser, event: &Event) {
|
|||
/// Fire all delayed events attached to the given parser.
|
||||
pub fn fire_delayed(parser: &Parser) {
|
||||
{
|
||||
let ld = &parser.libdata().pods;
|
||||
let ld = &parser.libdata();
|
||||
|
||||
// Do not invoke new event handlers from within event handlers.
|
||||
if ld.is_event != 0 {
|
||||
|
|
14
src/exec.rs
14
src/exec.rs
|
@ -652,7 +652,7 @@ fn run_internal_process_or_short_circuit(
|
|||
);
|
||||
if let Some(statuses) = j.get_statuses() {
|
||||
parser.set_last_statuses(statuses);
|
||||
parser.libdata_mut().pods.status_count += 1;
|
||||
parser.libdata_mut().status_count += 1;
|
||||
} else if j.flags().negate {
|
||||
// Special handling for `not set var (substitution)`.
|
||||
// If there is no status, but negation was requested,
|
||||
|
@ -950,7 +950,7 @@ fn function_restore_environment(parser: &Parser, block: BlockId) {
|
|||
parser.pop_block(block);
|
||||
|
||||
// If we returned due to a return statement, then stop returning now.
|
||||
parser.libdata_mut().pods.returning = false;
|
||||
parser.libdata_mut().returning = false;
|
||||
}
|
||||
|
||||
// The "performer" function of a block or function process.
|
||||
|
@ -1272,7 +1272,7 @@ fn exec_process_in_job(
|
|||
|
||||
if p.typ != ProcessType::block_node {
|
||||
// A simple `begin ... end` should not be considered an execution of a command.
|
||||
parser.libdata_mut().pods.exec_count += 1;
|
||||
parser.libdata_mut().exec_count += 1;
|
||||
}
|
||||
|
||||
let mut block_id = None;
|
||||
|
@ -1386,7 +1386,7 @@ fn allow_exec_with_background_jobs(parser: &Parser) -> bool {
|
|||
|
||||
// Compare run counts, so we only warn once.
|
||||
let current_run_count = reader_run_count();
|
||||
let last_exec_run_count = &mut parser.libdata_mut().pods.last_exec_run_counter;
|
||||
let last_exec_run_count = &mut parser.libdata_mut().last_exec_run_counter;
|
||||
if isatty(STDIN_FILENO) && current_run_count - 1 != *last_exec_run_count {
|
||||
print_exit_warning_for_jobs(&bgs);
|
||||
*last_exec_run_count = current_run_count;
|
||||
|
@ -1454,11 +1454,11 @@ fn exec_subshell_internal(
|
|||
) -> libc::c_int {
|
||||
parser.assert_can_execute();
|
||||
let _is_subshell = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_subshell, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_subshell, new_value),
|
||||
true,
|
||||
);
|
||||
let _read_limit = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.read_limit, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().read_limit, new_value),
|
||||
if is_subcmd {
|
||||
READ_BYTE_LIMIT.load(Ordering::Relaxed)
|
||||
} else {
|
||||
|
@ -1477,7 +1477,7 @@ fn exec_subshell_internal(
|
|||
|
||||
// IO buffer creation may fail (e.g. if we have too many open files to make a pipe), so this may
|
||||
// be null.
|
||||
let Ok(bufferfill) = IoBufferfill::create_opts(parser.libdata().pods.read_limit, STDOUT_FILENO)
|
||||
let Ok(bufferfill) = IoBufferfill::create_opts(parser.libdata().read_limit, STDOUT_FILENO)
|
||||
else {
|
||||
*break_expand = true;
|
||||
return STATUS_CMD_ERROR.unwrap();
|
||||
|
|
|
@ -270,7 +270,7 @@ impl<'a> ParseExecutionContext {
|
|||
return Some(EndExecutionReason::cancelled);
|
||||
}
|
||||
let parser = ctx.parser();
|
||||
let ld = &parser.libdata().pods;
|
||||
let ld = &parser.libdata();
|
||||
if ld.exit_current_script {
|
||||
return Some(EndExecutionReason::cancelled);
|
||||
}
|
||||
|
@ -1015,7 +1015,7 @@ impl<'a> ParseExecutionContext {
|
|||
);
|
||||
event::fire(ctx.parser(), evt.clone());
|
||||
|
||||
ctx.parser().libdata_mut().pods.loop_status = LoopStatus::normals;
|
||||
ctx.parser().libdata_mut().loop_status = LoopStatus::normals;
|
||||
|
||||
// Push and pop the block again and again to clear variables
|
||||
let fb = ctx.parser().push_block(Block::for_block());
|
||||
|
@ -1024,8 +1024,8 @@ impl<'a> ParseExecutionContext {
|
|||
|
||||
if self.check_end_execution(ctx) == Some(EndExecutionReason::control_flow) {
|
||||
// Handle break or continue.
|
||||
let do_break = ctx.parser().libdata().pods.loop_status == LoopStatus::breaks;
|
||||
ctx.parser().libdata_mut().pods.loop_status = LoopStatus::normals;
|
||||
let do_break = ctx.parser().libdata().loop_status == LoopStatus::breaks;
|
||||
ctx.parser().libdata_mut().loop_status = LoopStatus::normals;
|
||||
if do_break {
|
||||
break;
|
||||
}
|
||||
|
@ -1295,7 +1295,7 @@ impl<'a> ParseExecutionContext {
|
|||
}
|
||||
|
||||
// Push a while block and then check its cancellation reason.
|
||||
ctx.parser().libdata_mut().pods.loop_status = LoopStatus::normals;
|
||||
ctx.parser().libdata_mut().loop_status = LoopStatus::normals;
|
||||
|
||||
let wb = ctx.parser().push_block(Block::while_block());
|
||||
self.run_job_list(ctx, contents, Some(wb));
|
||||
|
@ -1304,8 +1304,8 @@ impl<'a> ParseExecutionContext {
|
|||
|
||||
if cancel_reason == Some(EndExecutionReason::control_flow) {
|
||||
// Handle break or continue.
|
||||
let do_break = ctx.parser().libdata().pods.loop_status == LoopStatus::breaks;
|
||||
ctx.parser().libdata_mut().pods.loop_status = LoopStatus::normals;
|
||||
let do_break = ctx.parser().libdata().loop_status == LoopStatus::breaks;
|
||||
ctx.parser().libdata_mut().loop_status = LoopStatus::normals;
|
||||
if do_break {
|
||||
break;
|
||||
} else {
|
||||
|
@ -1357,7 +1357,7 @@ impl<'a> ParseExecutionContext {
|
|||
NodeRef::new(self.pstree(), statement as *const ast::BlockStatement),
|
||||
);
|
||||
let err_code = err_code.unwrap();
|
||||
ctx.parser().libdata_mut().pods.status_count += 1;
|
||||
ctx.parser().libdata_mut().status_count += 1;
|
||||
ctx.parser().set_last_statuses(Statuses::just(err_code));
|
||||
|
||||
let errtext = errs.contents();
|
||||
|
@ -1661,7 +1661,7 @@ impl<'a> ParseExecutionContext {
|
|||
props.initial_background = job_is_background;
|
||||
{
|
||||
let parser = ctx.parser();
|
||||
let ld = &parser.libdata().pods;
|
||||
let ld = &parser.libdata();
|
||||
props.skip_notification =
|
||||
ld.is_subshell || parser.is_block() || ld.is_event != 0 || !parser.is_interactive();
|
||||
props.from_event_handler = ld.is_event != 0;
|
||||
|
@ -1673,9 +1673,7 @@ impl<'a> ParseExecutionContext {
|
|||
// which may be interested in the job that's populating it, via '--on-job-exit caller'. Record
|
||||
// the job ID here.
|
||||
let _caller_id = scoped_push_replacer(
|
||||
|new_value| {
|
||||
std::mem::replace(&mut ctx.parser().libdata_mut().pods.caller_id, new_value)
|
||||
},
|
||||
|new_value| std::mem::replace(&mut ctx.parser().libdata_mut().caller_id, new_value),
|
||||
job.internal_job_id,
|
||||
);
|
||||
|
||||
|
@ -1706,7 +1704,7 @@ impl<'a> ParseExecutionContext {
|
|||
// Ensure statuses are set (#7540).
|
||||
if let Some(statuses) = job.get_statuses() {
|
||||
parser.set_last_statuses(statuses);
|
||||
parser.libdata_mut().pods.status_count += 1;
|
||||
parser.libdata_mut().status_count += 1;
|
||||
}
|
||||
remove_job(parser, &job);
|
||||
}
|
||||
|
@ -1927,7 +1925,7 @@ impl<'a> ParseExecutionContext {
|
|||
} else {
|
||||
// This is a "real job" that gets its own pgroup.
|
||||
j.processes_mut()[0].leads_pgrp = true;
|
||||
let wants_terminal = ctx.parser().libdata().pods.is_event == 0;
|
||||
let wants_terminal = ctx.parser().libdata().is_event == 0;
|
||||
j.group = Some(JobGroup::create_with_job_control(
|
||||
j.command().to_owned(),
|
||||
wants_terminal,
|
||||
|
|
157
src/parser.rs
157
src/parser.rs
|
@ -216,8 +216,6 @@ impl ProfileItem {
|
|||
/// Miscellaneous data used to avoid recursion and others.
|
||||
#[derive(Default)]
|
||||
pub struct LibraryData {
|
||||
pub pods: library_data_pod_t,
|
||||
|
||||
/// The current filename we are evaluating, either from builtin source or on the command line.
|
||||
pub current_filename: Option<FilenameRef>,
|
||||
|
||||
|
@ -231,15 +229,72 @@ pub struct LibraryData {
|
|||
pub cwd_fd: Option<Arc<OwnedFd>>,
|
||||
|
||||
pub status_vars: StatusVars,
|
||||
|
||||
/// A counter incremented every time a command executes.
|
||||
pub exec_count: u64,
|
||||
|
||||
/// A counter incremented every time a command produces a $status.
|
||||
pub status_count: u64,
|
||||
|
||||
/// Last reader run count.
|
||||
pub last_exec_run_counter: u64,
|
||||
|
||||
/// Number of recursive calls to the internal completion function.
|
||||
pub complete_recursion_level: u32,
|
||||
|
||||
/// If set, we are currently within fish's initialization routines.
|
||||
pub within_fish_init: bool,
|
||||
|
||||
/// If we're currently repainting the commandline.
|
||||
/// Useful to stop infinite loops.
|
||||
pub is_repaint: bool,
|
||||
|
||||
/// Whether we called builtin_complete -C without parameter.
|
||||
pub builtin_complete_current_commandline: bool,
|
||||
|
||||
/// Whether we are currently cleaning processes.
|
||||
pub is_cleaning_procs: bool,
|
||||
|
||||
/// The internal job id of the job being populated, or 0 if none.
|
||||
/// This supports the '--on-job-exit caller' feature.
|
||||
pub caller_id: u64, // TODO should be InternalJobId
|
||||
|
||||
/// Whether we are running a subshell command.
|
||||
pub is_subshell: bool,
|
||||
|
||||
/// Whether we are running an event handler. This is not a bool because we keep count of the
|
||||
/// event nesting level.
|
||||
pub is_event: i32,
|
||||
|
||||
/// Whether we are currently interactive.
|
||||
pub is_interactive: bool,
|
||||
|
||||
/// Whether to suppress fish_trace output. This occurs in the prompt, event handlers, and key
|
||||
/// bindings.
|
||||
pub suppress_fish_trace: bool,
|
||||
|
||||
/// Whether we should break or continue the current loop.
|
||||
/// This is set by the 'break' and 'continue' commands.
|
||||
pub loop_status: LoopStatus,
|
||||
|
||||
/// Whether we should return from the current function.
|
||||
/// This is set by the 'return' command.
|
||||
pub returning: bool,
|
||||
|
||||
/// Whether we should stop executing.
|
||||
/// This is set by the 'exit' command, and unset after 'reader_read'.
|
||||
/// Note this only exits up to the "current script boundary." That is, a call to exit within a
|
||||
/// 'source' or 'read' command will only exit up to that command.
|
||||
pub exit_current_script: bool,
|
||||
|
||||
/// The read limit to apply to captured subshell output, or 0 for none.
|
||||
pub read_limit: usize,
|
||||
}
|
||||
|
||||
impl LibraryData {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
pods: library_data_pod_t {
|
||||
last_exec_run_counter: u64::MAX,
|
||||
..Default::default()
|
||||
},
|
||||
last_exec_run_counter: u64::MAX,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -572,15 +627,15 @@ impl Parser {
|
|||
);
|
||||
|
||||
// Check the exec count so we know if anything got executed.
|
||||
let prev_exec_count = self.libdata().pods.exec_count;
|
||||
let prev_status_count = self.libdata().pods.status_count;
|
||||
let prev_exec_count = self.libdata().exec_count;
|
||||
let prev_status_count = self.libdata().status_count;
|
||||
let reason =
|
||||
self.execution_context()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.eval_node(&op_ctx, node, Some(scope_block));
|
||||
let new_exec_count = self.libdata().pods.exec_count;
|
||||
let new_status_count = self.libdata().pods.status_count;
|
||||
let new_exec_count = self.libdata().exec_count;
|
||||
let new_status_count = self.libdata().status_count;
|
||||
|
||||
ScopeGuarding::commit(exc);
|
||||
self.pop_block(scope_block);
|
||||
|
@ -661,7 +716,7 @@ impl Parser {
|
|||
&user_presentable_path(&file, self.vars()),
|
||||
lineno
|
||||
));
|
||||
} else if self.libdata().pods.within_fish_init {
|
||||
} else if self.libdata().within_fish_init {
|
||||
prefix.push_utfstr(&wgettext_fmt!("Startup (line %d): ", lineno));
|
||||
} else {
|
||||
prefix.push_utfstr(&wgettext_fmt!("Standard input (line %d): ", lineno));
|
||||
|
@ -699,10 +754,14 @@ impl Parser {
|
|||
/// This supports 'status is-block'.
|
||||
pub fn is_block(&self) -> bool {
|
||||
// Note historically this has descended into 'source', unlike 'is_function'.
|
||||
self.blocks()
|
||||
.iter()
|
||||
.rev()
|
||||
.any(|b| ![BlockType::top, BlockType::subst].contains(&b.typ()))
|
||||
self.blocks().iter().rev().any(|b| {
|
||||
![
|
||||
BlockType::top,
|
||||
BlockType::subst,
|
||||
BlockType::variable_assignment,
|
||||
]
|
||||
.contains(&b.typ())
|
||||
})
|
||||
}
|
||||
|
||||
/// Return whether we have a breakpoint block.
|
||||
|
@ -1027,7 +1086,7 @@ impl Parser {
|
|||
/// Return if we are interactive, which means we are executing a command that the user typed in
|
||||
/// (and not, say, a prompt).
|
||||
pub fn is_interactive(&self) -> bool {
|
||||
self.libdata().pods.is_interactive
|
||||
self.libdata().is_interactive
|
||||
}
|
||||
|
||||
/// Return a string representing the current stack trace.
|
||||
|
@ -1206,7 +1265,7 @@ fn append_block_description_to_stack_trace(parser: &Parser, b: &Block, trace: &m
|
|||
b.src_lineno.unwrap_or(0),
|
||||
user_presentable_path(file, parser.vars())
|
||||
));
|
||||
} else if parser.libdata().pods.within_fish_init {
|
||||
} else if parser.libdata().within_fish_init {
|
||||
trace.push_str("\tcalled during startup\n");
|
||||
}
|
||||
}
|
||||
|
@ -1251,67 +1310,3 @@ pub enum LoopStatus {
|
|||
/// current loop block should be skipped
|
||||
continues,
|
||||
}
|
||||
|
||||
/// Plain-Old-Data components of `struct library_data_t` that can be shared over FFI
|
||||
#[derive(Default)]
|
||||
pub struct library_data_pod_t {
|
||||
/// A counter incremented every time a command executes.
|
||||
pub exec_count: u64,
|
||||
|
||||
/// A counter incremented every time a command produces a $status.
|
||||
pub status_count: u64,
|
||||
|
||||
/// Last reader run count.
|
||||
pub last_exec_run_counter: u64,
|
||||
|
||||
/// Number of recursive calls to the internal completion function.
|
||||
pub complete_recursion_level: u32,
|
||||
|
||||
/// If set, we are currently within fish's initialization routines.
|
||||
pub within_fish_init: bool,
|
||||
|
||||
/// If we're currently repainting the commandline.
|
||||
/// Useful to stop infinite loops.
|
||||
pub is_repaint: bool,
|
||||
|
||||
/// Whether we called builtin_complete -C without parameter.
|
||||
pub builtin_complete_current_commandline: bool,
|
||||
|
||||
/// Whether we are currently cleaning processes.
|
||||
pub is_cleaning_procs: bool,
|
||||
|
||||
/// The internal job id of the job being populated, or 0 if none.
|
||||
/// This supports the '--on-job-exit caller' feature.
|
||||
pub caller_id: u64, // TODO should be InternalJobId
|
||||
|
||||
/// Whether we are running a subshell command.
|
||||
pub is_subshell: bool,
|
||||
|
||||
/// Whether we are running an event handler. This is not a bool because we keep count of the
|
||||
/// event nesting level.
|
||||
pub is_event: i32,
|
||||
|
||||
/// Whether we are currently interactive.
|
||||
pub is_interactive: bool,
|
||||
|
||||
/// Whether to suppress fish_trace output. This occurs in the prompt, event handlers, and key
|
||||
/// bindings.
|
||||
pub suppress_fish_trace: bool,
|
||||
|
||||
/// Whether we should break or continue the current loop.
|
||||
/// This is set by the 'break' and 'continue' commands.
|
||||
pub loop_status: LoopStatus,
|
||||
|
||||
/// Whether we should return from the current function.
|
||||
/// This is set by the 'return' command.
|
||||
pub returning: bool,
|
||||
|
||||
/// Whether we should stop executing.
|
||||
/// This is set by the 'exit' command, and unset after 'reader_read'.
|
||||
/// Note this only exits up to the "current script boundary." That is, a call to exit within a
|
||||
/// 'source' or 'read' command will only exit up to that command.
|
||||
pub exit_current_script: bool,
|
||||
|
||||
/// The read limit to apply to captured subshell output, or 0 for none.
|
||||
pub read_limit: usize,
|
||||
}
|
||||
|
|
10
src/proc.rs
10
src/proc.rs
|
@ -984,7 +984,7 @@ impl Job {
|
|||
} else {
|
||||
"UNCOMPLETED"
|
||||
},
|
||||
if parser.libdata().pods.is_interactive {
|
||||
if parser.libdata().is_interactive {
|
||||
"INTERACTIVE"
|
||||
} else {
|
||||
"NON-INTERACTIVE"
|
||||
|
@ -1003,7 +1003,7 @@ impl Job {
|
|||
if p.status.normal_exited() || p.status.signal_exited() {
|
||||
if let Some(statuses) = self.get_statuses() {
|
||||
parser.set_last_statuses(statuses);
|
||||
parser.libdata_mut().pods.status_count += 1;
|
||||
parser.libdata_mut().status_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1290,7 +1290,7 @@ fn handle_child_status(job: &Job, proc: &Process, status: &ProcStatus) {
|
|||
/// Wait for any process finishing, or receipt of a signal.
|
||||
pub fn proc_wait_any(parser: &Parser) {
|
||||
process_mark_finished_children(parser, true /*block_ok*/);
|
||||
let is_interactive = parser.libdata().pods.is_interactive;
|
||||
let is_interactive = parser.libdata().is_interactive;
|
||||
process_clean_after_marking(parser, is_interactive);
|
||||
}
|
||||
|
||||
|
@ -1705,12 +1705,12 @@ fn process_clean_after_marking(parser: &Parser, allow_interactive: bool) -> bool
|
|||
|
||||
// This function may fire an event handler, we do not want to call ourselves recursively (to
|
||||
// avoid infinite recursion).
|
||||
if parser.libdata().pods.is_cleaning_procs {
|
||||
if parser.libdata().is_cleaning_procs {
|
||||
return false;
|
||||
}
|
||||
|
||||
let _cleaning = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_cleaning_procs, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_cleaning_procs, new_value),
|
||||
true,
|
||||
);
|
||||
|
||||
|
|
|
@ -574,7 +574,7 @@ pub fn reader_read(parser: &Parser, fd: RawFd, io: &IoChain) -> c_int {
|
|||
}
|
||||
|
||||
let _interactive_push = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_interactive, new_value),
|
||||
interactive,
|
||||
);
|
||||
signal_set_handlers_once(interactive);
|
||||
|
@ -586,7 +586,7 @@ pub fn reader_read(parser: &Parser, fd: RawFd, io: &IoChain) -> c_int {
|
|||
};
|
||||
|
||||
// If the exit command was called in a script, only exit the script, not the program.
|
||||
parser.libdata_mut().pods.exit_current_script = false;
|
||||
parser.libdata_mut().exit_current_script = false;
|
||||
|
||||
res
|
||||
}
|
||||
|
@ -637,8 +637,8 @@ fn read_i(parser: &Parser) -> i32 {
|
|||
}
|
||||
|
||||
// If the command requested an exit, then process it now and clear it.
|
||||
data.exit_loop_requested |= parser.libdata().pods.exit_current_script;
|
||||
parser.libdata_mut().pods.exit_current_script = false;
|
||||
data.exit_loop_requested |= parser.libdata().exit_current_script;
|
||||
parser.libdata_mut().exit_current_script = false;
|
||||
|
||||
let _ = write!(
|
||||
Outputter::stdoutput().borrow_mut(),
|
||||
|
@ -1796,7 +1796,7 @@ impl ReaderData {
|
|||
self,
|
||||
|zelf, new_value| {
|
||||
std::mem::replace(
|
||||
&mut zelf.parser().libdata_mut().pods.suppress_fish_trace,
|
||||
&mut zelf.parser().libdata_mut().suppress_fish_trace,
|
||||
new_value,
|
||||
)
|
||||
},
|
||||
|
@ -2057,8 +2057,8 @@ impl ReaderData {
|
|||
|
||||
// If we ran `exit` anywhere, exit.
|
||||
self.exit_loop_requested =
|
||||
self.exit_loop_requested || self.parser().libdata().pods.exit_current_script;
|
||||
self.parser().libdata_mut().pods.exit_current_script = false;
|
||||
self.exit_loop_requested || self.parser().libdata().exit_current_script;
|
||||
self.parser().libdata_mut().exit_current_script = false;
|
||||
if self.exit_loop_requested {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
@ -2222,7 +2222,7 @@ impl ReaderData {
|
|||
}
|
||||
rl::RepaintMode | rl::ForceRepaint | rl::Repaint => {
|
||||
self.queued_repaint = false;
|
||||
self.parser().libdata_mut().pods.is_repaint = true;
|
||||
self.parser().libdata_mut().is_repaint = true;
|
||||
if c == rl::RepaintMode {
|
||||
// Repaint the mode-prompt only if possible.
|
||||
// This is an optimization basically exclusively for vi-mode, since the prompt
|
||||
|
@ -2242,7 +2242,7 @@ impl ReaderData {
|
|||
self.screen.reset_line(/*repaint_prompt=*/ true);
|
||||
self.layout_and_repaint(L!("mode"));
|
||||
}
|
||||
self.parser().libdata_mut().pods.is_repaint = false;
|
||||
self.parser().libdata_mut().is_repaint = false;
|
||||
return;
|
||||
}
|
||||
// Else we repaint as normal.
|
||||
|
@ -2251,7 +2251,7 @@ impl ReaderData {
|
|||
self.screen.reset_line(/*repaint_prompt=*/ true);
|
||||
self.layout_and_repaint(L!("readline"));
|
||||
self.force_exec_prompt_and_repaint = false;
|
||||
self.parser().libdata_mut().pods.is_repaint = false;
|
||||
self.parser().libdata_mut().is_repaint = false;
|
||||
}
|
||||
rl::Complete | rl::CompleteAndSearch => {
|
||||
if !self.conf.complete_ok {
|
||||
|
@ -3152,7 +3152,7 @@ impl ReaderData {
|
|||
event::fire_generic(self.parser(), L!("fish_focus_out").to_owned(), vec![]);
|
||||
}
|
||||
rl::ClearScreenAndRepaint => {
|
||||
self.parser().libdata_mut().pods.is_repaint = true;
|
||||
self.parser().libdata_mut().is_repaint = true;
|
||||
let clear = screen_clear();
|
||||
if !clear.is_empty() {
|
||||
// Clear the screen if we can.
|
||||
|
@ -3168,7 +3168,7 @@ impl ReaderData {
|
|||
self.screen.reset_line(/*repaint_prompt=*/ true);
|
||||
self.layout_and_repaint(L!("readline"));
|
||||
self.force_exec_prompt_and_repaint = false;
|
||||
self.parser().libdata_mut().pods.is_repaint = false;
|
||||
self.parser().libdata_mut().is_repaint = false;
|
||||
}
|
||||
rl::SelfInsert | rl::SelfInsertNotFirst | rl::FuncAnd | rl::FuncOr => {
|
||||
panic!("should have been handled by inputter_t::readch");
|
||||
|
@ -3732,16 +3732,11 @@ pub fn reader_write_title(
|
|||
reset_cursor_position: bool, /* = true */
|
||||
) {
|
||||
let _noninteractive = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_interactive, new_value),
|
||||
false,
|
||||
);
|
||||
let _in_title = scoped_push_replacer(
|
||||
|new_value| {
|
||||
std::mem::replace(
|
||||
&mut parser.libdata_mut().pods.suppress_fish_trace,
|
||||
new_value,
|
||||
)
|
||||
},
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().suppress_fish_trace, new_value),
|
||||
true,
|
||||
);
|
||||
|
||||
|
@ -3813,7 +3808,7 @@ impl ReaderData {
|
|||
self,
|
||||
|zelf, new_value| {
|
||||
std::mem::replace(
|
||||
&mut zelf.parser().libdata_mut().pods.suppress_fish_trace,
|
||||
&mut zelf.parser().libdata_mut().suppress_fish_trace,
|
||||
new_value,
|
||||
)
|
||||
},
|
||||
|
@ -3829,10 +3824,7 @@ impl ReaderData {
|
|||
let mut zelf = scoped_push_replacer_ctx(
|
||||
&mut zelf,
|
||||
|zelf, new_value| {
|
||||
std::mem::replace(
|
||||
&mut zelf.parser().libdata_mut().pods.is_interactive,
|
||||
new_value,
|
||||
)
|
||||
std::mem::replace(&mut zelf.parser().libdata_mut().is_interactive, new_value)
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
@ -3884,9 +3876,9 @@ impl ReaderData {
|
|||
reader_write_title(L!(""), zelf.parser(), false);
|
||||
|
||||
// Some prompt may have requested an exit (#8033).
|
||||
let exit_current_script = zelf.parser().libdata().pods.exit_current_script;
|
||||
let exit_current_script = zelf.parser().libdata().exit_current_script;
|
||||
zelf.exit_loop_requested |= exit_current_script;
|
||||
zelf.parser().libdata_mut().pods.exit_current_script = false;
|
||||
zelf.parser().libdata_mut().exit_current_script = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4466,7 +4458,7 @@ fn expand_replacer(
|
|||
cmd.push(' ');
|
||||
cmd.push_utfstr(&escape(token));
|
||||
let _not_interactive = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_interactive, new_value),
|
||||
false,
|
||||
);
|
||||
|
||||
|
@ -4907,7 +4899,7 @@ impl ReaderData {
|
|||
let mut cmd: WString = L!("fish_should_add_to_history ").into();
|
||||
cmd.push_utfstr(&escape(text));
|
||||
let _not_interactive = scoped_push_replacer(
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().pods.is_interactive, new_value),
|
||||
|new_value| std::mem::replace(&mut parser.libdata_mut().is_interactive, new_value),
|
||||
false,
|
||||
);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn trace_set_enabled(do_enable: bool) {
|
|||
|
||||
/// return whether tracing is enabled.
|
||||
pub fn trace_enabled(parser: &Parser) -> bool {
|
||||
let ld = &parser.libdata().pods;
|
||||
let ld = &parser.libdata();
|
||||
if ld.suppress_fish_trace {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user