Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions library/bind-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ struct Cb;
impl ParseCallbacks for Cb {
fn process_comment(&self, comment: &str) -> Option<String> {
let comment = comment.replace("@retval {", "@retval return_value {");
// doxygen-rs は @param[in] name: の "name:" をパースできないためコロンを除去
let comment = strip_doxygen_param_colon(&comment);
let dox = doxygen_rs::transform(&comment)
.trim()
.replace('[', r"\[")
Expand All @@ -20,6 +22,64 @@ impl ParseCallbacks for Cb {
}
}

/// `@param[in] name: desc` や `@param[in]: desc` のコロンを除去する。
///
/// doxygen-rs はパラメータ名やディレクション指定の直後にコロンがある形式を
/// パースできないため、bindgen に渡す前にコロンを取り除く。
fn strip_doxygen_param_colon(comment: &str) -> String {
let mut result = String::with_capacity(comment.len());
for line in comment.lines() {
if !result.is_empty() {
result.push('\n');
}
// @param を含む行のみ処理
if let Some(param_pos) = line.find("@param") {
let after_param = &line[param_pos + "@param".len()..];
// @param[in]/[out]/[in,out] をスキップ
let rest = if after_param.starts_with('[') {
match after_param.find(']') {
Some(bracket_end) => &after_param[bracket_end + 1..],
None => {
result.push_str(line);
continue;
}
}
} else {
after_param
};
// ケース1: @param[in]: desc (パラメータ名なし、コロンが直後)
let rest_trimmed = rest.trim_start();
if rest_trimmed.starts_with(':') {
let colon_pos = param_pos
+ "@param".len()
+ (after_param.len() - rest.len())
+ (rest.len() - rest_trimmed.len());
result.push_str(&line[..colon_pos]);
result.push_str(&line[colon_pos + 1..]);
continue;
}
// ケース2: @param[in] name: desc (パラメータ名の末尾にコロン)
let name_end = rest_trimmed
.find(|c: char| !c.is_alphanumeric() && c != '_')
.unwrap_or(rest_trimmed.len());
if name_end > 0 && rest_trimmed.as_bytes().get(name_end) == Some(&b':') {
let colon_pos = param_pos
+ "@param".len()
+ (after_param.len() - rest.len())
+ (rest.len() - rest_trimmed.len())
+ name_end;
result.push_str(&line[..colon_pos]);
result.push_str(&line[colon_pos + 1..]);
} else {
result.push_str(line);
}
} else {
result.push_str(line);
}
}
result
}

pub fn bind_c2a_builder() -> bindgen::Builder {
bindgen::Builder::default()
.blocklist_type("max_align_t") // https://github.com/servo/rust-bindgen/issues/550
Expand Down
Loading