Implemented scoping for expansions

This commit is contained in:
2025-03-08 01:38:42 -05:00
parent eccdafb11e
commit 4f58c1c3fd
18 changed files with 271 additions and 141 deletions

View File

@@ -11,7 +11,6 @@ bitflags! {
pub struct ExecCtx {
redirs: Vec<Redir>,
depth: usize,
state_stack: Vec<Self>,
max_depth: usize,
flags: ExecFlags,
io_masks: IoMasks,
@@ -23,36 +22,12 @@ impl ExecCtx {
Self {
redirs: vec![],
depth: 0,
state_stack: vec![],
max_depth: 1500,
flags: ExecFlags::empty(),
io_masks: IoMasks::new(),
saved_io: None
}
}
pub fn push_state(&mut self) {
self.state_stack.push(self.clone());
}
pub fn pop_state(&mut self) {
if let Some(state) = self.state_stack.pop() {
*self = state;
}
}
pub fn descend(&mut self) -> ShResult<()> {
self.push_state();
self.depth += 1;
log!(DEBUG, "{}",self.depth);
if self.depth > self.max_depth {
return Err(
ShErr::simple(ShErrKind::ExecFail,"Exceeded maximum execution depth")
)
}
Ok(())
}
pub fn ascend(&mut self) {
self.pop_state();
self.depth = self.depth.saturating_sub(1);
}
pub fn as_cond(&self) -> Self {
let mut clone = self.clone();
let (cond_redirs,_) = self.sort_redirs();

View File

@@ -1,16 +1,41 @@
use crate::prelude::*;
#[derive(Clone,Debug,PartialEq)]
pub struct SavedSpan {
pointer: Rc<RefCell<Span>>,
start: usize,
end: usize,
expanded: bool
}
impl SavedSpan {
pub fn from_span(pointer: Rc<RefCell<Span>>) -> Self {
let expanded = pointer.borrow().expanded;
let start = pointer.borrow().start();
let end = pointer.borrow().end();
Self { pointer, start, end, expanded }
}
pub fn restore(&self) {
let mut deref = self.pointer.borrow_mut();
deref.set_start(self.start);
deref.set_end(self.end);
deref.expanded = self.expanded
}
pub fn into_span(self) -> Rc<RefCell<Span>> {
self.pointer
}
}
#[derive(Clone,Debug,PartialEq)]
pub struct InputMan {
input: Option<String>,
saved_input: Option<String>,
spans: Vec<Rc<RefCell<Span>>>,
saved_spans: Vec<Span>
saved_states: Vec<(String,Vec<SavedSpan>)>,
}
impl InputMan {
pub fn new() -> Self {
Self { input: None, saved_input: None, spans: vec![], saved_spans: vec![] }
Self { input: None, spans: vec![], saved_states: vec![] }
}
pub fn clear(&mut self) {
*self = Self::new();
@@ -24,22 +49,27 @@ impl InputMan {
pub fn get_input_mut(&mut self) -> Option<&mut String> {
self.input.as_mut()
}
pub fn save_state(&mut self) {
self.saved_input = self.input.clone();
self.saved_spans.clear();
for span in &self.spans {
self.saved_spans.push(span.borrow().clone());
pub fn push_state(&mut self) {
if let Some(input) = &self.input {
let saved_input = input.clone();
let mut saved_spans = vec![];
for span in &self.spans {
let saved_span = SavedSpan::from_span(span.clone());
saved_spans.push(saved_span);
}
self.saved_states.push((saved_input,saved_spans));
}
}
pub fn load_state(&mut self) {
if self.saved_input.is_some() {
self.input = self.saved_input.take();
for (span, saved_span) in self.spans.iter_mut().zip(self.saved_spans.iter()) {
*span.borrow_mut() = saved_span.clone();
pub fn pop_state(&mut self) {
if let Some((saved_input, saved_spans)) = self.saved_states.pop() {
self.input = Some(saved_input);
let mut restored_spans = vec![];
for saved_span in saved_spans.into_iter() {
saved_span.restore();
let span = saved_span.into_span();
restored_spans.push(span);
}
self.saved_spans.clear();
self.spans = restored_spans;
}
}
pub fn new_span(&mut self, start: usize, end: usize) -> Rc<RefCell<Span>> {

View File

@@ -538,7 +538,7 @@ impl JobTab {
None
}
}
pub fn print_jobs(&self, flags: JobCmdFlags) -> ShResult<()> {
pub fn print_jobs(&mut self, flags: JobCmdFlags) -> ShResult<()> {
let jobs = if flags.contains(JobCmdFlags::NEW_ONLY) {
&self.jobs
.iter()
@@ -551,6 +551,7 @@ impl JobTab {
.map(|job| job.as_ref())
.collect::<Vec<Option<&Job>>>()
};
let mut jobs_to_remove = vec![];
for job in jobs.iter().flatten() {
// Skip foreground job
let id = job.tabid().unwrap();
@@ -563,6 +564,12 @@ impl JobTab {
}
// Print the job in the selected format
write(borrow_fd(1), format!("{}\n",job.display(&self.order,flags)).as_bytes())?;
if job.get_stats().iter().all(|stat| matches!(stat,WtStat::Exited(_, _))) {
jobs_to_remove.push(JobID::TableID(id));
}
}
for id in jobs_to_remove {
self.remove_job(id);
}
Ok(())
}

View File

@@ -1,3 +1,5 @@
use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
use crate::prelude::*;
#[derive(Clone,Debug)]
@@ -51,12 +53,9 @@ impl ShEnv {
if repl_span.borrow().expanded {
return vec![];
}
log!(INFO, repl_span);
log!(INFO, new);
repl_span.borrow_mut().expanded = true;
let saved_spans = self.input_man.spans_mut().clone();
let mut new_tokens = Lexer::new(new.to_string(), self).lex();
log!(INFO, new_tokens);
*self.input_man.spans_mut() = saved_spans;
let offset = repl_span.borrow().start();
@@ -71,9 +70,8 @@ impl ShEnv {
if let Some(input) = self.input_man.get_input_mut() {
let old = &input[range.clone()];
let delta: isize = new.len() as isize - old.len() as isize;
log!(INFO, input);
log!(INFO, range);
input.replace_range(range, new);
log!(INFO,input);
for span in self.input_man.spans_mut() {
let mut span_mut = span.borrow_mut();
@@ -168,11 +166,11 @@ impl ShEnv {
let saved_in = saved.stdin;
let saved_out = saved.stdout;
let saved_err = saved.stderr;
dup2(0,saved_in)?;
dup2(saved_in,STDIN_FILENO)?;
close(saved_in)?;
dup2(1,saved_out)?;
dup2(saved_out,STDOUT_FILENO)?;
close(saved_out)?;
dup2(2,saved_err)?;
dup2(saved_err,STDERR_FILENO)?;
close(saved_err)?;
}
Ok(())