use std::ffi::OsString;
use std::path::PathBuf;
use std::process::exit;
use std::sync::Arc;
use std::sync::RwLock;
use clap::Parser;
use unlab_gpu::Home;
use unlab_gpu::ModNode;
use unlab_gpu::Value;
use unlab_gpu::add_std_builtin_funs;
use unlab_gpu::finalize_backend;
use unlab_gpu::initialize_backend;
use unlab_gpu::main_loop;
#[derive(Parser, Debug)]
#[command(version)]
struct Args
{
#[arg(short = 'H', long)]
home_dir: Option<String>,
#[arg(short = 'B', long)]
bin_path: Option<String>,
#[arg(short = 'L', long)]
lib_path: Option<String>,
#[arg(short = 'D', long)]
doc_path: Option<String>,
#[arg(short, long)]
bin_dir: Vec<String>,
#[arg(short, long)]
lib_dir: Vec<String>,
#[arg(short, long)]
doc_dir: Vec<String>,
#[arg(short, long)]
no_ctrl_c: bool,
#[arg(short = 'p', long)]
no_plotter_windows: bool,
script_file: Option<String>,
args: Vec<String>,
}
fn main()
{
let args = Args::parse();
let mut home = match Home::new(&args.home_dir, &args.bin_path, &args.lib_path, &args.doc_path, false) {
Some(tmp_home) => tmp_home,
None => {
eprintln!("no unlab-gpu home directory");
exit(1);
},
};
match home.add_dirs_to_bin_path(args.bin_dir.as_slice()) {
Ok(()) => (),
Err(err) => {
eprintln!("{}", err);
exit(1);
},
}
match home.add_dirs_to_lib_path(args.lib_dir.as_slice()) {
Ok(()) => (),
Err(err) => {
eprintln!("{}", err);
exit(1);
},
}
match home.add_dirs_to_doc_path(args.doc_dir.as_slice()) {
Ok(()) => (),
Err(err) => {
eprintln!("{}", err);
exit(1);
},
}
match initialize_backend(home.backend_config_file()) {
Ok(()) => (),
Err(err) => {
eprintln!("{}", err);
exit(1);
},
}
let exit_code = {
let mut root_mod: ModNode<Value, ()> = ModNode::new(());
add_std_builtin_funs(&mut root_mod);
let root_mod_arc = Arc::new(RwLock::new(root_mod));
main_loop(args.script_file.clone(), args.args.clone(), PathBuf::from(home.history_file()), root_mod_arc, OsString::from(home.lib_path()), OsString::from(home.doc_path()), !args.no_ctrl_c, !args.no_plotter_windows)
};
match finalize_backend() {
Ok(()) => (),
Err(err) => {
eprintln!("{}", err);
exit(1);
},
}
match exit_code {
Some(exit_code) => exit(exit_code),
None => (),
}
}