From fa268537b07821920aab9a79408133d12586d9cf Mon Sep 17 00:00:00 2001 From: oberrich Date: Thu, 2 Jan 2025 07:48:39 +0100 Subject: [PATCH] feat(doxygen): use custom parser --- Cargo.lock | 80 ++++----------------------------------- Cargo.toml | 4 +- src/build.rs | 104 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 108 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92fce1a..4b4a056 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,15 +133,6 @@ dependencies = [ "syn", ] -[[package]] -name = "doxygen-rs" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9" -dependencies = [ - "phf", -] - [[package]] name = "either" version = "1.11.0" @@ -264,48 +255,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - [[package]] name = "phnt" version = "0.0.32" @@ -313,10 +262,10 @@ dependencies = [ "bindgen", "chrono", "cty", - "doxygen-rs", "nt-string", "regex", "windows-sys", + "yap", ] [[package]] @@ -347,21 +296,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" - [[package]] name = "regex" version = "1.11.1" @@ -403,12 +337,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - [[package]] name = "syn" version = "2.0.59" @@ -567,3 +495,9 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "yap" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe269e7b803a5e8e20cbd97860e136529cd83bf2c9c6d37b142467e7e1f051f" diff --git a/Cargo.toml b/Cargo.toml index 0e96b9f..4910cd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ build = "src/build.rs" description = "Rust bindings to the System Informer's (formerly known as Process Hacker) `phnt` native Windows headers" [features] -regenerate = ["dep:regex", "dep:bindgen", "dep:chrono", "dep:doxygen-rs"] +regenerate = ["dep:regex", "dep:bindgen", "dep:chrono", "dep:yap"] [package.metadata.docs.rs] default-target = "x86_64-pc-windows-msvc" @@ -22,7 +22,7 @@ rustc-args = ["--cfg", "docsrs"] regex = { version = "1.11.1", optional = true } bindgen = { version = "0.71.1", optional = true } chrono = { version = "0.4.39", optional = true } -doxygen-rs = { version = "0.4.2", optional = true } +yap = { version = "0.12.0", optional = true } [dependencies.windows-sys] version = "0.59.0" diff --git a/src/build.rs b/src/build.rs index 72fd58e..20f6f70 100644 --- a/src/build.rs +++ b/src/build.rs @@ -25,7 +25,7 @@ #[cfg_attr(docsrs, doc(cfg(feature = "regenerate")))] #[cfg(feature = "regenerate")] -pub use regen::main; +use regen::main; #[cfg_attr(docsrs, doc(cfg(not(feature = "regenerate"))))] #[cfg(not(feature = "regenerate"))] @@ -33,6 +33,99 @@ fn main() { println!("Using vsendored bindings, build script skipped."); } +#[cfg_attr(docsrs, doc(cfg(feature = "regenerate")))] +#[cfg(feature = "regenerate")] +mod doxygen { + use yap::{IntoTokens, Tokens}; + static SEPS: [char; 5] = [' ', '\t', '\r', '\n', '[']; + + fn format_ref(str: String) -> String { + assert!(!str.contains(' ')); + // Don't turn URIs into code refs + if !str.contains("://") { + format!("[`{}`]", str) + } else { + str + } + } + + fn take_word(toks: &mut impl Tokens) -> String { + toks + .take_while(|&c| !SEPS.into_iter().any(|s| c == s)) + .collect::() + } + + fn skip_whitespace(toks: &mut impl Tokens) { + toks.skip_while(|c| c.is_ascii_whitespace()); + } + + pub fn transform(str: &str) -> String { + let mut res: Vec = vec![]; + let mut toks = str.into_tokens(); + let mut first_param = true; + let mut first_see_also = true; + + skip_whitespace(&mut toks); + while let Some(tok) = toks.next() { + if "@\\".chars().any(|c| c == tok) { + let tag = take_word(&mut toks); + skip_whitespace(&mut toks); + match tag.as_str() { + "param" => { + if first_param { + res.push("# Arguments\n\n".to_owned()); + first_param = false; + } + + let (mut argument, mut attributes) = (take_word(&mut toks), "".to_owned()); + if argument.is_empty() { + assert_eq!(toks.next().expect("has more input"), '['); + attributes = toks.take_while(|&c| c != ']').collect::(); + assert_eq!(toks.next().expect("has more input"), ']'); + attributes = format!(" [{}] ", attributes); + skip_whitespace(&mut toks); + argument = take_word(&mut toks); + } + + res.push(format!("* `{}`{} -", argument, attributes)); + } + "c" | "p" => res.push(format!("`{}`", take_word(&mut toks))), + "ref" => res.push(format_ref(take_word(&mut toks))), + "see" | "sa" => { + if first_see_also { + res.push("# See also\n\n".to_owned()); + first_see_also = false; + } + + res.push(format!("\t{}", format_ref(take_word(&mut toks)))); + } + "a" | "e" | "em" => res.push(format!("_{}_", take_word(&mut toks))), + "b" => res.push(format!("**{}**", take_word(&mut toks))), + "note" => res.push("> **Note:** ".to_owned()), + "since" => res.push("> Available since: ".to_owned()), + "deprecated" => res.push("> **Deprecated** ".to_owned()), + "remark" | "remarks" => res.push("> ".to_owned()), + "li" => res.push("- ".to_owned()), + "par" => res.push("# ".to_owned()), + "returns" | "return" | "result" => res.push("# Returns\n\n".to_owned()), + "{" => { /* group start, not implemented */ } + "}" => { /* group end, not implemented */ } + "brief" | "short" => {} + _ => { + res.push(format!("{tok}{tag} ")); + } + } + } else if tok == '\n' { + skip_whitespace(&mut toks); + res.push(format!("{tok}")); + } else { + res.push(format!("{tok}")); + } + } + res.join("") + } +} + #[cfg_attr(docsrs, doc(cfg(feature = "regenerate")))] #[cfg(feature = "regenerate")] mod regen { @@ -48,20 +141,21 @@ mod regen { impl ParseCallbacks for ProcessComments { fn process_comment(&self, comment: &str) -> Option { - match std::panic::catch_unwind(|| doxygen_rs::transform(comment)) { + match std::panic::catch_unwind(|| crate::doxygen::transform(comment)) { Ok(res) => Some(res), Err(err) => { println!( - "cargo:warning=Problem processing comment: {}", + "cargo:warning=Problem processing comment: {}\n{}", + comment, if let Some(msg) = err.downcast_ref::() { - msg + msg.as_str() } else if let Some(msg) = err.downcast_ref::<&str>() { msg } else { "Unknown panic type" } ); - None + Some(comment.to_owned()) } } }