Implemented scoping for expansions
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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>> {
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
|
||||
Reference in New Issue
Block a user