Skip to content

Commit d2e0407

Browse files
kulpemilio
authored andcommitted
Introduce tests for functional macros
1 parent 63b05cb commit d2e0407

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

bindgen-integration/build.rs

+57-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::sync::{Arc, Mutex, RwLock};
1212
struct MacroCallback {
1313
macros: Arc<RwLock<HashSet<String>>>,
1414
seen_hellos: Mutex<u32>,
15+
seen_funcs: Mutex<u32>,
1516
}
1617

1718
impl ParseCallbacks for MacroCallback {
@@ -45,6 +46,10 @@ impl ParseCallbacks for MacroCallback {
4546

4647
fn str_macro(&self, name: &str, value: &[u8]) {
4748
match name {
49+
"TESTMACRO_STRING_EXPR" => {
50+
assert_eq!(value, b"string");
51+
*self.seen_hellos.lock().unwrap() += 1;
52+
}
4853
"TESTMACRO_STRING_EXPANDED" |
4954
"TESTMACRO_STRING" |
5055
"TESTMACRO_INTEGER" => {
@@ -70,15 +75,64 @@ impl ParseCallbacks for MacroCallback {
7075
_ => None,
7176
}
7277
}
78+
79+
fn func_macro(&self, name: &str, value: &[&[u8]]) {
80+
match name {
81+
"TESTMACRO_NONFUNCTIONAL" => {
82+
panic!("func_macro was called for a non-functional macro");
83+
}
84+
"TESTMACRO_FUNCTIONAL_NONEMPTY(TESTMACRO_INTEGER)" => {
85+
// Spaces are inserted into the right-hand side of a functional
86+
// macro during reconstruction from the tokenization. This might
87+
// change in the future, but it is safe by the definition of a
88+
// token in C, whereas leaving the spaces out could change
89+
// tokenization.
90+
assert_eq!(value, &[b"-" as &[u8], b"TESTMACRO_INTEGER"]);
91+
*self.seen_funcs.lock().unwrap() += 1;
92+
}
93+
"TESTMACRO_FUNCTIONAL_EMPTY(TESTMACRO_INTEGER)" => {
94+
assert_eq!(value, &[] as &[&[u8]]);
95+
*self.seen_funcs.lock().unwrap() += 1;
96+
}
97+
"TESTMACRO_FUNCTIONAL_TOKENIZED(a,b,c,d,e)" => {
98+
assert_eq!(
99+
value,
100+
&[b"a" as &[u8], b"/", b"b", b"c", b"d", b"##", b"e"]
101+
);
102+
*self.seen_funcs.lock().unwrap() += 1;
103+
}
104+
"TESTMACRO_FUNCTIONAL_SPLIT(a,b)" => {
105+
assert_eq!(value, &[b"b", b",", b"a"]);
106+
*self.seen_funcs.lock().unwrap() += 1;
107+
}
108+
"TESTMACRO_STRING_FUNC_NON_UTF8(x)" => {
109+
assert_eq!(
110+
value,
111+
&[b"(" as &[u8], b"x", b"\"\xff\xff\"", b")"]
112+
);
113+
*self.seen_funcs.lock().unwrap() += 1;
114+
}
115+
_ => {
116+
// The system might provide lots of functional macros.
117+
// Ensure we did not miss handling one that we meant to handle.
118+
assert!(!name.starts_with("TESTMACRO_"), "name = {}", name);
119+
}
120+
}
121+
}
73122
}
74123

75124
impl Drop for MacroCallback {
76125
fn drop(&mut self) {
77126
assert_eq!(
78127
*self.seen_hellos.lock().unwrap(),
79-
2,
128+
3,
80129
"str_macro handle was not called once for all relevant macros"
81-
)
130+
);
131+
assert_eq!(
132+
*self.seen_funcs.lock().unwrap(),
133+
5,
134+
"func_macro handle was not called once for all relevant macros"
135+
);
82136
}
83137
}
84138

@@ -102,6 +156,7 @@ fn main() {
102156
.parse_callbacks(Box::new(MacroCallback {
103157
macros: macros.clone(),
104158
seen_hellos: Mutex::new(0),
159+
seen_funcs: Mutex::new(0),
105160
}))
106161
.blacklist_function("my_prefixed_function_to_remove")
107162
.generate()

bindgen-integration/cpp/Test.h

+13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@
77
#define TESTMACRO_STRING_EXPANDED TESTMACRO_STRING
88
#define TESTMACRO_CUSTOMINTKIND_PATH 123
99

10+
// The following two macros are parsed the same by cexpr, but are semantically
11+
// different.
12+
#define TESTMACRO_NONFUNCTIONAL (TESTMACRO_INTEGER)
13+
#define TESTMACRO_FUNCTIONAL_EMPTY(TESTMACRO_INTEGER)
14+
#define TESTMACRO_FUNCTIONAL_NONEMPTY(TESTMACRO_INTEGER)-TESTMACRO_INTEGER
15+
#define TESTMACRO_FUNCTIONAL_TOKENIZED( a, b ,c,d,e ) a/b c d ## e
16+
#define TESTMACRO_FUNCTIONAL_SPLIT( a, \
17+
b) b,\
18+
a
19+
//#define TESTMACRO_INVALID("string") // A conforming preprocessor rejects this
20+
#define TESTMACRO_STRING_EXPR ("string")
21+
#define TESTMACRO_STRING_FUNC_NON_UTF8(x) (x "ÿÿ") /* invalid UTF-8 on purpose */
22+
1023
#include <cwchar>
1124

1225
enum {

0 commit comments

Comments
 (0)