use autoconf_rs_cli::read_input;
use autoconf_rs_core::trace::AutoconfEvent;
use autoconf_rs_core::M4Engine;
use std::env;
use std::process::ExitCode;
fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();
let input_path = args.get(1).map(|s| s.as_str()).unwrap_or("configure.ac");
if input_path == "--help" || input_path == "-h" {
println!("autoheader-rs {}", env!("CARGO_PKG_VERSION"));
println!("Generate config.h.in from configure.ac");
println!("Usage: autoheader [configure.ac]");
println!(" -h, --help Show this help");
println!(" --version Show version");
return ExitCode::SUCCESS;
}
if input_path == "--version" {
println!("autoheader-rs {}", env!("CARGO_PKG_VERSION"));
return ExitCode::SUCCESS;
}
let input = match read_input(input_path) {
Ok(s) => s,
Err(e) => {
eprintln!("autoheader: {}", e);
return ExitCode::from(2);
}
};
let mut engine = M4Engine::new();
match engine.process(&input) {
Ok(_output) => {
let trace_log = &engine.trace_log;
let headers: Vec<&str> = trace_log
.events
.iter()
.filter_map(|e| match e {
AutoconfEvent::ConfigHeader { output, .. } => Some(output.as_str()),
_ => None,
})
.collect();
if headers.is_empty() {
eprintln!("autoheader: no AC_CONFIG_HEADERS in configure.ac");
eprintln!(
" (checked {} trace events, 0 ConfigHeader found)",
trace_log.events.len()
);
return ExitCode::from(1);
}
let defines: Vec<(&str, Option<&str>)> = trace_log
.events
.iter()
.filter_map(|e| match e {
AutoconfEvent::Define { name, value, .. } => {
Some((name.as_str(), value.as_deref()))
}
_ => None,
})
.collect();
let header_file = headers.first().unwrap_or(&"config.h");
println!(
"/* {} — Generated by autoconf-rs autoheader (trace-driven). */",
header_file
);
println!(
"/* Source: {} — {} trace events, {} AC_DEFINE, {} AC_CONFIG_HEADERS */",
input_path,
trace_log.events.len(),
defines.len(),
headers.len()
);
println!();
if defines.is_empty() {
println!("/* No AC_DEFINE calls found in trace events. */");
println!("/* Try: autom4te --trace=AC_DEFINE {} */", input_path);
} else {
for (var, _value) in &defines {
println!("#undef {}", var);
}
}
println!();
println!("/* Template entries for autoheader compatibility */");
for (var, value) in &defines {
let desc = value.unwrap_or("");
if !desc.is_empty() {
println!("@%:@undef {} /* {} */", var, desc);
} else {
println!("@%:@undef {}", var);
}
}
eprintln!(
"autoheader: generated {} with {} #undef entries (trace-driven)",
header_file,
defines.len()
);
ExitCode::SUCCESS
}
Err(e) => {
eprintln!("autoheader: {}", e);
ExitCode::from(2)
}
}
}