Implemented arithmetic substitution
This commit is contained in:
@@ -8,11 +8,7 @@ pub fn alias(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
while let Some(arg) = argv_iter.next() {
|
||||
let arg_raw = shenv.input_slice(arg.span()).to_string();
|
||||
if let Some((alias,body)) = arg_raw.split_once('=') {
|
||||
log!(DEBUG, "{:?}",arg.span());
|
||||
log!(DEBUG, arg_raw);
|
||||
log!(DEBUG, body);
|
||||
let clean_body = trim_quotes(&body);
|
||||
log!(DEBUG, clean_body);
|
||||
shenv.logic_mut().set_alias(alias, &clean_body);
|
||||
} else {
|
||||
return Err(ShErr::full(ShErrKind::SyntaxErr, "Expected an assignment in alias args", shenv.get_input(), arg.span().clone()))
|
||||
|
||||
@@ -14,8 +14,8 @@ pub fn exec_input<S: Into<String>>(input: S, shenv: &mut ShEnv) -> ShResult<()>
|
||||
|
||||
let token_stream = expand_aliases(token_stream, shenv);
|
||||
for token in &token_stream {
|
||||
log!(DEBUG, token);
|
||||
log!(DEBUG, "{}",token.as_raw(shenv));
|
||||
log!(TRACE, token);
|
||||
log!(TRACE, "{}",token.as_raw(shenv));
|
||||
}
|
||||
|
||||
let syn_tree = Parser::new(token_stream,shenv).parse()?;
|
||||
@@ -43,7 +43,7 @@ impl<'a> Executor<'a> {
|
||||
}
|
||||
pub fn walk(&mut self) -> ShResult<()> {
|
||||
self.shenv.inputman_mut().save_state();
|
||||
log!(DEBUG, "Starting walk");
|
||||
log!(TRACE, "Starting walk");
|
||||
while let Some(node) = self.ast.next_node() {
|
||||
if let NdRule::CmdList { cmds } = node.clone().into_rule() {
|
||||
log!(TRACE, "{:?}", cmds);
|
||||
@@ -51,13 +51,13 @@ impl<'a> Executor<'a> {
|
||||
} else { unreachable!() }
|
||||
}
|
||||
self.shenv.inputman_mut().load_state();
|
||||
log!(DEBUG, "passed");
|
||||
log!(TRACE, "passed");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn exec_list(list: Vec<(Option<CmdGuard>, Node)>, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
log!(DEBUG, "Executing list");
|
||||
log!(TRACE, "Executing list");
|
||||
let mut list = VecDeque::from(list);
|
||||
while let Some(cmd_info) = list.fpop() {
|
||||
let guard = cmd_info.0;
|
||||
@@ -104,7 +104,7 @@ fn dispatch_command(mut node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
let mut is_func = false;
|
||||
let mut is_subsh = false;
|
||||
if let NdRule::Command { ref mut argv, redirs: _ } = node.rule_mut() {
|
||||
*argv = expand_argv(argv.to_vec(), shenv);
|
||||
*argv = expand_argv(argv.to_vec(), shenv)?;
|
||||
let cmd = argv.first().unwrap().as_raw(shenv);
|
||||
if shenv.logic().get_function(&cmd).is_some() {
|
||||
is_func = true;
|
||||
@@ -112,7 +112,7 @@ fn dispatch_command(mut node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
is_builtin = true;
|
||||
}
|
||||
} else if let NdRule::Subshell { body: _, ref mut argv, redirs: _ } = node.rule_mut() {
|
||||
*argv = expand_argv(argv.to_vec(), shenv);
|
||||
*argv = expand_argv(argv.to_vec(), shenv)?;
|
||||
is_subsh = true;
|
||||
} else { unreachable!() }
|
||||
|
||||
@@ -239,7 +239,7 @@ fn exec_subshell(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
}
|
||||
|
||||
fn exec_builtin(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
log!(DEBUG, "Executing builtin");
|
||||
log!(TRACE, "Executing builtin");
|
||||
let command = if let NdRule::Command { argv, redirs: _ } = node.rule() {
|
||||
argv.first().unwrap().as_raw(shenv)
|
||||
} else { unreachable!() };
|
||||
@@ -267,7 +267,7 @@ fn exec_builtin(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
}
|
||||
|
||||
fn exec_assignment(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
log!(DEBUG, "Executing assignment");
|
||||
log!(TRACE, "Executing assignment");
|
||||
let rule = node.into_rule();
|
||||
if let NdRule::Assignment { assignments, cmd } = rule {
|
||||
log!(TRACE, "Assignments: {:?}", assignments);
|
||||
@@ -298,7 +298,7 @@ fn exec_assignment(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
}
|
||||
|
||||
fn exec_pipeline(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
log!(DEBUG, "Executing pipeline");
|
||||
log!(TRACE, "Executing pipeline");
|
||||
let rule = node.into_rule();
|
||||
if let NdRule::Pipeline { cmds } = rule {
|
||||
let mut prev_rpipe: Option<i32> = None;
|
||||
@@ -384,7 +384,7 @@ fn exec_pipeline(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
}
|
||||
|
||||
fn exec_cmd(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
log!(DEBUG, "Executing command");
|
||||
log!(TRACE, "Executing command");
|
||||
let blame = node.span();
|
||||
let rule = node.into_rule();
|
||||
|
||||
@@ -393,11 +393,11 @@ fn exec_cmd(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
let command = argv.first().unwrap().to_string();
|
||||
if get_bin_path(&command, shenv).is_some() {
|
||||
|
||||
log!(DEBUG, "{:?}",shenv.ctx().flags());
|
||||
log!(TRACE, "{:?}",shenv.ctx().flags());
|
||||
if shenv.ctx().flags().contains(ExecFlags::NO_FORK) {
|
||||
log!(TRACE, "Not forking");
|
||||
shenv.collect_redirs(redirs);
|
||||
log!(DEBUG, "{:?}",shenv.ctx().redirs());
|
||||
log!(TRACE, "{:?}",shenv.ctx().redirs());
|
||||
if let Err(e) = shenv.ctx_mut().activate_rdrs() {
|
||||
eprintln!("{:?}",e);
|
||||
exit(1);
|
||||
@@ -411,7 +411,7 @@ fn exec_cmd(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
log!(TRACE, "Forking");
|
||||
match unsafe { fork()? } {
|
||||
Child => {
|
||||
log!(DEBUG, redirs);
|
||||
log!(TRACE, redirs);
|
||||
shenv.collect_redirs(redirs);
|
||||
if let Err(e) = shenv.ctx_mut().activate_rdrs() {
|
||||
eprintln!("{:?}",e);
|
||||
@@ -441,9 +441,9 @@ fn exec_cmd(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
}
|
||||
|
||||
fn prep_execve(argv: Vec<Token>, shenv: &mut ShEnv) -> (Vec<String>, Vec<String>) {
|
||||
log!(DEBUG, "Preparing execvpe args");
|
||||
log!(TRACE, "Preparing execvpe args");
|
||||
let argv_s = argv.as_strings(shenv);
|
||||
log!(DEBUG, argv_s);
|
||||
log!(TRACE, argv_s);
|
||||
|
||||
let mut envp = vec![];
|
||||
let mut env_vars = shenv.vars().env().iter();
|
||||
|
||||
@@ -119,7 +119,7 @@ pub fn exec_case(node: Node, shenv: &mut ShEnv) -> ShResult<()> {
|
||||
if let NdRule::Case { pat, blocks, redirs } = rule {
|
||||
shenv.collect_redirs(redirs);
|
||||
let mut blocks_iter = blocks.into_iter();
|
||||
let pat_raw = expand_token(pat, shenv)
|
||||
let pat_raw = expand_token(pat, shenv)?
|
||||
.iter()
|
||||
.map(|tk| tk.as_raw(shenv))
|
||||
.collect::<Vec<_>>()
|
||||
|
||||
@@ -51,7 +51,6 @@ pub fn expand_aliases(tokens: Vec<Token>, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
TkRule::Ident if is_command => {
|
||||
is_command = false;
|
||||
let mut alias_tokens = expand_alias(token.clone(), shenv);
|
||||
log!(DEBUG, alias_tokens);
|
||||
if !alias_tokens.is_empty() {
|
||||
processed.append(&mut alias_tokens);
|
||||
} else {
|
||||
|
||||
171
src/expand/arithmetic.rs
Normal file
171
src/expand/arithmetic.rs
Normal file
@@ -0,0 +1,171 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use super::vars::expand_dquote;
|
||||
|
||||
#[derive(Clone,PartialEq,Debug)]
|
||||
pub enum ExprToken {
|
||||
Number(f64),
|
||||
Operator(Op),
|
||||
OpenParen,
|
||||
CloseParen
|
||||
}
|
||||
|
||||
#[derive(Clone,PartialEq,Debug)]
|
||||
pub enum Op {
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
Pow
|
||||
}
|
||||
|
||||
impl Op {
|
||||
pub fn precedence(&self) -> u8 {
|
||||
match self {
|
||||
Op::Add | Op::Sub => 1,
|
||||
Op::Mul | Op::Div | Op::Mod => 2,
|
||||
Op::Pow => 3
|
||||
}
|
||||
}
|
||||
pub fn is_left_associative(&self) -> bool {
|
||||
*self != Op::Pow
|
||||
}
|
||||
}
|
||||
|
||||
fn tokenize_expr(expr: &str) -> ShResult<Vec<ExprToken>> {
|
||||
let mut chars = expr.chars().peekable();
|
||||
let mut tokens = vec![];
|
||||
|
||||
while let Some(ch) = chars.next() {
|
||||
match ch {
|
||||
'+' => tokens.push(ExprToken::Operator(Op::Add)),
|
||||
'-' => tokens.push(ExprToken::Operator(Op::Sub)),
|
||||
'*' => {
|
||||
if chars.peek() == Some(&'*') {
|
||||
chars.next();
|
||||
tokens.push(ExprToken::Operator(Op::Pow));
|
||||
} else {
|
||||
tokens.push(ExprToken::Operator(Op::Mul));
|
||||
}
|
||||
}
|
||||
'/' => tokens.push(ExprToken::Operator(Op::Div)),
|
||||
'%' => tokens.push(ExprToken::Operator(Op::Mod)),
|
||||
'(' => tokens.push(ExprToken::OpenParen),
|
||||
')' => tokens.push(ExprToken::CloseParen),
|
||||
'0'..='9' => {
|
||||
let mut number = ch.to_string();
|
||||
while let Some(next_ch) = chars.peek() {
|
||||
if next_ch.is_ascii_digit() {
|
||||
number.push(chars.next().unwrap());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let value = number.parse::<f64>().unwrap();
|
||||
tokens.push(ExprToken::Number(value));
|
||||
}
|
||||
' ' | '\t' => continue, // Skip whitespace
|
||||
_ => return Err(ShErr::simple(ShErrKind::ParseErr, format!("Unexpected character in arithmetic expansion: {}",ch))), // Handle unexpected characters
|
||||
}
|
||||
}
|
||||
|
||||
Ok(tokens)
|
||||
}
|
||||
|
||||
fn shunting_yard(tokens: Vec<ExprToken>) -> ShResult<Vec<ExprToken>> {
|
||||
let mut sorted = vec![];
|
||||
let mut operators = vec![];
|
||||
|
||||
for token in tokens {
|
||||
match token {
|
||||
ExprToken::Number(_) => sorted.push(token.clone()),
|
||||
ExprToken::Operator(ref op) => {
|
||||
while let Some(top) = operators.last() {
|
||||
if let ExprToken::Operator(top_op) = top {
|
||||
if (op.is_left_associative() && op.precedence() <= top_op.precedence())
|
||||
|| (!op.is_left_associative() && op.precedence() < top_op.precedence())
|
||||
{
|
||||
sorted.push(operators.pop().unwrap())
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
operators.push(token.clone())
|
||||
}
|
||||
ExprToken::OpenParen => operators.push(token.clone()),
|
||||
ExprToken::CloseParen => {
|
||||
while let Some(top) = operators.pop() {
|
||||
if matches!(top, ExprToken::OpenParen) {
|
||||
break;
|
||||
}
|
||||
sorted.push(top);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while let Some(op) = operators.pop() {
|
||||
if matches!(op, ExprToken::OpenParen | ExprToken::CloseParen) {
|
||||
return Err(ShErr::simple(ShErrKind::ParseErr, "Mismatched parenthesis in arithmetic expansion"))
|
||||
}
|
||||
sorted.push(op);
|
||||
}
|
||||
|
||||
Ok(sorted)
|
||||
}
|
||||
|
||||
pub fn eval_rpn(tokens: Vec<ExprToken>) -> ShResult<f64> {
|
||||
let mut stack = vec![];
|
||||
|
||||
for token in tokens {
|
||||
match token {
|
||||
ExprToken::Number(num) => stack.push(num),
|
||||
ExprToken::Operator(op) => {
|
||||
if stack.len() < 2 {
|
||||
return Err(ShErr::simple(ShErrKind::ParseErr, "Not enough operands in arithmetic expansion"))
|
||||
}
|
||||
let rhs = stack.pop().unwrap();
|
||||
let lhs = stack.pop().unwrap();
|
||||
let result = match op {
|
||||
Op::Add => lhs + rhs,
|
||||
Op::Sub => lhs - rhs,
|
||||
Op::Mul => lhs * rhs,
|
||||
Op::Mod => lhs % rhs,
|
||||
Op::Pow => lhs.powf(rhs),
|
||||
Op::Div => {
|
||||
if rhs == 0.0 {
|
||||
return Err(ShErr::simple(ShErrKind::ParseErr, "Attempt to divide by zero in arithmetic expansion"))
|
||||
}
|
||||
lhs / rhs
|
||||
}
|
||||
};
|
||||
stack.push(result);
|
||||
}
|
||||
ExprToken::OpenParen => todo!(),
|
||||
ExprToken::CloseParen => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(stack.pop().unwrap())
|
||||
}
|
||||
|
||||
pub fn expand_arithmetic(token: Token, shenv: &mut ShEnv) -> ShResult<Token> {
|
||||
// I mean hey it works (I think)
|
||||
let dummy_token = Token::new(TkRule::DQuote, token.span());
|
||||
let expanded = expand_dquote(dummy_token, shenv);
|
||||
token.span().borrow_mut().expanded = false;
|
||||
let expanded_raw = expanded.as_raw(shenv);
|
||||
let arith_raw = expanded_raw.trim_matches('`');
|
||||
|
||||
let expr_tokens = shunting_yard(tokenize_expr(arith_raw)?)?;
|
||||
log!(DEBUG,expr_tokens);
|
||||
let result = eval_rpn(expr_tokens)?.to_string();
|
||||
|
||||
let mut final_expansion = shenv.expand_input(&result, token.span());
|
||||
|
||||
Ok(final_expansion.pop().unwrap_or(token))
|
||||
}
|
||||
@@ -2,24 +2,26 @@ pub mod vars;
|
||||
pub mod tilde;
|
||||
pub mod alias;
|
||||
pub mod cmdsub;
|
||||
pub mod arithmetic;
|
||||
|
||||
use arithmetic::expand_arithmetic;
|
||||
use vars::{expand_dquote, expand_var};
|
||||
use tilde::expand_tilde;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn expand_argv(argv: Vec<Token>, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
pub fn expand_argv(argv: Vec<Token>, shenv: &mut ShEnv) -> ShResult<Vec<Token>> {
|
||||
let mut processed = vec![];
|
||||
for arg in argv {
|
||||
log!(DEBUG, "{}",arg.as_raw(shenv));
|
||||
log!(DEBUG, processed);
|
||||
let mut expanded = expand_token(arg, shenv);
|
||||
let mut expanded = expand_token(arg, shenv)?;
|
||||
processed.append(&mut expanded);
|
||||
}
|
||||
processed
|
||||
Ok(processed)
|
||||
}
|
||||
|
||||
pub fn expand_token(token: Token, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
pub fn expand_token(token: Token, shenv: &mut ShEnv) -> ShResult<Vec<Token>> {
|
||||
let mut processed = vec![];
|
||||
match token.rule() {
|
||||
TkRule::DQuote => {
|
||||
@@ -34,6 +36,10 @@ pub fn expand_token(token: Token, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
let tilde_exp = expand_tilde(token.clone(), shenv);
|
||||
processed.push(tilde_exp);
|
||||
}
|
||||
TkRule::ArithSub => {
|
||||
let arith_exp = expand_arithmetic(token.clone(), shenv)?;
|
||||
processed.push(arith_exp);
|
||||
}
|
||||
_ => {
|
||||
if token.rule() != TkRule::Ident {
|
||||
log!(WARN, "found this in expand_token: {:?}", token.rule());
|
||||
@@ -41,5 +47,5 @@ pub fn expand_token(token: Token, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
processed.push(token.clone())
|
||||
}
|
||||
}
|
||||
processed
|
||||
Ok(processed)
|
||||
}
|
||||
|
||||
@@ -58,10 +58,6 @@ pub fn expand_dquote(dquote: Token, shenv: &mut ShEnv) -> Token {
|
||||
}
|
||||
}
|
||||
|
||||
log!(DEBUG, result);
|
||||
|
||||
log!(DEBUG, "{:?}",dquote.span());
|
||||
let token = shenv.expand_input(&result, dquote.span()).pop().unwrap_or(dquote);
|
||||
log!(DEBUG, "{}",token.as_raw(shenv));
|
||||
token
|
||||
}
|
||||
|
||||
@@ -371,6 +371,7 @@ tkrule_def!(ArithSub, |input: &str| {
|
||||
}
|
||||
}
|
||||
}
|
||||
' ' | '\t' | ';' | '\n' => return None,
|
||||
_ => { /* Continue */ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,6 @@ ndrule_def!(ShellCmd, shenv, |tokens: &[Token], shenv: &mut ShEnv| {
|
||||
});
|
||||
|
||||
ndrule_def!(Case, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
log!(DEBUG, tokens);
|
||||
let err = |msg: &str, span: Rc<RefCell<Span>>, shenv: &mut ShEnv | {
|
||||
ShErr::full(ShErrKind::ParseErr, msg, shenv.get_input(), span)
|
||||
};
|
||||
@@ -411,7 +410,6 @@ ndrule_def!(Case, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
}
|
||||
}
|
||||
}
|
||||
log!(DEBUG,tokens);
|
||||
tokens_iter = tokens.iter().peekable();
|
||||
|
||||
if tokens_iter.peek().is_none() {
|
||||
@@ -431,14 +429,10 @@ ndrule_def!(Case, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
let block_pat = token.clone();
|
||||
let (used,lists) = get_lists(tokens, shenv);
|
||||
let mut lists_iter = lists.iter().peekable();
|
||||
log!(DEBUG, used);
|
||||
log!(DEBUG, lists);
|
||||
while let Some(list) = lists_iter.next() {
|
||||
node_toks.extend(list.tokens.clone());
|
||||
if lists_iter.peek().is_none() {
|
||||
log!(DEBUG, list);
|
||||
for token in list.tokens() {
|
||||
log!(DEBUG, "{}", token.as_raw(shenv));
|
||||
}
|
||||
}
|
||||
if let Some(token) = list.tokens().last() {
|
||||
@@ -482,7 +476,6 @@ ndrule_def!(Case, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
redirs.push(redir);
|
||||
}
|
||||
_ => {
|
||||
log!(DEBUG, token);
|
||||
return Err(err("Expected `esac` or a case block here", node_toks.last().unwrap().span(), shenv))
|
||||
}
|
||||
}
|
||||
@@ -523,7 +516,6 @@ ndrule_def!(ForLoop, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
} else { return Ok(None) }
|
||||
|
||||
while let Some(token) = tokens_iter.next() {
|
||||
log!(DEBUG, token);
|
||||
node_toks.push(token.clone());
|
||||
tokens = &tokens[1..];
|
||||
match token.rule() {
|
||||
@@ -656,7 +648,6 @@ ndrule_def!(ForLoop, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
});
|
||||
|
||||
ndrule_def!(IfThen, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
log!(DEBUG,tokens);
|
||||
let err = |msg: &str, span: Rc<RefCell<Span>>, shenv: &mut ShEnv | {
|
||||
ShErr::full(ShErrKind::ParseErr, msg, shenv.get_input(), span)
|
||||
};
|
||||
@@ -666,7 +657,6 @@ ndrule_def!(IfThen, shenv, |mut tokens: &[Token], shenv: &mut ShEnv| {
|
||||
let mut redirs = vec![];
|
||||
let mut else_block: Option<Vec<Node>> = None;
|
||||
|
||||
log!(DEBUG,tokens);
|
||||
if let Some(token) = tokens_iter.next() {
|
||||
if let TkRule::If = token.rule() {
|
||||
node_toks.push(token.clone());
|
||||
@@ -1151,6 +1141,7 @@ ndrule_def!(Command, shenv, |tokens: &[Token], shenv: &mut ShEnv| {
|
||||
TkRule::DQuote |
|
||||
TkRule::Assign |
|
||||
TkRule::TildeSub |
|
||||
TkRule::ArithSub |
|
||||
TkRule::VarSub => {
|
||||
argv.push(token.clone());
|
||||
}
|
||||
@@ -1228,13 +1219,11 @@ ndrule_def!(Assignment, shenv, |tokens: &[Token], shenv: &mut ShEnv| {
|
||||
};
|
||||
return Ok(Some(node))
|
||||
} else {
|
||||
log!(DEBUG, tokens);
|
||||
if let Some(token) = tokens.next() {
|
||||
if token.rule() == TkRule::Sep {
|
||||
node_toks.push(token.clone());
|
||||
}
|
||||
}
|
||||
log!(DEBUG, node_toks);
|
||||
|
||||
let span = get_span(&node_toks,shenv)?;
|
||||
let node = Node {
|
||||
|
||||
@@ -97,7 +97,6 @@ impl<'a> ChildProc {
|
||||
} else {
|
||||
WtStat::Exited(pid, 0)
|
||||
};
|
||||
log!(DEBUG, command);
|
||||
let mut child = Self { pgid: pid, pid, command, stat };
|
||||
if let Some(pgid) = pgid {
|
||||
child.set_pgid(pgid).ok();
|
||||
@@ -505,7 +504,6 @@ impl JobTab {
|
||||
self.fg.as_mut()
|
||||
}
|
||||
pub fn new_fg<'a>(&mut self, job: Job) -> ShResult<Vec<WtStat>> {
|
||||
log!(DEBUG, "New fg job: {:?}", job);
|
||||
let pgid = job.pgid();
|
||||
self.fg = Some(job);
|
||||
attach_tty(pgid)?;
|
||||
@@ -519,7 +517,6 @@ impl JobTab {
|
||||
}
|
||||
take_term()?;
|
||||
let fg = std::mem::take(&mut self.fg);
|
||||
log!(DEBUG, "Moving foreground job to background");
|
||||
if let Some(mut job) = fg {
|
||||
job.set_stats(stat);
|
||||
self.insert_job(job, false)?;
|
||||
|
||||
@@ -33,7 +33,6 @@ impl ShEnv {
|
||||
}
|
||||
pub fn source_file(&mut self, path: PathBuf) -> ShResult<()> {
|
||||
if path.is_file() {
|
||||
log!(DEBUG, "sourcing {}", path.to_str().unwrap());
|
||||
let mut file = std::fs::File::open(path)?;
|
||||
let mut buf = String::new();
|
||||
file.read_to_string(&mut buf)?;
|
||||
@@ -43,14 +42,12 @@ impl ShEnv {
|
||||
Ok(())
|
||||
}
|
||||
pub fn source_rc(&mut self) -> ShResult<()> {
|
||||
log!(DEBUG, "sourcing rc");
|
||||
let path_raw = std::env::var("FERN_RC")?;
|
||||
let path = PathBuf::from(path_raw);
|
||||
self.source_file(path)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn expand_input(&mut self, new: &str, repl_span: Rc<RefCell<Span>>) -> Vec<Token> {
|
||||
log!(DEBUG,repl_span);
|
||||
if repl_span.borrow().expanded {
|
||||
return vec![];
|
||||
}
|
||||
@@ -71,10 +68,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!(DEBUG, input);
|
||||
input.replace_range(range, new);
|
||||
let expanded = input.clone();
|
||||
log!(DEBUG, expanded);
|
||||
|
||||
for span in self.input_man.spans_mut() {
|
||||
let mut span_mut = span.borrow_mut();
|
||||
@@ -87,7 +82,6 @@ impl ShEnv {
|
||||
}
|
||||
}
|
||||
self.input_man.clamp_all();
|
||||
log!(DEBUG, new_tokens);
|
||||
if new_tokens.is_empty() {
|
||||
let empty = Token::new(
|
||||
TkRule::Ident,
|
||||
@@ -156,11 +150,8 @@ impl ShEnv {
|
||||
let stderr = ctx.masks().stderr().get_fd();
|
||||
|
||||
let saved_in = dup(stdin)?;
|
||||
log!(DEBUG, saved_in);
|
||||
let saved_out = dup(stdout)?;
|
||||
log!(DEBUG, saved_out);
|
||||
let saved_err = dup(stderr)?;
|
||||
log!(DEBUG, saved_err);
|
||||
|
||||
let saved_io = shellenv::exec_ctx::SavedIo::save(saved_in, saved_out, saved_err);
|
||||
*ctx.saved_io() = Some(saved_io);
|
||||
|
||||
Reference in New Issue
Block a user