pub fn parse_gdb_version(output: &str) -> Option<String> {
for line in output.lines() {
if line.starts_with("exec:") {
continue;
}
if line.contains("GNU gdb") {
let parts: Vec<&str> = line.split_whitespace().collect();
for (i, part) in parts.iter().enumerate() {
if *part == "gdb" {
if let Some(version) = parts.get(i + 1) {
if version.chars().next().map_or(false, |c| c.is_ascii_digit()) {
return Some(version.to_string());
}
}
}
}
}
}
output
.lines()
.next()
.and_then(|line| {
line.split_whitespace()
.find(|token| token.chars().next().map_or(false, |c| c.is_ascii_digit()))
})
.map(|s| s.to_string())
}
pub fn is_gdb_version_sufficient(version: &str) -> bool {
let parts: Vec<&str> = version.split('.').collect();
let Some(major_str) = parts.get(0) else {
return false;
};
let Some(minor_str) = parts.get(1) else {
return false;
};
let Ok(major) = major_str.parse::<u32>() else {
return false;
};
let Ok(minor) = minor_str.parse::<u32>() else {
return false;
};
major > 14 || (major == 14 && minor >= 1)
}
pub async fn get_gdb_version(path: &std::path::PathBuf) -> Option<String> {
let output = tokio::process::Command::new(path)
.arg("--version")
.output()
.await
.ok()?;
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
parse_gdb_version(&stdout)
} else {
None
}
}