use clap::error::ErrorKind;
use clap::{Args, CommandFactory, Parser, Subcommand};
const AFTER_HELP: &str = "EXIT CODES:
0 - Analysis passed (score >= 90)
1 - Analysis passed with warnings (score 70-89)
2 - Analysis failed (score < 70)
3 - Critical bugs detected
10 - Parse error
11 - I/O error
EXAMPLES:
aprender-ptx-debug analyze kernel.ptx --falsify
aprender-ptx-debug analyze kernel.ptx --min-score 90 --html report.html
aprender-ptx-debug gen-fkr kernel.ptx -o tests/kernel_fkr.rs";
#[derive(Debug, Parser)]
#[command(
name = "aprender-ptx-debug",
about = "Pure Rust PTX debugging and static analysis tool",
version,
subcommand_required = true,
arg_required_else_help = true,
after_help = AFTER_HELP
)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
#[derive(Debug, Subcommand)]
pub enum Command {
Analyze(AnalyzeArgs),
#[command(name = "gen-fkr")]
GenFkr(GenFkrArgs),
Version,
}
#[derive(Debug, Args)]
pub struct AnalyzeArgs {
#[arg(value_name = "FILE")]
pub file: String,
#[arg(long)]
pub falsify: bool,
#[arg(long = "min-score", value_name = "N", default_value_t = 70.0)]
pub min_score: f64,
#[arg(long, value_name = "FILE")]
pub html: Option<String>,
#[arg(long)]
pub json: bool,
}
#[derive(Debug, Args)]
pub struct GenFkrArgs {
#[arg(value_name = "FILE")]
pub file: String,
#[arg(short = 'o', value_name = "FILE")]
pub output: Option<String>,
}
#[must_use]
pub fn version_string() -> String {
Cli::command().render_version()
}
#[must_use]
pub fn exit_code_for_parse_error(err: &clap::Error) -> i32 {
match err.kind() {
ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => 0,
_ => 1,
}
}