🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

cbindgen

Package Overview
Dependencies
Maintainers
1
Versions
106
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cbindgen - cargo Package Compare versions

Comparing version
0.27.0
to
0.28.0
tests/expectations-symbols/abi_string.c.sym

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

+14
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct NotReprC_i32 NotReprC_i32;
typedef struct NotReprC_i32 Foo;
typedef struct MyStruct {
int32_t number;
} MyStruct;
void root(const Foo *a, const struct MyStruct *with_cell);
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct NotReprC_i32 NotReprC_i32;
typedef struct NotReprC_i32 Foo;
typedef struct MyStruct {
int32_t number;
} MyStruct;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(const Foo *a, const struct MyStruct *with_cell);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct NotReprC_i32;
typedef struct NotReprC_i32 Foo;
struct MyStruct {
int32_t number;
};
void root(const Foo *a, const struct MyStruct *with_cell);
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct NotReprC_i32;
typedef struct NotReprC_i32 Foo;
struct MyStruct {
int32_t number;
};
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(const Foo *a, const struct MyStruct *with_cell);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list
cdef extern from *:
cdef struct NotReprC_i32:
pass
ctypedef NotReprC_i32 Foo;
cdef struct MyStruct:
int32_t number;
void root(const Foo *a, const MyStruct *with_cell);
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct NotReprC_i32 NotReprC_i32;
typedef NotReprC_i32 Foo;
typedef struct {
int32_t number;
} MyStruct;
void root(const Foo *a, const MyStruct *with_cell);
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct NotReprC_i32 NotReprC_i32;
typedef NotReprC_i32 Foo;
typedef struct {
int32_t number;
} MyStruct;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(const Foo *a, const MyStruct *with_cell);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
template<typename T = void>
struct NotReprC;
using Foo = NotReprC<int32_t>;
struct MyStruct {
int32_t number;
};
extern "C" {
void root(const Foo *a, const MyStruct *with_cell);
} // extern "C"
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list
cdef extern from *:
ctypedef struct NotReprC_i32:
pass
ctypedef NotReprC_i32 Foo;
ctypedef struct MyStruct:
int32_t number;
void root(const Foo *a, const MyStruct *with_cell);
#[repr(C)]
pub struct MyStruct {
number: std::cell::UnsafeCell<i32>,
}
pub struct NotReprC<T> { inner: T }
pub type Foo = NotReprC<std::cell::SyncUnsafeCell<i32>>;
#[no_mangle]
pub extern "C" fn root(a: &Foo, with_cell: &MyStruct) {}
+1
-1
{
"git": {
"sha1": "58c6156b0d91e82abb03c26187b8d18fa4345ce0"
"sha1": "bd78bbe59b10eda6ef1255e4acda95c56c6d0279"
},
"path_in_vcs": ""
}

@@ -17,3 +17,3 @@ name: cbindgen

runs-on: ubuntu-latest
runs-on: ubuntu-24.04

@@ -45,4 +45,12 @@ steps:

build:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
strategy:
matrix:
arch: [amd64, arm64]
include:
- arch: arm64
env:
CARGO_BUILD_TARGET: aarch64-unknown-linux-gnu
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc-11

@@ -52,4 +60,26 @@ steps:

- name: Setup environment variables for cross compiling
if: matrix.arch != 'amd64'
run: |
echo CARGO_BUILD_TARGET=${{matrix.env.CARGO_BUILD_TARGET}} >> ${GITHUB_ENV}
echo CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=${{matrix.env.CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER}} >> ${GITHUB_ENV}
- name: Install cross linker and emulator
if: matrix.arch == 'arm64'
run: |
# Only works on noble (and later?)
sudo sed -i '/^Components/a Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources
echo "deb [arch=arm64] http://ports.ubuntu.com/ $(lsb_release -sc) main multiverse universe" | sudo tee -a /etc/apt/sources.list.d/ports.list
echo "deb [arch=arm64] http://ports.ubuntu.com/ $(lsb_release -sc)-security main multiverse universe" | sudo tee -a /etc/apt/sources.list.d/ports.list
echo "deb [arch=arm64] http://ports.ubuntu.com/ $(lsb_release -sc)-backports main multiverse universe" | sudo tee -a /etc/apt/sources.list.d/ports.list
echo "deb [arch=arm64] http://ports.ubuntu.com/ $(lsb_release -sc)-updates main multiverse universe" | sudo tee -a /etc/apt/sources.list.d/ports.list
sudo dpkg --add-architecture arm64
sudo apt-get update
sudo apt-get install -y qemu-user gcc-11-aarch64-linux-gnu libc6:arm64
- name: Install stable Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{matrix.env.CARGO_BUILD_TARGET}}

@@ -83,2 +113,4 @@ - name: Install Python

uses: dtolnay/rust-toolchain@nightly
with:
targets: ${{matrix.env.CARGO_BUILD_TARGET}}

@@ -85,0 +117,0 @@ - name: Test

@@ -68,3 +68,3 @@ # This file is automatically @generated by Cargo.

name = "cbindgen"
version = "0.27.0"
version = "0.28.0"
dependencies = [

@@ -409,5 +409,5 @@ "clap",

name = "syn"
version = "2.0.72"
version = "2.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
dependencies = [

@@ -414,0 +414,0 @@ "proc-macro2",

@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "cbindgen"
version = "0.27.0"
version = "0.28.0"
authors = [

@@ -26,2 +26,3 @@ "Emilio Cobos Álvarez <emilio@crisal.io>",

exclude = ["tests/profile.rs"]
autolib = false
autobins = false

@@ -45,2 +46,6 @@ autoexamples = false

[features]
default = ["clap"]
unstable_ir = []
[lib]

@@ -92,3 +97,3 @@ name = "cbindgen"

[dependencies.syn]
version = "2.0.64"
version = "2.0.85"
features = [

@@ -116,4 +121,1 @@ "clone-impls",

default-features = false
[features]
default = ["clap"]
+14
-0
# unreleased
# 0.28.0
* Parse unsafe attributes in https://github.com/mozilla/cbindgen/pull/1020
* Fix local override of enum prefix-with-name by jsgf in https://github.com/mozilla/cbindgen/pull/1006
* Add rename-all=prefix in https://github.com/mozilla/cbindgen/pull/1021
* ir: add support for UnsafeCell and SyncUnsafeCell by alekitto in https://github.com/mozilla/cbindgen/pull/1003
* Implement mangling for arrays in https://github.com/mozilla/cbindgen/pull/1022
* Fix: Ignore `CARGO_BUILD_TARGET` in tests by bryango in https://github.com/mozilla/cbindgen/pull/1010
* Newline for each field for constexpr field constants by youknowone in https://github.com/mozilla/cbindgen/pull/988
* Fix clippy warnings by youknowone in https://github.com/mozilla/cbindgen/pull/1026
* Add aarch64/arm64 to CI by NickeZ in https://github.com/mozilla/cbindgen/pull/1036
* Add `unstable_ir` feature flag that makes the ir pub by heesooy in https://github.com/mozilla/cbindgen/pull/1011
* Support generated a symbols file by TheElectronWill in https://github.com/mozilla/cbindgen/pull/916
# 0.27.0

@@ -4,0 +18,0 @@

@@ -97,6 +97,15 @@ # cbindgen User Guide

## Internal Representation
Some users may find it useful to access the **unstable** internal representation (IR) that cbindgen uses to parse and generate code. By default, the IR is private, but you can access it by enabling the `"unstable_ir"` feature flag like so:
```
[build-dependencies]
cbindgen = { version = "0.27.0", features = ["unstable_ir"] }
```
This opens up the `cbindgen::bindgen::ir` module.
Please remember that the IR is **not stable**, so if you use this feature, you will need to pin cbindgen to avoid breakages.
# Writing Your C API

@@ -103,0 +112,0 @@

@@ -10,3 +10,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

use std::fs::File;
use std::io::{Read, Write};
use std::io::{BufWriter, Read, Write};
use std::path;

@@ -133,2 +133,23 @@ use std::rc::Rc;

/// Lists the exported symbols that can be dynamically linked, i.e. globals and functions.
pub fn dynamic_symbols_names(&self) -> impl Iterator<Item = &str> {
use crate::bindgen::ir::Item;
let function_names = self.functions.iter().map(|f| f.path().name());
let global_names = self.globals.iter().map(|g| g.export_name());
function_names.chain(global_names)
}
pub fn generate_symfile<P: AsRef<path::Path>>(&self, symfile_path: P) {
if let Some(dir) = symfile_path.as_ref().parent() {
std::fs::create_dir_all(dir).unwrap();
}
let mut writer = BufWriter::new(File::create(symfile_path).unwrap());
writeln!(&mut writer, "{{").expect("writing symbol file header failed");
for symbol in self.dynamic_symbols_names() {
writeln!(&mut writer, "{};", symbol).expect("writing symbol failed");
}
write!(&mut writer, "}};").expect("writing symbol file footer failed");
}
pub fn generate_depfile<P: AsRef<path::Path>>(&self, header_path: P, depfile_path: P) {

@@ -135,0 +156,0 @@ if let Some(dir) = depfile_path.as_ref().parent() {

@@ -140,3 +140,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

impl<'a> FlagValueFold<'a> {
impl FlagValueFold<'_> {
fn is_self(&self, ident: &syn::Ident) -> bool {

@@ -147,3 +147,3 @@ ident == self.struct_name || ident == "Self"

impl<'a> Fold for FlagValueFold<'a> {
impl Fold for FlagValueFold<'_> {
fn fold_expr(&mut self, node: syn::Expr) -> syn::Expr {

@@ -150,0 +150,0 @@ // bitflags 2 doesn't expose `bits` publically anymore, and the documented way to

@@ -239,4 +239,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

while let Some(declarator) = iter_rev.next() {
let next_is_pointer = iter_rev.peek().map_or(false, |x| x.is_ptr());
let next_is_pointer = iter_rev.peek().is_some_and(|x| x.is_ptr());
match *declarator {

@@ -243,0 +242,0 @@ CDeclarator::Ptr {

@@ -18,3 +18,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

impl<'a> DefineKey<'a> {
impl DefineKey<'_> {
fn load(key: &str) -> DefineKey {

@@ -21,0 +21,0 @@ // TODO: dirty parser

@@ -187,3 +187,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

fn can_be_constexpr(&self) -> bool {
pub(crate) fn can_be_constexpr(&self) -> bool {
!self.has_pointer_casts()

@@ -649,3 +649,3 @@ }

let associated_to_transparent = associated_to_struct.map_or(false, |s| s.is_transparent);
let associated_to_transparent = associated_to_struct.is_some_and(|s| s.is_transparent);

@@ -652,0 +652,0 @@ let in_body = associated_to_struct.is_some()

@@ -155,5 +155,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

let body_rule = enum_annotations
.parse_atom::<RenameRule>("rename-variant-name-fields")
.unwrap_or(config.enumeration.rename_variant_name_fields);
let body_rule = enum_annotations.parse_atom::<RenameRule>("rename-variant-name-fields");
let body_rule = body_rule
.as_ref()
.unwrap_or(&config.enumeration.rename_variant_name_fields);

@@ -538,4 +539,6 @@ let body = match variant.fields {

if config.enumeration.prefix_with_name
|| self.annotations.bool("prefix-with-name").unwrap_or(false)
if self
.annotations
.bool("prefix-with-name")
.unwrap_or(config.enumeration.prefix_with_name)
{

@@ -558,6 +561,6 @@ let separator = if config.export.mangle.remove_underscores {

let rules = self
.annotations
.parse_atom::<RenameRule>("rename-all")
.unwrap_or(config.enumeration.rename_variants);
let rules = self.annotations.parse_atom::<RenameRule>("rename-all");
let rules = rules
.as_ref()
.unwrap_or(&config.enumeration.rename_variants);

@@ -564,0 +567,0 @@ if let Some(r) = rules.not_none() {

@@ -159,6 +159,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

// Apply rename rules to argument names
let rules = self
.annotations
.parse_atom::<RenameRule>("rename-all")
.unwrap_or(config.function.rename_args);
let rules = self.annotations.parse_atom::<RenameRule>("rename-all");
let rules = rules.as_ref().unwrap_or(&config.function.rename_args);

@@ -165,0 +163,0 @@ if let Some(r) = rules.not_none() {

@@ -14,3 +14,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

AnnotationSet, Cfg, Constant, Documentation, Field, GenericArgument, GenericParams, Item,
ItemContainer, Path, Repr, ReprAlign, ReprStyle, Type,
ItemContainer, Path, Repr, ReprAlign, ReprStyle, Type, Typedef,
};

@@ -126,3 +126,3 @@ use crate::bindgen::library::Library;

alignment: Option<ReprAlign>,
is_transparent: bool,
mut is_transparent: bool,
cfg: Option<Cfg>,

@@ -132,2 +132,18 @@ annotations: AnnotationSet,

) -> Self {
// WARNING: Zero-sized transparent structs are legal rust [1], but zero-sized types of any
// repr are "best avoided entirely" [2] because they "will be nonsensical or problematic if
// passed through the FFI boundary" [3]. Further, because no well-defined underlying native
// type exists for a ZST, we cannot emit a typedef and must define an empty struct instead.
//
// [1] https://github.com/rust-lang/rust/issues/77841#issuecomment-716575747
// [2] https://github.com/rust-lang/rust/issues/77841#issuecomment-716796313
// [3] https://doc.rust-lang.org/nomicon/other-reprs.html
if fields.is_empty() {
warn!(
"Passing zero-sized struct {} across the FFI boundary is undefined behavior",
&path
);
is_transparent = false;
}
let export_name = path.name().to_owned();

@@ -156,2 +172,10 @@ Self {

/// Attempts to convert this struct to a typedef (only works for transparent structs).
pub fn as_typedef(&self) -> Option<Typedef> {
match self.fields.first() {
Some(field) if self.is_transparent => Some(Typedef::new_from_struct_field(self, field)),
_ => None,
}
}
pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) {

@@ -322,6 +346,6 @@ // Generic structs can instantiate monomorphs only once they've been

let field_rules = self
.annotations
.parse_atom::<RenameRule>("rename-all")
.unwrap_or(config.structure.rename_fields);
let field_rules = self.annotations.parse_atom::<RenameRule>("rename-all");
let field_rules = field_rules
.as_ref()
.unwrap_or(&config.structure.rename_fields);

@@ -328,0 +352,0 @@ if let Some(o) = self.annotations.list("field-names") {

@@ -562,3 +562,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

}),
"Cell" => Some(generic.into_owned()),
"SyncUnsafeCell" | "UnsafeCell" | "Cell" => Some(generic.into_owned()),
"ManuallyDrop" | "MaybeUninit" | "Pin" if config.language != Language::Cxx => {

@@ -565,0 +565,0 @@ Some(generic.into_owned())

@@ -13,4 +13,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

use crate::bindgen::ir::{
AnnotationSet, Cfg, Documentation, GenericArgument, GenericParams, Item, ItemContainer, Path,
Type,
AnnotationSet, Cfg, Documentation, Field, GenericArgument, GenericParams, Item, ItemContainer,
Path, Struct, Type,
};

@@ -74,2 +74,15 @@ use crate::bindgen::library::Library;

// Used to convert a transparent Struct to a Typedef.
pub fn new_from_struct_field(item: &Struct, field: &Field) -> Self {
Self {
path: item.path().clone(),
export_name: item.export_name().to_string(),
generic_params: item.generic_params.clone(),
aliased: field.ty.clone(),
cfg: item.cfg().cloned(),
annotations: item.annotations().clone(),
documentation: item.documentation().clone(),
}
}
pub fn transfer_annotations(&mut self, out: &mut HashMap<Path, AnnotationSet>) {

@@ -76,0 +89,0 @@ if self.annotations.is_empty() {

@@ -171,6 +171,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

let rules = self
.annotations
.parse_atom::<RenameRule>("rename-all")
.unwrap_or(config.structure.rename_fields);
let rules = self.annotations.parse_atom::<RenameRule>("rename-all");
let rules = rules.as_ref().unwrap_or(&config.structure.rename_fields);

@@ -177,0 +175,0 @@ if let Some(o) = self.annotations.list("field-names") {

@@ -543,20 +543,2 @@ use crate::bindgen::ir::{

fn write_struct<W: Write>(&mut self, out: &mut SourceWriter<W>, s: &Struct) {
if s.is_transparent {
let typedef = Typedef {
path: s.path.clone(),
export_name: s.export_name.to_owned(),
generic_params: s.generic_params.clone(),
aliased: s.fields[0].ty.clone(),
cfg: s.cfg.clone(),
annotations: s.annotations.clone(),
documentation: s.documentation.clone(),
};
self.write_type_def(out, &typedef);
for constant in &s.associated_constants {
out.new_line();
constant.write(self.config, self, out, Some(s));
}
return;
}
let condition = s.cfg.to_condition(self.config);

@@ -915,2 +897,5 @@ condition.write_before(self.config, out);

} => {
let allow_constexpr = self.config.constant.allow_constexpr && l.can_be_constexpr();
let is_constexpr = self.config.language == Language::Cxx
&& (self.config.constant.allow_static_const || allow_constexpr);
if self.config.language == Language::C {

@@ -922,23 +907,48 @@ write!(out, "({})", export_name);

write!(out, "{{ ");
let mut is_first_field = true;
write!(out, "{{");
if is_constexpr {
out.push_tab();
} else {
write!(out, " ");
}
// In C++, same order as defined is required.
let ordered_fields = out.bindings().struct_field_names(path);
for ordered_key in ordered_fields.iter() {
for (i, ordered_key) in ordered_fields.iter().enumerate() {
if let Some(lit) = fields.get(ordered_key) {
if !is_first_field {
write!(out, ", ");
}
is_first_field = false;
if self.config.language == Language::Cxx {
if is_constexpr {
out.new_line();
// TODO: Some C++ versions (c++20?) now support designated
// initializers, consider generating them.
write!(out, "/* .{} = */ ", ordered_key);
self.write_literal(out, lit);
if i + 1 != ordered_fields.len() {
write!(out, ",");
if !is_constexpr {
write!(out, " ");
}
}
} else {
write!(out, ".{} = ", ordered_key);
if i > 0 {
write!(out, ", ");
}
if self.config.language == Language::Cxx {
// TODO: Some C++ versions (c++20?) now support designated
// initializers, consider generating them.
write!(out, "/* .{} = */ ", ordered_key);
} else {
write!(out, ".{} = ", ordered_key);
}
self.write_literal(out, lit);
}
self.write_literal(out, lit);
}
}
write!(out, " }}");
if is_constexpr {
out.pop_tab();
out.new_line();
} else {
write!(out, " ");
}
write!(out, "}}");
}

@@ -945,0 +955,0 @@ }

@@ -162,20 +162,2 @@ use crate::bindgen::ir::{

fn write_struct<W: Write>(&mut self, out: &mut SourceWriter<W>, s: &Struct) {
if s.is_transparent {
let typedef = Typedef {
path: s.path.clone(),
export_name: s.export_name.to_owned(),
generic_params: s.generic_params.clone(),
aliased: s.fields[0].ty.clone(),
cfg: s.cfg.clone(),
annotations: s.annotations.clone(),
documentation: s.documentation.clone(),
};
self.write_type_def(out, &typedef);
for constant in &s.associated_constants {
out.new_line();
constant.write(self.config, self, out, Some(s));
}
return;
}
let condition = s.cfg.to_condition(self.config);

@@ -182,0 +164,0 @@ condition.write_before(self.config, out);

@@ -142,2 +142,20 @@ use crate::bindgen::ir::{

/// If the struct is transparent, emit a typedef of its NZST field type instead.
fn write_struct_or_typedef<W: Write>(
&mut self,
out: &mut SourceWriter<W>,
s: &Struct,
b: &Bindings,
) {
if let Some(typedef) = s.as_typedef() {
self.write_type_def(out, &typedef);
for constant in &s.associated_constants {
out.new_line();
constant.write(&b.config, self, out, Some(s));
}
} else {
self.write_struct(out, s);
}
}
fn write_items<W: Write>(&mut self, out: &mut SourceWriter<W>, b: &Bindings) {

@@ -159,3 +177,3 @@ for item in &b.items {

ItemContainer::Enum(ref x) => self.write_enum(out, x),
ItemContainer::Struct(ref x) => self.write_struct(out, x),
ItemContainer::Struct(ref x) => self.write_struct_or_typedef(out, x, b),
ItemContainer::Union(ref x) => self.write_union(out, x),

@@ -162,0 +180,0 @@ ItemContainer::OpaqueItem(ref x) => self.write_opaque_item(out, x),

@@ -30,2 +30,4 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

EndFn,
BeginArray,
BetweenArray,
}

@@ -132,8 +134,7 @@

}
Type::Array(..) => {
unimplemented!(
"Unable to mangle generic parameter {:?} for '{}'",
ty,
self.input
);
Type::Array(ref ty, ref len) => {
self.push(Separator::BeginArray);
self.append_mangled_type(ty, false);
self.push(Separator::BetweenArray);
self.append_mangled_argument(&GenericArgument::Const(len.clone()), last);
}

@@ -140,0 +141,0 @@ }

@@ -48,2 +48,5 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

mod error;
#[cfg(feature = "unstable_ir")]
pub mod ir;
#[cfg(not(feature = "unstable_ir"))]
mod ir;

@@ -50,0 +53,0 @@ mod language_backend;

@@ -109,3 +109,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

impl<'a> Parser<'a> {
impl Parser<'_> {
fn should_parse_dependency(&self, pkg_name: &str) -> bool {

@@ -112,0 +112,0 @@ if self.parsed_crates.contains(pkg_name) {

@@ -18,3 +18,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

impl<'a> IdentifierType<'a> {
impl IdentifierType<'_> {
fn to_str(self) -> &'static str {

@@ -32,3 +32,3 @@ match self {

/// A rule to apply to an identifier when generating bindings.
#[derive(Debug, Clone, Copy, Default)]
#[derive(Debug, Clone, Default)]
pub enum RenameRule {

@@ -55,6 +55,8 @@ /// Do not apply any renaming. The default.

QualifiedScreamingSnakeCase,
/// Adds a given prefix
Prefix(String),
}
impl RenameRule {
pub(crate) fn not_none(self) -> Option<Self> {
pub(crate) fn not_none(&self) -> Option<&Self> {
match self {

@@ -67,3 +69,3 @@ RenameRule::None => None,

/// Applies the rename rule to a string
pub fn apply<'a>(self, text: &'a str, context: IdentifierType) -> Cow<'a, str> {
pub fn apply<'a>(&self, text: &'a str, context: IdentifierType) -> Cow<'a, str> {
use heck::*;

@@ -97,2 +99,3 @@

}
RenameRule::Prefix(prefix) => prefix.to_owned() + text,
})

@@ -106,2 +109,5 @@ }

fn from_str(s: &str) -> Result<RenameRule, Self::Err> {
const PREFIX: &str = "prefix:";
const PREFIX_LEN: usize = PREFIX.len();
match s {

@@ -141,2 +147,4 @@ "none" => Ok(RenameRule::None),

s if s.starts_with(PREFIX) => Ok(RenameRule::Prefix(s[PREFIX_LEN..].to_string())),
_ => Err(format!("Unrecognized RenameRule: '{}'.", s)),

@@ -143,0 +151,0 @@ }

@@ -41,8 +41,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

.attr_name_value_lookup("export_name")
.or_else(|| self.unsafe_attr_name_value_lookup("export_name"))
.or_else(|| {
if self.is_no_mangle() {
Some(self.sig.ident.unraw().to_string())
} else {
None
}
self.is_no_mangle()
.then(|| self.sig.ident.unraw().to_string())
})

@@ -154,2 +152,26 @@ }

/// Searches for attributes like `#[unsafe(test)]`.
/// Example:
/// - `item.has_unsafe_attr_word("test")` => `#[unsafe(test)]`
fn has_unsafe_attr_word(&self, name: &str) -> bool {
for attr in self.attrs() {
let unsafe_list = match &attr.meta {
syn::Meta::List(list) if list.path.is_ident("unsafe") => list,
_ => continue,
};
let args: syn::punctuated::Punctuated<syn::Path, Token![,]> =
match unsafe_list.parse_args_with(syn::punctuated::Punctuated::parse_terminated) {
Ok(args) => args,
Err(..) => {
warn!("couldn't parse unsafe() attribute");
continue;
}
};
if args.iter().any(|a| a.is_ident(name)) {
return true;
}
}
false
}
fn find_deprecated_note(&self) -> Option<String> {

@@ -176,10 +198,11 @@ let attrs = self.attrs();

let args: syn::punctuated::Punctuated<syn::MetaNameValue, Token![,]> =
match attr.parse_args_with(syn::punctuated::Punctuated::parse_terminated) {
Ok(args) => args,
Err(_) => {
warn!("couldn't parse deprecated attribute");
return None;
}
};
let parser =
syn::punctuated::Punctuated::<syn::MetaNameValue, syn::Token![,]>::parse_terminated;
let args = match attr.parse_args_with(parser) {
Ok(args) => args,
Err(_) => {
warn!("couldn't parse deprecated attribute");
return None;
}
};

@@ -200,3 +223,3 @@ let arg = args.iter().find(|arg| arg.path.is_ident("note"))?;

fn is_no_mangle(&self) -> bool {
self.has_attr_word("no_mangle")
self.has_attr_word("no_mangle") || self.has_unsafe_attr_word("no_mangle")
}

@@ -238,2 +261,28 @@

fn unsafe_attr_name_value_lookup(&self, name: &str) -> Option<String> {
self.attrs()
.iter()
.filter_map(|attr| {
let syn::Meta::List(list) = &attr.meta else { return None };
if !list.path.is_ident("unsafe") {
return None;
}
let parser = syn::punctuated::Punctuated::<syn::MetaNameValue, syn::Token![,]>::parse_terminated;
let Ok(args) = list.parse_args_with(parser) else { return None };
for arg in args {
if !arg.path.is_ident(name) {
continue;
}
if let syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Str(lit),
..
}) = arg.value {
return Some(lit.value());
}
}
None
})
.next()
}
fn get_comment_lines(&self) -> Vec<String> {

@@ -240,0 +289,0 @@ let mut comment = Vec::new();

@@ -24,3 +24,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

impl<'a, 'b, F: Write> Write for InnerWriter<'a, 'b, F> {
impl<F: Write> Write for InnerWriter<'_, '_, F> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {

@@ -27,0 +27,0 @@ let writer = &mut self.0;

@@ -17,2 +17,5 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

#[cfg(feature = "unstable_ir")]
pub mod bindgen;
#[cfg(not(feature = "unstable_ir"))]
mod bindgen;

@@ -19,0 +22,0 @@

@@ -301,2 +301,13 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

)
.arg(
Arg::new("symfile")
.value_name("PATH")
.long("symfile")
.num_args(1)
.required(false)
.help("Generate a list of symbols at the given Path. This list can be \
given to a linker in order to compile an application that exposes \
dynamic symbols. Useful when creating a plugin system with a C interface."
)
)
.get_matches();

@@ -347,4 +358,7 @@

if let Some(depfile) = matches.get_one("depfile") {
bindings.generate_depfile(file, depfile)
bindings.generate_depfile(file, depfile);
}
if let Some(symfile) = matches.get_one::<String>("symfile") {
bindings.generate_symfile(symfile);
}
}

@@ -351,0 +365,0 @@ _ => {

@@ -50,14 +50,30 @@ #include <cstdarg>

/// 'auto'
constexpr inline const StyleAlignFlags StyleAlignFlags::AUTO = StyleAlignFlags{ /* .bits = */ (uint8_t)0 };
constexpr inline const StyleAlignFlags StyleAlignFlags::AUTO = StyleAlignFlags{
/* .bits = */ (uint8_t)0
};
/// 'normal'
constexpr inline const StyleAlignFlags StyleAlignFlags::NORMAL = StyleAlignFlags{ /* .bits = */ (uint8_t)1 };
constexpr inline const StyleAlignFlags StyleAlignFlags::NORMAL = StyleAlignFlags{
/* .bits = */ (uint8_t)1
};
/// 'start'
constexpr inline const StyleAlignFlags StyleAlignFlags::START = StyleAlignFlags{ /* .bits = */ (uint8_t)(1 << 1) };
constexpr inline const StyleAlignFlags StyleAlignFlags::START = StyleAlignFlags{
/* .bits = */ (uint8_t)(1 << 1)
};
/// 'end'
constexpr inline const StyleAlignFlags StyleAlignFlags::END = StyleAlignFlags{ /* .bits = */ (uint8_t)(1 << 2) };
constexpr inline const StyleAlignFlags StyleAlignFlags::ALIAS = StyleAlignFlags{ /* .bits = */ (uint8_t)(StyleAlignFlags::END).bits };
constexpr inline const StyleAlignFlags StyleAlignFlags::END = StyleAlignFlags{
/* .bits = */ (uint8_t)(1 << 2)
};
constexpr inline const StyleAlignFlags StyleAlignFlags::ALIAS = StyleAlignFlags{
/* .bits = */ (uint8_t)(StyleAlignFlags::END).bits
};
/// 'flex-start'
constexpr inline const StyleAlignFlags StyleAlignFlags::FLEX_START = StyleAlignFlags{ /* .bits = */ (uint8_t)(1 << 3) };
constexpr inline const StyleAlignFlags StyleAlignFlags::MIXED = StyleAlignFlags{ /* .bits = */ (uint8_t)(((1 << 4) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits) };
constexpr inline const StyleAlignFlags StyleAlignFlags::MIXED_SELF = StyleAlignFlags{ /* .bits = */ (uint8_t)(((1 << 5) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits) };
constexpr inline const StyleAlignFlags StyleAlignFlags::FLEX_START = StyleAlignFlags{
/* .bits = */ (uint8_t)(1 << 3)
};
constexpr inline const StyleAlignFlags StyleAlignFlags::MIXED = StyleAlignFlags{
/* .bits = */ (uint8_t)(((1 << 4) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits)
};
constexpr inline const StyleAlignFlags StyleAlignFlags::MIXED_SELF = StyleAlignFlags{
/* .bits = */ (uint8_t)(((1 << 5) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits)
};

@@ -70,3 +86,5 @@ /// An arbitrary identifier for a native (OS compositor) surface

/// A special id for the native surface that is used for debug / profiler overlays.
constexpr inline const StyleNativeSurfaceId StyleNativeSurfaceId::DEBUG_OVERLAY = StyleNativeSurfaceId{ /* ._0 = */ UINT64_MAX };
constexpr inline const StyleNativeSurfaceId StyleNativeSurfaceId::DEBUG_OVERLAY = StyleNativeSurfaceId{
/* ._0 = */ UINT64_MAX
};

@@ -80,3 +98,7 @@ struct StyleNativeTileId {

/// A special id for the native surface that is used for debug / profiler overlays.
constexpr inline const StyleNativeTileId StyleNativeTileId::DEBUG_OVERLAY = StyleNativeTileId{ /* .surface_id = */ StyleNativeSurfaceId::DEBUG_OVERLAY, /* .x = */ 0, /* .y = */ 0 };
constexpr inline const StyleNativeTileId StyleNativeTileId::DEBUG_OVERLAY = StyleNativeTileId{
/* .surface_id = */ StyleNativeSurfaceId::DEBUG_OVERLAY,
/* .x = */ 0,
/* .y = */ 0
};

@@ -83,0 +105,0 @@ extern "C" {

@@ -42,14 +42,30 @@ #include <cstdarg>

/// 'auto'
constexpr static const AlignFlags AlignFlags_AUTO = AlignFlags{ /* .bits = */ (uint8_t)0 };
constexpr static const AlignFlags AlignFlags_AUTO = AlignFlags{
/* .bits = */ (uint8_t)0
};
/// 'normal'
constexpr static const AlignFlags AlignFlags_NORMAL = AlignFlags{ /* .bits = */ (uint8_t)1 };
constexpr static const AlignFlags AlignFlags_NORMAL = AlignFlags{
/* .bits = */ (uint8_t)1
};
/// 'start'
constexpr static const AlignFlags AlignFlags_START = AlignFlags{ /* .bits = */ (uint8_t)(1 << 1) };
constexpr static const AlignFlags AlignFlags_START = AlignFlags{
/* .bits = */ (uint8_t)(1 << 1)
};
/// 'end'
constexpr static const AlignFlags AlignFlags_END = AlignFlags{ /* .bits = */ (uint8_t)(1 << 2) };
constexpr static const AlignFlags AlignFlags_ALIAS = AlignFlags{ /* .bits = */ (uint8_t)(AlignFlags_END).bits };
constexpr static const AlignFlags AlignFlags_END = AlignFlags{
/* .bits = */ (uint8_t)(1 << 2)
};
constexpr static const AlignFlags AlignFlags_ALIAS = AlignFlags{
/* .bits = */ (uint8_t)(AlignFlags_END).bits
};
/// 'flex-start'
constexpr static const AlignFlags AlignFlags_FLEX_START = AlignFlags{ /* .bits = */ (uint8_t)(1 << 3) };
constexpr static const AlignFlags AlignFlags_MIXED = AlignFlags{ /* .bits = */ (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) };
constexpr static const AlignFlags AlignFlags_MIXED_SELF = AlignFlags{ /* .bits = */ (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) };
constexpr static const AlignFlags AlignFlags_FLEX_START = AlignFlags{
/* .bits = */ (uint8_t)(1 << 3)
};
constexpr static const AlignFlags AlignFlags_MIXED = AlignFlags{
/* .bits = */ (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits)
};
constexpr static const AlignFlags AlignFlags_MIXED_SELF = AlignFlags{
/* .bits = */ (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits)
};

@@ -88,3 +104,5 @@ struct DebugFlags {

/// Flag with the topmost bit set of the u32
constexpr static const DebugFlags DebugFlags_BIGGEST_ALLOWED = DebugFlags{ /* .bits = */ (uint32_t)(1 << 31) };
constexpr static const DebugFlags DebugFlags_BIGGEST_ALLOWED = DebugFlags{
/* .bits = */ (uint32_t)(1 << 31)
};

@@ -123,4 +141,8 @@ struct LargeFlags {

/// Flag with a very large shift that usually would be narrowed.
constexpr static const LargeFlags LargeFlags_LARGE_SHIFT = LargeFlags{ /* .bits = */ (uint64_t)(1ull << 44) };
constexpr static const LargeFlags LargeFlags_INVERTED = LargeFlags{ /* .bits = */ (uint64_t)~(LargeFlags_LARGE_SHIFT).bits };
constexpr static const LargeFlags LargeFlags_LARGE_SHIFT = LargeFlags{
/* .bits = */ (uint64_t)(1ull << 44)
};
constexpr static const LargeFlags LargeFlags_INVERTED = LargeFlags{
/* .bits = */ (uint64_t)~(LargeFlags_LARGE_SHIFT).bits
};

@@ -158,5 +180,11 @@ struct OutOfLine {

};
constexpr static const OutOfLine OutOfLine_A = OutOfLine{ /* ._0 = */ (uint32_t)1 };
constexpr static const OutOfLine OutOfLine_B = OutOfLine{ /* ._0 = */ (uint32_t)2 };
constexpr static const OutOfLine OutOfLine_AB = OutOfLine{ /* ._0 = */ (uint32_t)((OutOfLine_A)._0 | (OutOfLine_B)._0) };
constexpr static const OutOfLine OutOfLine_A = OutOfLine{
/* ._0 = */ (uint32_t)1
};
constexpr static const OutOfLine OutOfLine_B = OutOfLine{
/* ._0 = */ (uint32_t)2
};
constexpr static const OutOfLine OutOfLine_AB = OutOfLine{
/* ._0 = */ (uint32_t)((OutOfLine_A)._0 | (OutOfLine_B)._0)
};

@@ -163,0 +191,0 @@ extern "C" {

@@ -19,3 +19,7 @@ #include <cstdarg>

};
constexpr static const FontWeight FontWeight_NORMAL = FontWeight{ /* ._0 = */ FontWeightFixedPoint{ /* .value = */ (400 << FONT_WEIGHT_FRACTION_BITS) } };
constexpr static const FontWeight FontWeight_NORMAL = FontWeight{
/* ._0 = */ FontWeightFixedPoint{
/* .value = */ (400 << FONT_WEIGHT_FRACTION_BITS)
}
};

@@ -22,0 +26,0 @@ extern "C" {

@@ -21,2 +21,4 @@ #include <cstdarg>

static const Foo SomeFoo = Foo{ /* .x = */ 99 };
static const Foo SomeFoo = Foo{
/* .x = */ 99
};

@@ -17,3 +17,5 @@ #include <cstdarg>

constexpr static const S C1 = S{ /* .field = */ 0 };
constexpr static const S C1 = S{
/* .field = */ 0
};

@@ -20,0 +22,0 @@ constexpr static const E C2 = V;

@@ -7,1 +7,3 @@ #include <stdarg.h>

void do_the_thing_with_export_name(void);
void do_the_thing_with_unsafe_export_name(void);

@@ -12,4 +12,6 @@ #include <stdarg.h>

void do_the_thing_with_unsafe_export_name(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -11,2 +11,4 @@ #include <cstdarg>

void do_the_thing_with_unsafe_export_name();
} // extern "C"

@@ -10,1 +10,3 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

void do_the_thing_with_export_name();
void do_the_thing_with_unsafe_export_name();

@@ -12,2 +12,8 @@ #include <stdarg.h>

typedef struct Foo__________u8__________4 {
uint8_t a[4];
} Foo__________u8__________4;
void root(Boo x);
void my_function(struct Foo__________u8__________4 x);

@@ -12,2 +12,6 @@ #include <stdarg.h>

typedef struct Foo__________u8__________4 {
uint8_t a[4];
} Foo__________u8__________4;
#ifdef __cplusplus

@@ -19,4 +23,6 @@ extern "C" {

void my_function(struct Foo__________u8__________4 x);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -12,2 +12,8 @@ #include <stdarg.h>

struct Foo__________u8__________4 {
uint8_t a[4];
};
void root(Boo x);
void my_function(struct Foo__________u8__________4 x);

@@ -12,2 +12,6 @@ #include <stdarg.h>

struct Foo__________u8__________4 {
uint8_t a[4];
};
#ifdef __cplusplus

@@ -19,4 +23,6 @@ extern "C" {

void my_function(struct Foo__________u8__________4 x);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -14,2 +14,7 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

cdef struct Foo__________u8__________4:
uint8_t a[4];
void root(Boo x);
void my_function(Foo__________u8__________4 x);

@@ -12,2 +12,8 @@ #include <stdarg.h>

typedef struct {
uint8_t a[4];
} Foo__________u8__________4;
void root(Boo x);
void my_function(Foo__________u8__________4 x);

@@ -12,2 +12,6 @@ #include <stdarg.h>

typedef struct {
uint8_t a[4];
} Foo__________u8__________4;
#ifdef __cplusplus

@@ -19,4 +23,6 @@ extern "C" {

void my_function(Foo__________u8__________4 x);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -18,2 +18,4 @@ #include <cstdarg>

void my_function(Foo<uint8_t[4]> x);
} // extern "C"

@@ -14,2 +14,7 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

ctypedef struct Foo__________u8__________4:
uint8_t a[4];
void root(Boo x);
void my_function(Foo__________u8__________4 x);

@@ -18,1 +18,3 @@ #include <stdarg.h>

void root(Boo x, enum Bar y);
void unsafe_root(Boo x, enum Bar y);

@@ -23,4 +23,6 @@ #include <stdarg.h>

void unsafe_root(Boo x, enum Bar y);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -18,1 +18,3 @@ #include <stdarg.h>

void root(Boo x, enum Bar y);
void unsafe_root(Boo x, enum Bar y);

@@ -23,4 +23,6 @@ #include <stdarg.h>

void unsafe_root(Boo x, enum Bar y);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -19,1 +19,3 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

void root(Boo x, Bar y);
void unsafe_root(Boo x, Bar y);

@@ -18,1 +18,3 @@ #include <stdarg.h>

void root(Boo x, Bar y);
void unsafe_root(Boo x, Bar y);

@@ -23,4 +23,6 @@ #include <stdarg.h>

void unsafe_root(Boo x, Bar y);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -23,2 +23,4 @@ #include <cstdarg>

void unsafe_root(Boo x, Bar y);
} // extern "C"

@@ -19,1 +19,3 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

void root(Boo x, Bar y);
void unsafe_root(Boo x, Bar y);

@@ -17,3 +17,9 @@ #include <cstdarg>

constexpr static const PREFIXFoo PREFIXVAL = PREFIXFoo{ /* .a = */ 42, /* .b = */ 1337, /* .bar = */ PREFIXBar{ /* .a = */ 323 } };
constexpr static const PREFIXFoo PREFIXVAL = PREFIXFoo{
/* .a = */ 42,
/* .b = */ 1337,
/* .bar = */ PREFIXBar{
/* .a = */ 323
}
};

@@ -20,0 +26,0 @@ extern "C" {

@@ -11,5 +11,11 @@ #include <cstdarg>

};
constexpr static const PREFIXFoo PREFIXFoo_FOO = PREFIXFoo{ /* .a = */ 42, /* .b = */ 47 };
constexpr static const PREFIXFoo PREFIXFoo_FOO = PREFIXFoo{
/* .a = */ 42,
/* .b = */ 47
};
constexpr static const PREFIXFoo PREFIXBAR = PREFIXFoo{ /* .a = */ 42, /* .b = */ 1337 };
constexpr static const PREFIXFoo PREFIXBAR = PREFIXFoo{
/* .a = */ 42,
/* .b = */ 1337
};

@@ -16,0 +22,0 @@ extern "C" {

@@ -15,1 +15,3 @@ #include <stdarg.h>

void test_gecko_case(int32_t aFooBar);
void test_prefix(int32_t prefix_foo_bar);

@@ -20,4 +20,6 @@ #include <stdarg.h>

void test_prefix(int32_t prefix_foo_bar);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

@@ -19,2 +19,4 @@ #include <cstdarg>

void test_prefix(int32_t prefix_foo_bar);
} // extern "C"

@@ -18,1 +18,3 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

void test_gecko_case(int32_t aFooBar);
void test_prefix(int32_t prefix_foo_bar);

@@ -12,5 +12,17 @@ #include <cstdarg>

};
constexpr static const ABC ABC_abc = ABC{ /* .a = */ 1.0, /* .b = */ 2, /* .c = */ 3 };
constexpr static const ABC ABC_bac = ABC{ /* .a = */ 1.0, /* .b = */ 2, /* .c = */ 3 };
constexpr static const ABC ABC_cba = ABC{ /* .a = */ 1.0, /* .b = */ 2, /* .c = */ 3 };
constexpr static const ABC ABC_abc = ABC{
/* .a = */ 1.0,
/* .b = */ 2,
/* .c = */ 3
};
constexpr static const ABC ABC_bac = ABC{
/* .a = */ 1.0,
/* .b = */ 2,
/* .c = */ 3
};
constexpr static const ABC ABC_cba = ABC{
/* .a = */ 1.0,
/* .b = */ 2,
/* .c = */ 3
};

@@ -22,5 +34,17 @@ struct BAC {

};
constexpr static const BAC BAC_abc = BAC{ /* .b = */ 1, /* .a = */ 2.0, /* .c = */ 3 };
constexpr static const BAC BAC_bac = BAC{ /* .b = */ 1, /* .a = */ 2.0, /* .c = */ 3 };
constexpr static const BAC BAC_cba = BAC{ /* .b = */ 1, /* .a = */ 2.0, /* .c = */ 3 };
constexpr static const BAC BAC_abc = BAC{
/* .b = */ 1,
/* .a = */ 2.0,
/* .c = */ 3
};
constexpr static const BAC BAC_bac = BAC{
/* .b = */ 1,
/* .a = */ 2.0,
/* .c = */ 3
};
constexpr static const BAC BAC_cba = BAC{
/* .b = */ 1,
/* .a = */ 2.0,
/* .c = */ 3
};

@@ -27,0 +51,0 @@ extern "C" {

@@ -13,8 +13,20 @@ #include <cstdarg>

};
constexpr static const Foo Foo_FOO = Foo{ /* .a = */ 42, /* .b = */ 47 };
constexpr static const Foo Foo_FOO2 = Foo{ /* .a = */ 42, /* .b = */ 47 };
constexpr static const Foo Foo_FOO3 = Foo{ /* .a = */ 42, /* .b = */ 47 };
constexpr static const Foo Foo_FOO = Foo{
/* .a = */ 42,
/* .b = */ 47
};
constexpr static const Foo Foo_FOO2 = Foo{
/* .a = */ 42,
/* .b = */ 47
};
constexpr static const Foo Foo_FOO3 = Foo{
/* .a = */ 42,
/* .b = */ 47
};
constexpr static const Foo BAR = Foo{ /* .a = */ 42, /* .b = */ 1337 };
constexpr static const Foo BAR = Foo{
/* .a = */ 42,
/* .b = */ 1337
};

@@ -21,0 +33,0 @@

@@ -26,2 +26,6 @@ #include <stdarg.h>

typedef struct TransparentEmptyStructure {
} TransparentEmptyStructure;
#define EnumWithAssociatedConstantInImpl_TEN 10

@@ -36,2 +40,3 @@

TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);

@@ -26,2 +26,6 @@ #include <stdarg.h>

typedef struct TransparentEmptyStructure {
} TransparentEmptyStructure;
#define EnumWithAssociatedConstantInImpl_TEN 10

@@ -40,3 +44,4 @@

TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);

@@ -43,0 +48,0 @@ #ifdef __cplusplus

@@ -26,2 +26,6 @@ #include <stdarg.h>

struct TransparentEmptyStructure {
};
#define EnumWithAssociatedConstantInImpl_TEN 10

@@ -36,2 +40,3 @@

TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);

@@ -26,2 +26,6 @@ #include <stdarg.h>

struct TransparentEmptyStructure {
};
#define EnumWithAssociatedConstantInImpl_TEN 10

@@ -40,3 +44,4 @@

TransparentPrimitiveWithAssociatedConstants g,
struct EnumWithAssociatedConstantInImpl h);
struct TransparentEmptyStructure h,
struct EnumWithAssociatedConstantInImpl i);

@@ -43,0 +48,0 @@ #ifdef __cplusplus

@@ -31,2 +31,5 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

cdef struct TransparentEmptyStructure:
pass
const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN # = 10

@@ -41,2 +44,3 @@

TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);

@@ -26,2 +26,6 @@ #include <stdarg.h>

typedef struct {
} TransparentEmptyStructure;
#define EnumWithAssociatedConstantInImpl_TEN 10

@@ -36,2 +40,3 @@

TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);

@@ -26,2 +26,6 @@ #include <stdarg.h>

typedef struct {
} TransparentEmptyStructure;
#define EnumWithAssociatedConstantInImpl_TEN 10

@@ -40,3 +44,4 @@

TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);

@@ -43,0 +48,0 @@ #ifdef __cplusplus

@@ -29,2 +29,6 @@ #include <cstdarg>

struct TransparentEmptyStructure {
};
constexpr static const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN = 10;

@@ -41,4 +45,5 @@

TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);
} // extern "C"

@@ -31,2 +31,5 @@ from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t

ctypedef struct TransparentEmptyStructure:
pass
const TransparentPrimitiveWrappingStructure EnumWithAssociatedConstantInImpl_TEN # = 10

@@ -41,2 +44,3 @@

TransparentPrimitiveWithAssociatedConstants g,
EnumWithAssociatedConstantInImpl h);
TransparentEmptyStructure h,
EnumWithAssociatedConstantInImpl i);
#[export_name = "do_the_thing_with_export_name"]
pub extern "C" fn do_the_thing() {
println!("doing the thing!");
}
}
#[unsafe(export_name = "do_the_thing_with_unsafe_export_name")]
pub extern "C" fn unsafe_do_the_thing() {
println!("doing the thing!");
}

@@ -12,1 +12,4 @@ #[repr(C)]

) { }
#[no_mangle]
pub extern "C" fn my_function(x: Foo<[u8; 4]>) {}

@@ -20,1 +20,7 @@ #[repr(C)]

) { }
#[unsafe(no_mangle)]
pub extern "C" fn unsafe_root(
x: Boo,
y: Bar,
) { }

@@ -20,1 +20,5 @@ /// cbindgen:rename-all=CamelCase

pub extern "C" fn test_gecko_case(foo_bar: i32) {}
/// cbindgen:rename-all=prefix:prefix_
#[no_mangle]
pub extern "C" fn test_prefix(foo_bar: i32) {}

@@ -44,2 +44,7 @@ struct DummyStruct;

// Transparent zero-sized structs are legal rust, but there's no way to emit a typedef for one, so
// cbindgen should treat it as repr(C) instead and emit an empty struct definition.
#[repr(transparent)]
struct TransparentEmptyStructure;
// Associated constant declared after struct declaration.

@@ -67,3 +72,4 @@ impl TransparentPrimitiveWithAssociatedConstants {

g: TransparentPrimitiveWithAssociatedConstants,
h: EnumWithAssociatedConstantInImpl,
h: TransparentEmptyStructure,
i: EnumWithAssociatedConstantInImpl,
) { }

@@ -10,2 +10,3 @@ extern crate cbindgen;

use std::{env, fs, str};
use tempfile::NamedTempFile;

@@ -25,2 +26,8 @@ use pretty_assertions::assert_eq;

struct CBindgenOutput {
bindings_content: Vec<u8>,
depfile_content: Option<String>,
symfile_content: Option<String>,
}
fn run_cbindgen(

@@ -34,6 +41,7 @@ path: &Path,

package_version: bool,
) -> (Vec<u8>, Option<String>) {
generate_symfile: bool,
) -> CBindgenOutput {
assert!(
!(output.is_none() && generate_depfile),
"generating a depfile requires outputting to a path"
!output.is_none() || !(generate_depfile || generate_symfile),
"generating a depfile or symfile requires outputting to a path"
);

@@ -45,6 +53,7 @@ let program = Path::new(CBINDGEN_PATH);

}
let cbindgen_depfile = if generate_depfile {
let depfile = tempfile::NamedTempFile::new().unwrap();
command.arg("--depfile").arg(depfile.path());
Some(depfile)
let depfile = if generate_depfile {
let tmp = tempfile::NamedTempFile::new().unwrap();
command.arg("--depfile").arg(tmp.path());
Some(tmp)
} else {

@@ -54,2 +63,10 @@ None

let symfile = if generate_symfile {
let tmp = tempfile::NamedTempFile::new().unwrap();
command.arg("--symfile").arg(tmp.path());
Some(tmp)
} else {
None
};
match language {

@@ -94,3 +111,3 @@ Language::Cxx => {}

let bindings = if let Some(output_path) = output {
let bindings_content = if let Some(output_path) = output {
let mut bindings = Vec::new();

@@ -106,14 +123,13 @@ // Ignore errors here, we have assertions on the expected output later.

let depfile_contents = if let Some(mut depfile) = cbindgen_depfile {
let mut raw = Vec::new();
depfile.read_to_end(&mut raw).unwrap();
Some(
str::from_utf8(raw.as_slice())
.expect("Invalid encoding encountered in depfile")
.into(),
)
} else {
None
};
(bindings, depfile_contents)
fn read_to_string(f: NamedTempFile) -> String {
std::fs::read_to_string(&f).expect(&format!("Failed to read file as String: {:?}", f))
}
let depfile_content = depfile.map(read_to_string);
let symfile_content = symfile.map(read_to_string);
CBindgenOutput {
bindings_content,
depfile_content,
symfile_content,
}
}

@@ -218,2 +234,3 @@

package_version: bool,
generate_symfile: bool,
) {

@@ -223,4 +240,9 @@ let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

let mut generated_file = tests_path.join("expectations");
let mut generated_symfile = tests_path.join("expectations-symbols");
fs::create_dir_all(&generated_file).unwrap();
fs::create_dir_all(&generated_symfile).unwrap();
let verify = env::var_os("CBINDGEN_TEST_VERIFY").is_some();
let no_compile = env::var_os("CBINDGEN_TEST_NO_COMPILE").is_some();
let style_ext = style

@@ -248,7 +270,9 @@ // Cython is sensitive to dots, so we can't include any dots.

format!("{}{}{}", name, style_ext, lang_ext).replace(SKIP_WARNING_AS_ERROR_SUFFIX, "");
let symbols_file = format!("{source_file}.sym");
generated_file.push(source_file);
generated_symfile.push(symbols_file);
let (output_file, generate_depfile) = if env::var_os("CBINDGEN_TEST_VERIFY").is_some() {
(None, false)
let (output_file, generate_depfile, generate_symfile) = if verify {
(None, false, false)
} else {

@@ -259,6 +283,11 @@ (

!(name.contains("expand") || name.contains("bitfield")),
generate_symfile,
)
};
let (cbindgen_output, depfile_contents) = run_cbindgen(
let CBindgenOutput {
bindings_content,
depfile_content,
symfile_content,
} = run_cbindgen(
path,

@@ -271,5 +300,6 @@ output_file,

package_version,
generate_symfile,
);
if generate_depfile {
let depfile = depfile_contents.expect("No depfile generated");
let depfile = depfile_content.expect("No depfile generated");
assert!(!depfile.is_empty());

@@ -290,5 +320,5 @@ let mut rules = depfile.split(':');

if cbindgen_outputs.contains(&cbindgen_output) {
if cbindgen_outputs.contains(&bindings_content) {
// We already generated an identical file previously.
if env::var_os("CBINDGEN_TEST_VERIFY").is_some() {
if verify {
assert!(!generated_file.exists());

@@ -299,15 +329,19 @@ } else if generated_file.exists() {

} else {
if env::var_os("CBINDGEN_TEST_VERIFY").is_some() {
use std::str::from_utf8;
let prev_cbindgen_output = fs::read(&generated_file).unwrap();
let cbindgen_output = from_utf8(&cbindgen_output).unwrap();
let prev_cbindgen_output = from_utf8(&prev_cbindgen_output).unwrap();
assert_eq!(prev_cbindgen_output, cbindgen_output);
if verify {
// Compare cbindgen output to expected (existing on disk) output.
let prev_cbindgen_bindings = fs::read(&generated_file).unwrap();
assert_eq!(bindings_content, prev_cbindgen_bindings);
} else {
fs::write(&generated_file, &cbindgen_output).unwrap();
fs::write(&generated_file, &bindings_content)
.expect("Failed to write generated bindings.");
if generate_symfile {
let symbols = symfile_content.expect("No symfile generated");
fs::write(&generated_symfile, &symbols)
.expect("Failed to write generated symbols.");
}
}
cbindgen_outputs.insert(cbindgen_output);
cbindgen_outputs.insert(bindings_content);
if env::var_os("CBINDGEN_TEST_NO_COMPILE").is_some() {
if no_compile {
return;

@@ -350,2 +384,5 @@ }

for style in &[Style::Type, Style::Tag, Style::Both] {
// We only need to generate the symfile once,
// it should not change with the different options.
let generate_symfile = !cpp_compat && *style == Style::Type;
run_compile_test(

@@ -360,2 +397,3 @@ name,

false,
generate_symfile,
);

@@ -374,2 +412,3 @@ }

false,
/* generate_symfile = */ false,
);

@@ -389,2 +428,3 @@

false,
/* generate_symfile = */ false,
);

@@ -391,0 +431,0 @@ }

Sorry, the diff of this file is not supported yet