use crate::action::AtomicAction;
use crate::lexer::Token;
use crate::shell::{ClassifyError, Sink};
pub(super) fn push(tokens: &[Token], sink: &mut Sink) -> Result<(), ClassifyError> {
let mut flat: Vec<String> = Vec::new();
let mut starts: Vec<usize> = Vec::new();
let mut at_command_start = true;
let mut trailing_separators = 0;
for token in tokens {
match token {
Token::Word(w) => {
if at_command_start {
starts.push(flat.len());
at_command_start = false;
}
flat.push(w.text.clone());
trailing_separators = 0;
}
Token::Operator(op) if op.is_separator() => {
if !at_command_start {
flat.push(op.symbol().to_owned());
trailing_separators += 1;
}
at_command_start = true;
}
Token::Operator(op) if op.is_redirect() => {
flat.push(op.symbol().to_owned());
trailing_separators = 0;
}
Token::Operator(_) | Token::HereDoc { .. } => {}
}
}
flat.truncate(flat.len() - trailing_separators);
if starts.len() < 2 {
return Ok(());
}
for &start in &starts[..starts.len() - 1] {
sink.push(AtomicAction::Pipeline {
argv: flat[start..].to_vec(),
})?;
}
Ok(())
}