Skip to content

Commit

Permalink
Generate BindgenOptions and the Builder methods using macros (#2473)
Browse files Browse the repository at this point in the history
* Generate `BindgenOptions` and the `Builder` methods using macros

This is done so the definition, default value and `Builder` methods for
each field of `BindgenOptions` are kept in the same region of code.

Before this change, adding (or modifying) a new option for `bindgen`
required:
- Updating the fields of the `BindgenOptions` type.
- Updating the `Default` implementation for `BindgenOptions`.
- Updating one or several `Builder` methods with proper documentation
  explaining the default value of the option.
- Updating the `Builder::command_line_flags` method.

Each one of these steps was done in a different place inside
`bindgen/lib.rs`.

With this change, all these 4 steps are done in the same place. This
should make less likely to have bugs.

Clearly using macros implies properly documenting how to use such macros
and makes adding new options a bit harder because most (all?) editors
are not able to format code and suggest completions inside macros.

This change also moves all the code related to setting `BindgenOptions`
to the new `bindgen/options.rs` file.

* Factor out the "Regex are supported" docs.

All the options that support regular expressions had the following
sentence in their documentation:

> Regular expressions are supported

This comment was factored out to the macro that documents options based
on `RegexSet`s.

* Rename `fn_with_regex_arg` to `regex_option`

* Allow optional commas in the `options` macro.

This is done to avoid hard to detect macro parsing issues due to missing
commas.

* Fix typo

* Add the `AsArg` trait.

This trait eases the conversion of `BindgenOptions` fields into CLI
args.

This commit also changes the `options` macro so the flag can be passed
to `as_args` instead of a closure.

* Document the `option` macro

* Document the `options` module

* Rewrite some documentation

* Run rustfmt

* Avoid examples with `bool` parameters

* More documentation changes

* Reorganize the `options` module

* Run rustfmt
  • Loading branch information
pvdrz authored Apr 3, 2023
1 parent c94367c commit 040149b
Show file tree
Hide file tree
Showing 5 changed files with 2,441 additions and 2,279 deletions.
85 changes: 58 additions & 27 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use crate::{Entry, HashMap, HashSet};
use std::borrow::Cow;
use std::cell::Cell;
use std::collections::VecDeque;
use std::fmt::Write;
use std::fmt::{self, Write};
use std::ops;
use std::str::FromStr;

Expand All @@ -73,13 +73,13 @@ impl From<std::io::Error> for CodegenError {
}
}

impl std::fmt::Display for CodegenError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl fmt::Display for CodegenError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CodegenError::Serialize { msg, loc } => {
Self::Serialize { msg, loc } => {
write!(f, "serialization error at {}: {}", loc, msg)
}
CodegenError::Io(err) => err.fmt(f),
Self::Io(err) => err.fmt(f),
}
}
}
Expand Down Expand Up @@ -2736,6 +2736,35 @@ impl Default for EnumVariation {
}
}

impl fmt::Display for EnumVariation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::Rust {
non_exhaustive: false,
} => "rust",
Self::Rust {
non_exhaustive: true,
} => "rust_non_exhaustive",
Self::NewType {
is_bitfield: true, ..
} => "bitfield",
Self::NewType {
is_bitfield: false,
is_global,
} => {
if *is_global {
"newtype_global"
} else {
"newtype"
}
}
Self::Consts => "consts",
Self::ModuleConsts => "moduleconsts",
};
s.fmt(f)
}
}

impl std::str::FromStr for EnumVariation {
type Err = std::io::Error;

Expand Down Expand Up @@ -3422,13 +3451,13 @@ pub enum MacroTypeVariation {
Unsigned,
}

impl MacroTypeVariation {
/// Convert a `MacroTypeVariation` to its str representation.
pub(crate) fn as_str(&self) -> &str {
match self {
MacroTypeVariation::Signed => "signed",
MacroTypeVariation::Unsigned => "unsigned",
}
impl fmt::Display for MacroTypeVariation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::Signed => "signed",
Self::Unsigned => "unsigned",
};
s.fmt(f)
}
}

Expand Down Expand Up @@ -3468,14 +3497,15 @@ pub enum AliasVariation {
NewTypeDeref,
}

impl AliasVariation {
/// Convert an `AliasVariation` to its str representation.
pub(crate) fn as_str(&self) -> &str {
match self {
AliasVariation::TypeAlias => "type_alias",
AliasVariation::NewType => "new_type",
AliasVariation::NewTypeDeref => "new_type_deref",
}
impl fmt::Display for AliasVariation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::TypeAlias => "type_alias",
Self::NewType => "new_type",
Self::NewTypeDeref => "new_type_deref",
};

s.fmt(f)
}
}

Expand Down Expand Up @@ -3505,10 +3535,10 @@ impl std::str::FromStr for AliasVariation {
}
}

/// Enum for how non-Copy unions should be translated.
/// Enum for how non-`Copy` `union`s should be translated.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum NonCopyUnionStyle {
/// Wrap members in a type generated by bindgen.
/// Wrap members in a type generated by `bindgen`.
BindgenWrapper,
/// Wrap members in [`::core::mem::ManuallyDrop`].
///
Expand All @@ -3517,13 +3547,14 @@ pub enum NonCopyUnionStyle {
ManuallyDrop,
}

impl NonCopyUnionStyle {
/// Convert an `NonCopyUnionStyle` to its str representation.
pub(crate) fn as_str(&self) -> &'static str {
match self {
impl fmt::Display for NonCopyUnionStyle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::BindgenWrapper => "bindgen_wrapper",
Self::ManuallyDrop => "manually_drop",
}
};

s.fmt(f)
}
}

Expand Down
Loading

0 comments on commit 040149b

Please sign in to comment.