Skip to content

Commit

Permalink
Implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
ryuichiueda committed Jan 31, 2024
1 parent 8847c83 commit 2aab001
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 36 deletions.
7 changes: 6 additions & 1 deletion src/elements/command/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ pub struct SimpleCommand {

impl Command for SimpleCommand {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
self.args = self.words.iter()
let mut words = vec![];
for w in self.words.iter_mut() {
words.extend(w.brace_expansion());
}

self.args = words.iter()
.filter(|w| w.text != "")
.map(|w| w.text.clone()).collect();

Expand Down
3 changes: 3 additions & 0 deletions src/elements/subword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod unquoted;

use crate::{Feeder, ShellCore};
use crate::elements::subword::brace::BraceSubword;
use crate::elements::word::Word;
use super::subword::unquoted::UnquotedSubword;
use std::fmt;
use std::fmt::Debug;
Expand All @@ -18,6 +19,8 @@ impl Debug for dyn Subword {

pub trait Subword {
fn get_text(&self) -> String;
fn copy(&self) -> Box<dyn Subword>;
fn brace_expansion(&mut self, ans: &mut Vec<Word>);
}

pub fn parse(feeder: &mut Feeder, core: &mut ShellCore) -> Option<Box<dyn Subword>> {
Expand Down
39 changes: 39 additions & 0 deletions src/elements/subword/brace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ pub struct BraceSubword {

impl Subword for BraceSubword {
fn get_text(&self) -> String { self.text.clone() }

fn copy(&self) -> Box<dyn Subword> {
Box::new( BraceSubword {
text: self.text.clone(),
words: self.words.iter().map(|w| w.copy()).collect(),
} )
}

fn brace_expansion(&mut self, lefts: &mut Vec<Word>) {
let mut rights = vec![];
for w in self.words.iter_mut() {
rights.extend(w.brace_expansion());
}

let mut ans = vec![];
for lf in lefts.iter_mut() {
ans.extend(self.add_expended(lf, &rights));
}
*lefts = ans;
}
}

impl BraceSubword {
Expand All @@ -23,6 +43,25 @@ impl BraceSubword {
}
}

fn add_expended(&mut self, left: &mut Word, rights: &Vec<Word>) -> Vec<Word> {
if self.words.len() < 2 {
left.add_text("{");
}

let mut ans = vec![];
for rw in rights {
let mut lw = left.copy();
lw.concat(&rw);
ans.push(lw);
}

if self.words.len() < 2 {
ans.iter_mut().for_each(|w| w.add_text("}"));
}

ans
}

fn eat_word(feeder: &mut Feeder, ans: &mut BraceSubword, core: &mut ShellCore) -> bool {
match Word::parse(feeder, core) {
Some(w) => {
Expand Down
14 changes: 13 additions & 1 deletion src/elements/subword/unquoted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@

use crate::{ShellCore, Feeder};
use crate::elements::subword::Subword;
use crate::elements::word::Word;

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct UnquotedSubword {
text: String,
}

impl Subword for UnquotedSubword {
fn get_text(&self) -> String { self.text.clone() }

fn copy(&self) -> Box<dyn Subword> {
Box::new(self.clone())
}

fn brace_expansion(&mut self, ans: &mut Vec<Word>) {
for a in ans.iter_mut() {
a.subwords.push(self.copy());
a.text += &self.text.clone();
}
}
}

impl UnquotedSubword {
Expand Down
28 changes: 28 additions & 0 deletions src/elements/word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ impl Word {
subwords: vec![],
}
}
pub fn copy(&self) -> Word {
Word {
text: self.text.clone(),
subwords: self.subwords.iter().map(|e| e.copy()).collect(),
}
}

pub fn concat(&mut self, left: &Word) {
self.text += &left.text;
for e in left.subwords.iter() {
self.subwords.push(e.copy());
}
}

pub fn add_text(&mut self, s: &str) {
self.text += &s.to_string();
self.subwords.push(Box::new(UnquotedSubword::new(s)));
}

pub fn brace_expansion(&mut self) -> Vec<Word> {
let mut ans = vec![Word::new()];

for sub in self.subwords.iter_mut() {
sub.brace_expansion(&mut ans);
}

ans
}

pub fn parse(feeder: &mut Feeder, core: &mut ShellCore) -> Option<Word> {
if feeder.starts_with("#") {
Expand Down
68 changes: 34 additions & 34 deletions test/test.bash
Original file line number Diff line number Diff line change
Expand Up @@ -341,28 +341,28 @@ res=$($com <<< 'rm -f /tmp/rusty_bash ; while [ -f /tmp/rusty_bash ] ; do echo w
# brace

res=$($com <<< 'echo {a,b}c')
[ "$res" == "<{a,b}>c" ] || err $LINENO
#[ "$res" == "ac bc" ] || err $LINENO
#[ "$res" == "<{a,b}>c" ] || err $LINENO
[ "$res" == "ac bc" ] || err $LINENO

res=$($com <<< 'echo c{a,b}')
[ "$res" == "c<{a,b}>" ] || err $LINENO
#[ "$res" == "ca cb" ] || err $LINENO
#[ "$res" == "c<{a,b}>" ] || err $LINENO
[ "$res" == "ca cb" ] || err $LINENO

res=$($com <<< 'echo {{a},b}')
[ "$res" == "<{<{a}>,b}>" ] || err $LINENO
#[ "$res" == "{a} b" ] || err $LINENO
#[ "$res" == "<{<{a}>,b}>" ] || err $LINENO
[ "$res" == "{a} b" ] || err $LINENO

res=$($com <<< 'echo {a,{b},c}')
[ "$res" == "<{a,<{b}>,c}>" ] || err $LINENO
#[ "$res" == "a {b} c" ] || err $LINENO
#[ "$res" == "<{a,<{b}>,c}>" ] || err $LINENO
[ "$res" == "a {b} c" ] || err $LINENO

res=$($com <<< 'echo {a,b,c{d,e}f,g{h,i{j,k}}}')
[ "$res" == "<{a,b,c<{d,e}>f,g<{h,i<{j,k}>}>}>" ] || err $LINENO
#[ "$res" == "a b cdf cef gh gij gik" ] || err $LINENO
#[ "$res" == "<{a,b,c<{d,e}>f,g<{h,i<{j,k}>}>}>" ] || err $LINENO
[ "$res" == "a b cdf cef gh gij gik" ] || err $LINENO

res=$($com <<< 'echo {a,b,c{d,e}f,g{h,i{j,k}}')
[ "$res" == "{a,b,c<{d,e}>f,g<{h,i<{j,k}>}>" ] || err $LINENO
#[ "$res" == "{a,b,cdf,gh {a,b,cdf,gij {a,b,cdf,gik {a,b,cef,gh {a,b,cef,gij {a,b,cef,gik" ] || err $LINENO
#[ "$res" == "{a,b,c<{d,e}>f,g<{h,i<{j,k}>}>" ] || err $LINENO
[ "$res" == "{a,b,cdf,gh {a,b,cdf,gij {a,b,cdf,gik {a,b,cef,gh {a,b,cef,gij {a,b,cef,gik" ] || err $LINENO

res=$($com <<< 'echo c{a,b')
[ "$res" == "c{a,b" ] || err $LINENO
Expand All @@ -371,47 +371,47 @@ res=$($com <<< 'echo c{a,b,')
[ "$res" == "c{a,b," ] || err $LINENO

res=$($com <<< 'echo {{a,b},{c,d},')
[ "$res" == "{<{a,b}>,<{c,d}>," ] || err $LINENO
#[ "$res" == "{a,c, {a,d, {b,c, {b,d," ] || err $LINENO
#[ "$res" == "{<{a,b}>,<{c,d}>," ] || err $LINENO
[ "$res" == "{a,c, {a,d, {b,c, {b,d," ] || err $LINENO

res=$($com <<< 'echo {{a,b},{c,d')
[ "$res" == "{<{a,b}>,{c,d" ] || err $LINENO
#[ "$res" == "{a,{c,d {b,{c,d" ] || err $LINENO
#[ "$res" == "{<{a,b}>,{c,d" ] || err $LINENO
[ "$res" == "{a,{c,d {b,{c,d" ] || err $LINENO

res=$($com <<< 'echo {{a,b,{c,')
[ "$res" == "{{a,b,{c," ] || err $LINENO

res=$($com <<< 'echo {a}')
[ "$res" == "<{a}>" ] || err $LINENO
#[ "$res" == "{a}" ] || err $LINENO
#[ "$res" == "<{a}>" ] || err $LINENO
[ "$res" == "{a}" ] || err $LINENO

res=$($com <<< 'echo {a,}')
[ "$res" == "<{a,}>" ] || err $LINENO
#[ "$res" == "a" ] || err $LINENO
#[ "$res" == "<{a,}>" ] || err $LINENO
[ "$res" == "a" ] || err $LINENO

res=$($com <<< 'echo {a,b,}')
[ "$res" == "<{a,b,}>" ] || err $LINENO
#[ "$res" == "a b" ] || err $LINENO
#[ "$res" == "<{a,b,}>" ] || err $LINENO
[ "$res" == "a b" ] || err $LINENO

res=$($com <<< 'echo {a,b,}c')
[ "$res" == "<{a,b,}>c" ] || err $LINENO
#[ "$res" == "ac bc c" ] || err $LINENO
#[ "$res" == "<{a,b,}>c" ] || err $LINENO
[ "$res" == "ac bc c" ] || err $LINENO

res=$($com <<< 'echo {}')
[ "$res" == "{}" ] || err $LINENO
#[ "$res" == "{}" ] || err $LINENO
[ "$res" == "{}" ] || err $LINENO

res=$($com <<< 'echo {,}')
[ "$res" == "<{,}>" ] || err $LINENO
#[ "$res" == "" ] || err $LINENO
#[ "$res" == "<{,}>" ] || err $LINENO
[ "$res" == "" ] || err $LINENO

res=$($com <<< 'echo {,,}')
[ "$res" == "<{,,}>" ] || err $LINENO
#[ "$res" == "" ] || err $LINENO
#[ "$res" == "<{,,}>" ] || err $LINENO
[ "$res" == "" ] || err $LINENO

res=$($com <<< 'echo a{,,}b')
[ "$res" == "a<{,,}>b" ] || err $LINENO
#[ "$res" == "ab ab ab" ] || err $LINENO
#[ "$res" == "a<{,,}>b" ] || err $LINENO
[ "$res" == "ab ab ab" ] || err $LINENO

res=$($com <<< 'echo {')
[ "$res" == "{" ] || err $LINENO
Expand All @@ -420,14 +420,14 @@ res=$($com <<< 'echo }')
[ "$res" == "}" ] || err $LINENO

res=$($com <<< 'echo {a,}{b,}')
[ "$res" == "<{a,}><{b,}>" ] || err $LINENO
#[ "$res" == "ab a b" ] || err $LINENO
#[ "$res" == "<{a,}><{b,}>" ] || err $LINENO
[ "$res" == "ab a b" ] || err $LINENO

res=$($com <<< 'echo {},b}')
[ "$res" == "{},b}" ] || err $LINENO

res=$($com <<< 'echo a{},b}')
[ "$res" == "a<{},b}>" ] || err $LINENO
[ "$res" == "a} ab" ] || err $LINENO

### WHILE TEST ###

Expand Down

0 comments on commit 2aab001

Please sign in to comment.