mod config;
mod help;
mod repl;
use std::io::IsTerminal;
fn main() {
let result = std::thread::Builder::new()
.stack_size(64 * 1024 * 1024)
.spawn(run)
.expect("failed to spawn main thread")
.join();
if let Err(e) = result {
std::panic::resume_unwind(e);
}
}
fn run() {
ccalc_engine::exec::init();
let args: Vec<String> = std::env::args().collect();
if args.len() > 1 {
match args[1].as_str() {
"-v" | "--version" => {
println!("ccalc v{}", env!("CARGO_PKG_VERSION"));
return;
}
"-h" | "--help" => {
help::print(None);
return;
}
arg if !arg.starts_with('-') => {
let config_path = ccalc_engine::env::config_dir().join("config.toml");
if let Ok(cfg) = config::load(&config_path) {
ccalc_engine::exec::session_path_init(cfg.search_path());
}
let resolved = std::path::Path::new(arg)
.is_file()
.then(|| std::path::PathBuf::from(arg))
.or_else(|| ccalc_engine::exec::resolve_script_path(arg));
if let Some(path) = resolved {
let file = std::fs::File::open(&path).unwrap_or_else(|e| {
eprintln!("Error opening '{}': {e}", path.display());
std::process::exit(1);
});
if let Some(dir) = path
.canonicalize()
.ok()
.and_then(|p| p.parent().map(|d| d.to_path_buf()))
{
ccalc_engine::exec::script_dir_push(&dir);
}
repl::run_pipe(std::io::BufReader::new(file));
} else {
repl::run_expr(arg);
}
return;
}
flag => {
eprintln!("Unknown option: {flag}");
eprintln!("Run 'ccalc -h' for usage.");
std::process::exit(1);
}
}
}
if !std::io::stdin().is_terminal() {
repl::run_pipe(std::io::stdin().lock());
} else {
repl::run();
}
}