From 036de1d067094e7850980352ec71861229ddaf34 Mon Sep 17 00:00:00 2001 From: Ryuichi Ueda Date: Fri, 2 Feb 2024 15:37:11 +0900 Subject: [PATCH] Fix redirect --- src/elements/io/redirect.rs | 40 ++++++++++++++++++-------------- src/elements/subword/unquoted.rs | 2 +- src/elements/word.rs | 6 ++++- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/elements/io/redirect.rs b/src/elements/io/redirect.rs index 5dce0b12..8e67786a 100644 --- a/src/elements/io/redirect.rs +++ b/src/elements/io/redirect.rs @@ -5,13 +5,14 @@ use std::fs::{File, OpenOptions}; use std::os::fd::{IntoRawFd, RawFd}; use std::io::Error; use crate::elements::io; +use crate::elements::word::Word; use crate::{Feeder, ShellCore}; #[derive(Debug, Clone)] pub struct Redirect { pub text: String, pub symbol: String, - pub right: String, + pub right: Word, pub left: String, left_fd: RawFd, left_backup: RawFd, @@ -20,6 +21,11 @@ pub struct Redirect { impl Redirect { pub fn connect(&mut self, restore: bool) -> bool { + if self.right.eval().len() != 1 { + eprintln!("sush: {}: ambiguous redirect", self.right.text); + return false; + } + match self.symbol.as_str() { "<" => self.redirect_simple_input(restore), ">" => self.redirect_simple_output(restore), @@ -53,7 +59,7 @@ impl Redirect { result }, _ => { - eprintln!("sush: {}: {}", &self.right, Error::last_os_error().kind()); + eprintln!("sush: {}: {}", &self.right.text, Error::last_os_error().kind()); false }, } @@ -61,23 +67,23 @@ impl Redirect { fn redirect_simple_input(&mut self, restore: bool) -> bool { self.set_left_fd(0); - self.connect_to_file(File::open(&self.right), restore) + self.connect_to_file(File::open(&self.right.text), restore) } fn redirect_simple_output(&mut self, restore: bool) -> bool { self.set_left_fd(1); - self.connect_to_file(File::create(&self.right), restore) + self.connect_to_file(File::create(&self.right.text), restore) } fn redirect_append(&mut self, restore: bool) -> bool { self.set_left_fd(1); self.connect_to_file(OpenOptions::new().create(true) - .write(true).append(true).open(&self.right), restore) + .write(true).append(true).open(&self.right.text), restore) } fn redirect_both_output(&mut self, restore: bool) -> bool { self.left_fd = 1; - if ! self.connect_to_file(File::create(&self.right), restore){ + if ! self.connect_to_file(File::create(&self.right.text), restore){ return false; } @@ -101,7 +107,7 @@ impl Redirect { Redirect { text: String::new(), symbol: String::new(), - right: String::new(), + right: Word::new(), left: String::new(), left_fd: -1, left_backup: -1, @@ -124,14 +130,14 @@ impl Redirect { let blank_len = feeder.scanner_blank(core); ans.text += &feeder.consume(blank_len); - match feeder.scanner_word(core) { - 0 => false, - n => { - ans.right = feeder.consume(n); - ans.text += &ans.right.clone(); - true - }, - } + let w = match Word::parse(feeder, core) { + Some(w) => w, + _ => return false, + }; + + ans.text += &w.text.clone(); + ans.right = w; + true } fn eat_left(feeder: &mut Feeder, ans: &mut Self, core: &mut ShellCore) -> bool { @@ -153,8 +159,8 @@ impl Redirect { let mut ans = Self::new(); feeder.set_backup(); //追加 - if Self::eat_left(feeder, &mut ans, core) && //追加 - Self::eat_symbol(feeder, &mut ans, core) && //ifを除去 + if Self::eat_left(feeder, &mut ans, core) && + Self::eat_symbol(feeder, &mut ans, core) && Self::eat_right(feeder, &mut ans, core) { feeder.pop_backup(); Some(ans) diff --git a/src/elements/subword/unquoted.rs b/src/elements/subword/unquoted.rs index a54fcd67..f1c319bb 100644 --- a/src/elements/subword/unquoted.rs +++ b/src/elements/subword/unquoted.rs @@ -3,7 +3,7 @@ use crate::{ShellCore, Feeder}; -#[derive(Debug)] +#[derive(Debug,Clone)] pub struct UnquotedSubword { pub text: String, } diff --git a/src/elements/word.rs b/src/elements/word.rs index b5a53c42..0fafa31c 100644 --- a/src/elements/word.rs +++ b/src/elements/word.rs @@ -4,7 +4,7 @@ use crate::{Feeder, ShellCore}; use crate::elements::subword::unquoted::UnquotedSubword; -#[derive(Debug)] +#[derive(Debug,Clone)] pub struct Word { pub text: String, pub subwords: Vec, @@ -18,6 +18,10 @@ impl Word { } } + pub fn eval(&mut self) -> Vec { + vec![self.clone()] + } + pub fn parse(feeder: &mut Feeder, core: &mut ShellCore) -> Option { let mut ans = Word::new(); while let Some(sw) = UnquotedSubword::parse(feeder, core) {