#[cfg(feature = "dhat-heap")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
use std::process;
fn main() {
#[cfg(feature = "dhat-heap")]
let _profiler = dhat::Profiler::new_heap();
let args: Vec<String> = std::env::args().collect();
let status = match args.get(1).map(|s| s.as_str()) {
Some("--exec-loop") => run_exec_loop(&args[2..]),
Some("--pre-prompt-loop") => run_pre_prompt_loop(&args[2..]),
Some(_) => run_script(&args[1]),
None => {
eprintln!(
"usage: {bin} <script-path>\n {bin} --exec-loop N CMD [ARG ...]\n {bin} --pre-prompt-loop N",
bin = args.first().map(String::as_str).unwrap_or("yosh-dhat")
);
2
}
};
#[cfg(feature = "dhat-heap")]
drop(_profiler);
process::exit(status);
}
fn run_script(script_path: &str) -> i32 {
let input = match std::fs::read_to_string(script_path) {
Ok(s) => s,
Err(e) => {
eprintln!("yosh-dhat: {}: {}", script_path, e);
return 127;
}
};
yosh::signal::init_signal_handling();
let mut executor = yosh::exec::Executor::new("yosh-dhat", vec![]);
yosh::env::default_path::ensure_default_path(&mut executor.env);
executor.load_plugins();
let program = match yosh::parser::Parser::new(&input).parse_program() {
Ok(p) => p,
Err(e) => {
eprintln!("yosh-dhat: parse error: {}", e);
return 2;
}
};
let status = executor.exec_program(&program);
executor.process_pending_signals();
executor.execute_exit_trap();
status
}
fn run_exec_loop(args: &[String]) -> i32 {
let n: u32 = match args.first().and_then(|s| s.parse().ok()) {
Some(n) if n > 0 => n,
_ => {
eprintln!("yosh-dhat: --exec-loop: missing or invalid N (positive integer)");
return 2;
}
};
let cmd = match args.get(1) {
Some(c) => c.clone(),
None => {
eprintln!("yosh-dhat: --exec-loop: missing CMD");
return 2;
}
};
let cmd_args: Vec<String> = args.iter().skip(2).cloned().collect();
yosh::signal::init_signal_handling();
let mut executor = yosh::exec::Executor::new("yosh-dhat", vec![]);
yosh::env::default_path::ensure_default_path(&mut executor.env);
executor.load_plugins();
let mut last_status = 0;
for _ in 0..n {
let r = executor
.plugins
.exec_command(&mut executor.env, &cmd, &cmd_args);
last_status = match r {
yosh::plugin::PluginExec::Handled(code) => code,
yosh::plugin::PluginExec::NotHandled => 127,
yosh::plugin::PluginExec::Failed => 1,
};
}
last_status
}
fn run_pre_prompt_loop(args: &[String]) -> i32 {
let n: u32 = match args.first().and_then(|s| s.parse().ok()) {
Some(n) if n > 0 => n,
_ => {
eprintln!("yosh-dhat: --pre-prompt-loop: missing or invalid N (positive integer)");
return 2;
}
};
yosh::signal::init_signal_handling();
let mut executor = yosh::exec::Executor::new("yosh-dhat", vec![]);
yosh::env::default_path::ensure_default_path(&mut executor.env);
executor.load_plugins();
for _ in 0..n {
executor.plugins.call_pre_prompt(&mut executor.env);
}
0
}