Skip to content
Snippets Groups Projects
Commit 277b13de authored by Michael Aaron Murphy's avatar Michael Aaron Murphy
Browse files

Merge branch 'trim-commands' into 'master'

Trim start and end of commands

See merge request redox-os/ion!930
parents f1e06847 5789f8ce
No related branches found
No related tags found
No related merge requests found
...@@ -109,9 +109,10 @@ impl<I: Iterator<Item = u8>> Iterator for Terminator<I> { ...@@ -109,9 +109,10 @@ impl<I: Iterator<Item = u8>> Iterator for Terminator<I> {
&& !self.and_or && !self.and_or
{ {
self.terminated = true; self.terminated = true;
None
} else {
out
} }
out
} }
} }
...@@ -122,7 +123,7 @@ impl<I: Iterator<Item = u8>> Terminator<I> { ...@@ -122,7 +123,7 @@ impl<I: Iterator<Item = u8>> Terminator<I> {
let stmt = self.collect::<Vec<_>>(); let stmt = self.collect::<Vec<_>>();
let stmt = unsafe { String::from_utf8_unchecked(stmt) }; let stmt = unsafe { String::from_utf8_unchecked(stmt) };
if self.terminated && !stmt.is_empty() { if self.terminated {
Ok(stmt) Ok(stmt)
} else { } else {
Err(()) Err(())
...@@ -130,85 +131,93 @@ impl<I: Iterator<Item = u8>> Terminator<I> { ...@@ -130,85 +131,93 @@ impl<I: Iterator<Item = u8>> Terminator<I> {
} }
fn handle_char(&mut self, character: Option<u8>) -> Option<u8> { fn handle_char(&mut self, character: Option<u8>) -> Option<u8> {
character character.and_then(|character| {
.and_then(|character| { let prev_whitespace = self.whitespace;
let prev_whitespace = self.whitespace; self.whitespace = false;
self.whitespace = false;
if let Some(matcher) = self.eof.as_mut() {
if let Some(matcher) = self.eof.as_mut() { if matcher.next(character) {
if matcher.next(character) { self.eof = None;
self.eof = None; }
Some(character)
} else if self.skip_next {
self.skip_next = false;
Some(character)
} else if self.quotes != Quotes::None && character != b'\\' {
match (character, &self.quotes) {
(b'\'', Quotes::Single) | (b'"', Quotes::Double) => {
self.quotes = Quotes::None;
} }
} else if self.skip_next { _ => (),
self.skip_next = false; }
} else if self.quotes != Quotes::None && character != b'\\' { Some(character)
match (character, &self.quotes) { } else {
(b'\'', Quotes::Single) | (b'"', Quotes::Double) => { match character {
self.quotes = Quotes::None; b'\'' => {
} self.quotes = Quotes::Single;
_ => (), Some(b'\'')
} }
} else { b'"' => {
match character { self.quotes = Quotes::Double;
b'\'' => { Some(b'"')
self.quotes = Quotes::Single; }
} b'<' if self.inner.prev() == Some(&b'<') => {
b'"' => { if let Some(&b'<') = self.inner.peek() {
self.quotes = Quotes::Double; self.skip_next = true; // avoid falling in the else at the next pass
} } else {
b'<' if self.inner.prev() == Some(&b'<') => { self.eof = Some(EofMatcher::new());
if let Some(&b'<') = self.inner.peek() {
self.skip_next = true; // avoid falling in the else at the next pass
} else {
self.eof = Some(EofMatcher::new());
}
}
b'[' => {
self.array += 1;
}
b']' => {
if self.array > 0 {
self.array -= 1;
}
}
b'#' if self
.inner
.prev()
.filter(|&c| ![b' ', b'\n'].contains(c))
.is_none() =>
{
return self.inner.find(|&c| c == b'\n');
}
b'\\' => {
if self.inner.peek() == Some(&b'\n') {
let next = self.inner.find(|&c| !(c as char).is_whitespace());
return self.handle_char(next);
} else {
self.skip_next = true;
}
} }
b'&' | b'|' if self.inner.prev() == Some(&character) => { Some(b'<')
self.and_or = true; }
b'[' => {
self.array += 1;
Some(b'[')
}
b']' => {
if self.array > 0 {
self.array -= 1;
} }
b'\n' if self.array == 0 && !self.and_or => { Some(b']')
self.terminated = true; }
b'#' if self.inner.prev().filter(|&c| ![b' ', b'\n'].contains(c)).is_none() => {
self.whitespace = prev_whitespace;
let next = self.inner.find(|&c| c == b'\n');
self.handle_char(next)
}
b'\\' => {
if self.inner.peek() == Some(&b'\n') {
let next = self.inner.find(|&c| !(c as char).is_whitespace());
self.handle_char(next)
} else {
self.skip_next = true;
Some(character)
} }
_ if (character as char).is_whitespace() => { }
if prev_whitespace { b'&' | b'|' if self.inner.prev() == Some(&character) => {
let next = self.inner.find(|&c| !(c as char).is_whitespace()); self.and_or = true;
return self.handle_char(next); Some(character)
} }
b'\n' if self.array == 0 && !self.and_or => {
self.terminated = true;
None
}
_ if (character as char).is_whitespace() => {
if prev_whitespace {
let next =
self.inner.find(|&c| c == b'\n' || !(c as char).is_whitespace());
self.handle_char(next)
} else {
self.whitespace = true; self.whitespace = true;
} Some(b' ')
_ => {
self.and_or = false;
} }
} }
_ => {
self.and_or = false;
Some(character)
}
} }
}
Some(character) })
})
.map(|c| if c == b'\n' && self.array > 0 { b' ' } else { c })
} }
pub fn new(inner: I) -> Terminator<I> { pub fn new(inner: I) -> Terminator<I> {
...@@ -220,7 +229,7 @@ impl<I: Iterator<Item = u8>> Terminator<I> { ...@@ -220,7 +229,7 @@ impl<I: Iterator<Item = u8>> Terminator<I> {
quotes: Quotes::None, quotes: Quotes::None,
terminated: false, terminated: false,
and_or: false, and_or: false,
whitespace: false, whitespace: true,
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment