WIP early start on pipe command

This commit is contained in:
Ava Apples Affine 2023-04-05 21:18:40 -07:00
parent ba38fbde04
commit 9c0f88ec91
Signed by: affine
GPG key ID: 3A4645B8CF806069
2 changed files with 71 additions and 2 deletions

View file

@ -165,6 +165,57 @@ fn load_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Resu
}
}
// TODO: maybe flesh out this docstring a bit
const PIPE_DOCSTRING: &str = "Calls a sequence of shell commands.
Each one has their output redirected to the input of the next one.
Example:
(pipe
(ls -la)
(grep '*.rs')
(tr -d '.rs'))";
fn pipe_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Result<Ctr, String> {
if ast.is_empty() {
return Err("need at least one argument".to_string())
}
let mut input = Stdio::inherit();
if !ast.circuit(&mut |arg: &Ctr| -> bool {
if let Ctr::Seg(command_form) = arg {
let args = VecDeque::from(args_from_ast(ast, syms));
if args.is_empty() {
return false
}
if let Some(filepath) = run::find_on_path(args.pop_front().unwrap()) {
let tmp = Stdio::piped();
// TODO Youll just have to break open launch_command here
// youll need seperate calls for .stdin and .stdout anyways
// and also the move semantics are not working
launch_command(
filepath,
&Vec::from(args.make_contiguous()),
input,
Stdio::inherit(),
tmp,
false,
state,
).unwrap();
input = tmp;
true
} else {
eprintln!("file not found");
false
}
} else {
false
}
}) {
Err("all arguments must be full shell commands".to_string())
} else {
Ok(Ctr::None)
}
}
const LOAD_TO_STRING_DOCSTRING: &str = "Calls a binary off disk with given arguments.
Arguments may be of any type except lambda. If a symbol is not defined it will be passed as a string.
@ -208,7 +259,25 @@ fn load_to_string_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellStat
}
// TODO: rework this callback to reduce spaghett
const LOAD_WITH_DOCSTRING: &str = "";
const LOAD_WITH_DOCSTRING: &str = "Takes two arguments.
1. a list of up to three redirects
- A redirect looks like a variable declaration in a let form
Ex: ('stdout' '/dev/null')
- The first value is one of 'stdout', 'stdin', or 'stderr'
- The second value is a filename.
The file must exist for stdin redirects.
For other redirects the file will be created if not existing.
Example: (('stdin' '/path/to/myinput.txt')
('stdout' '/dev/null'))
2. a shell command
- exactly as would be passed to load
Example: (ping -c 4 google.com)
Example invocation:
(load-with (('stdout' '/dev/null'))
(ping -c 4 google.com))";
fn load_with_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Result<Ctr, String> {
if ast.len() != 2 {
Err("exactly two arguments needed".to_string())