abigen: try getting headers

This commit is contained in:
Artemis Tosini 2024-09-13 02:53:05 +00:00
parent ac065b60f7
commit 1084402c28
Signed by: artemist
GPG key ID: ADFFE553DCBB831E

View file

@ -1,6 +1,11 @@
use std::{collections::HashMap, env, path::PathBuf, vec};
use std::{
collections::BTreeMap,
env,
fs::{self, File},
io::Read,
path::{Path, PathBuf},
};
use clang::{Entity, EntityKind};
use color_eyre::eyre;
use regex::Regex;
@ -8,49 +13,50 @@ fn main() -> eyre::Result<()> {
env_logger::init();
color_eyre::install()?;
let re = Regex::new(r#"^#define\s*(STEAM[A-Z]*)_INTERFACE_VERSION\s*"([a-zA-Z0-9_]*)"$"#)?;
let lsteamclient_path =
PathBuf::from(env::var_os("PROTON_SOURCE").unwrap_or_else(|| "proton".into()))
.join("lsteamclient");
let clang = clang::Clang::new().unwrap();
let mut versions = BTreeMap::new();
let index = clang::Index::new(&clang, false, false);
let parsed = index
.parser(
lsteamclient_path
.join("steamworks_sdk_160")
.join("steam_api.h"),
)
.arguments(&["-x", "c++"])
.detailed_preprocessing_record(true)
.parse()?;
let mut classes = Vec::new();
// let mut interfaces = HashMap::new();
for child in parsed.get_entity().get_children() {
if child.get_kind() == EntityKind::ClassDecl {
let Some(class_name) = child.get_name() else {
continue;
};
if !class_name.starts_with("ISteam") {
continue;
};
if child.get_children().len() == 0 {
continue;
}
log::info!("Found class `{}`", class_name);
classes.push(class_name);
for maybe_sdk in fs::read_dir(lsteamclient_path)? {
let sdk = maybe_sdk?;
if !sdk.file_type()?.is_dir() {
continue;
}
let this_versions = interface_versions(&sdk.path())?;
versions.insert(sdk.file_name(), this_versions);
}
println!("{:#?}", versions);
Ok(())
}
fn interface_versions(path: &Path) -> eyre::Result<BTreeMap<String, String>> {
let re = Regex::new(r#"#define\s*(STEAM[A-Z]*)_INTERFACE_VERSION\s*"([a-zA-Z0-9_]*)""#)?;
let mut versions = BTreeMap::new();
for maybe_file in fs::read_dir(path)? {
let file = maybe_file?;
if !file.file_name().to_string_lossy().ends_with(".h") {
continue;
}
let mut content_bytes = Vec::new();
if let Err(e) = File::open(file.path())?.read_to_end(&mut content_bytes) {
log::warn!("Got error in {:?}: {}", file.path(), e)
}
let content: String = content_bytes.into_iter().map(|c| c as char).collect();
for capture in re.captures_iter(&content) {
versions.insert(
capture.get(1).unwrap().as_str().to_string(),
capture.get(2).unwrap().as_str().to_string(),
);
}
}
Ok(versions)
}