#![allow(clippy::ptr_arg)]
use clap::Parser;
use std::path::Path;
use std::time::SystemTime;
use vhdl_lang::{Config, Diagnostic, MessagePrinter, Project};
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(short = 'p', long)]
num_threads: Option<usize>,
#[arg(long, default_value_t = false)]
perf: bool,
#[arg(short, long)]
config: String,
#[arg(long)]
dump_unresolved: bool,
#[arg(long)]
count_unresolved: bool,
}
fn main() {
let args = Args::parse();
rayon::ThreadPoolBuilder::new()
.num_threads(args.num_threads.unwrap_or(0))
.build_global()
.unwrap();
let mut config = Config::default();
let mut msg_printer = MessagePrinter::default();
config.load_external_config(&mut msg_printer);
config.append(
&Config::read_file_path(Path::new(&args.config)).expect("Failed to read config file"),
&mut msg_printer,
);
let start = SystemTime::now();
let mut project = Project::from_config(&config, &mut msg_printer);
let diagnostics = project.analyse();
let duration = start.elapsed().unwrap();
show_diagnostics(&diagnostics);
if args.perf {
let mut num_files = 0;
let mut num_lines = 0;
for source_file in project.files() {
num_files += 1;
num_lines += source_file.num_lines();
}
let duration_per_line = duration.checked_div(num_lines as u32).unwrap();
println!(
"Analyzed {} files with {} lines of code",
num_files, num_lines
);
println!(
"Total time to run was {} ms with an average of {} ns per line",
duration.as_millis(),
duration_per_line.as_nanos()
);
}
if args.dump_unresolved || args.count_unresolved {
let (total, unresolved) = project.find_all_unresolved();
if args.dump_unresolved {
for pos in unresolved.iter() {
println!("{}", pos.show("Unresolved"));
}
}
if args.count_unresolved {
println!("{} out of {} positions unresolved", unresolved.len(), total);
}
}
std::process::exit(0);
}
fn show_diagnostics(diagnostics: &[Diagnostic]) {
for diagnostic in diagnostics {
println!("{}", diagnostic.show());
}
}