1#![no_std]
28
29#[allow(
30 missing_docs,
31 nonstandard_style,
32 unsafe_op_in_unsafe_fn,
33 unused,
34 clippy::all,
35 clippy::pedantic,
36 clippy::nursery,
37 clippy::restriction,
38 rustdoc::all,
39 reason = "generated by bindgen; regenerate with `cargo xtask bindgen`"
40)]
41mod bindings;
42mod midi;
43
44pub use bindings::*;
45pub use midi::{
46 BELA_MIDI_ALREADY_OPEN, BELA_MIDI_MESSAGE_MAX, BELA_MIDI_NO_SUCH_PORT, BelaMidi,
47 bela_midi_available_messages, bela_midi_delete, bela_midi_get_message, bela_midi_list_ports,
48 bela_midi_new, bela_midi_read_from, bela_midi_write_output, bela_midi_write_to,
49};
50
51#[cfg(test)]
55mod shim_compiler {
56 extern crate std;
57
58 use std::borrow::ToOwned;
59 use std::format;
60 use std::string::String;
61
62 include!("../shim_compiler.rs");
63
64 #[test]
65 fn bela_cxx_is_taken_as_it_stands() {
66 assert_eq!(
67 shim_compiler_from(
68 "clang++",
69 "aarch64-unknown-linux-gnu-gcc",
70 "aarch64-linux-gnu-gcc"
71 ),
72 Ok("clang++".to_owned()),
73 "an explicit C++ compiler outranks anything derived, even a resolved linker"
74 );
75 }
76
77 #[test]
78 fn a_c_compiler_ending_in_gcc_answers_for_both() {
79 assert_eq!(
82 shim_compiler_from("", "", "aarch64-linux-gnu-gcc"),
83 Ok("aarch64-linux-gnu-g++".to_owned())
84 );
85 assert_eq!(shim_compiler_from("", "", "gcc"), Ok("g++".to_owned()));
86 }
87
88 #[test]
89 fn neither_set_is_the_tap_default() {
90 assert_eq!(
91 shim_compiler_from("", "", ""),
92 Ok(DEFAULT_CXX.to_owned()),
93 "the same default scripts/aarch64-bela-linker.sh has"
94 );
95 }
96
97 #[test]
98 fn a_c_compiler_nothing_follows_from_is_refused() {
99 let error = shim_compiler_from("", "", "clang").unwrap_err();
103 assert!(
104 error.contains("BELA_CXX"),
105 "the message should say what to set, got: {error}"
106 );
107 }
108
109 #[test]
110 fn a_resolved_gcc_linker_answers_for_the_shim_too() {
111 assert_eq!(
115 shim_compiler_from("", "aarch64-unknown-linux-gnu-gcc", ""),
116 Ok("aarch64-unknown-linux-gnu-g++".to_owned())
117 );
118 assert_eq!(shim_compiler_from("", "gcc", ""), Ok("g++".to_owned()));
119 }
120
121 #[test]
122 fn a_resolved_linker_outranks_a_stale_bela_cc() {
123 assert_eq!(
128 shim_compiler_from("", "aarch64-unknown-linux-gnu-gcc", "gcc"),
129 Ok("aarch64-unknown-linux-gnu-g++".to_owned())
130 );
131 }
132
133 #[test]
134 fn the_wrapper_as_the_resolved_linker_falls_through_to_bela_cc() {
135 assert_eq!(
139 shim_compiler_from("", "scripts/aarch64-bela-linker.sh", "gcc"),
140 Ok("g++".to_owned())
141 );
142 assert_eq!(
143 shim_compiler_from(
144 "",
145 "/Users/dev/bela-rs/scripts/aarch64-bela-linker.sh",
146 "aarch64-linux-gnu-gcc"
147 ),
148 Ok("aarch64-linux-gnu-g++".to_owned()),
149 "an absolute path still matches by its last segment"
150 );
151 assert_eq!(
152 shim_compiler_from("", "scripts/aarch64-bela-linker.sh", ""),
153 Ok(DEFAULT_CXX.to_owned()),
154 "and with BELA_CC unset too, the tap default"
155 );
156 }
157
158 #[test]
159 fn a_resolved_linker_nothing_follows_from_is_refused() {
160 let error = shim_compiler_from("", "clang", "").unwrap_err();
165 assert!(
166 error.contains("BELA_CXX"),
167 "the message should say what to set, got: {error}"
168 );
169 }
170
171 #[test]
172 fn the_archiver_follows_the_compiler_it_belongs_to() {
173 assert_eq!(
174 shim_archiver("aarch64-unknown-linux-gnu-g++"),
175 Some("aarch64-unknown-linux-gnu-ar".to_owned()),
176 "cc would otherwise look for one named after the target triple"
177 );
178 assert_eq!(shim_archiver("g++"), Some("ar".to_owned()));
179 }
180
181 #[test]
182 fn an_archiver_that_does_not_follow_is_left_to_cc() {
183 assert_eq!(shim_archiver("clang++"), None);
187 assert_eq!(shim_archiver("aarch64-linux-gnu-clang++"), None);
188 }
189
190 #[test]
191 fn a_compiler_named_by_its_path_is_still_one() {
192 assert_eq!(
195 shim_compiler_from("", "", "/usr/bin/gcc"),
196 Ok("/usr/bin/g++".to_owned())
197 );
198 assert_eq!(
199 shim_compiler_from("", "", "/opt/tc/bin/aarch64-linux-gnu-gcc"),
200 Ok("/opt/tc/bin/aarch64-linux-gnu-g++".to_owned())
201 );
202 assert_eq!(
203 shim_archiver("/usr/bin/g++"),
204 Some("/usr/bin/ar".to_owned()),
205 "and the archiver beside it"
206 );
207 }
208
209 #[test]
210 fn a_compiler_that_merely_ends_in_gcc_is_not_one() {
211 assert!(shim_compiler_from("", "", "notgcc").is_err());
214 assert_eq!(shim_archiver("notg++"), None);
215 assert_eq!(
216 shim_archiver("/usr/bin/clang++"),
217 None,
218 "a path does not make it one"
219 );
220 }
221}
222
223#[cfg(test)]
227mod link_args {
228 extern crate std;
229
230 use std::borrow::ToOwned;
231 use std::format;
232 use std::string::{String, ToString};
233 use std::vec;
234 use std::vec::Vec;
235
236 include!("../link_args.rs");
237
238 fn args(values: &[&str]) -> Vec<String> {
239 values.iter().map(|value| (*value).to_owned()).collect()
240 }
241
242 #[test]
243 fn no_arguments_still_publishes_a_zero_count() {
244 assert_eq!(
245 encode_link_args(&[]),
246 vec![("LINK_ARGS_COUNT".to_owned(), "0".to_owned())],
247 "a dependent has to see a count of zero, not an absent key, \
248 to tell \"nothing to add\" apart from \"never ran\""
249 );
250 }
251
252 #[test]
253 fn arguments_are_indexed_from_zero_in_order() {
254 assert_eq!(
255 encode_link_args(&args(&["--sysroot=/opt/bela", "-Bfoo"])),
256 vec![
257 ("LINK_ARGS_COUNT".to_owned(), "2".to_owned()),
258 ("LINK_ARGS_0".to_owned(), "--sysroot=/opt/bela".to_owned()),
259 ("LINK_ARGS_1".to_owned(), "-Bfoo".to_owned()),
260 ]
261 );
262 }
263
264 #[test]
265 fn whitespace_in_an_argument_survives_uninterpreted() {
266 let value = "--sysroot=/Volumes/Bela Sysroot";
270 assert_eq!(
271 encode_link_args(&args(&[value])),
272 vec![
273 ("LINK_ARGS_COUNT".to_owned(), "1".to_owned()),
274 ("LINK_ARGS_0".to_owned(), value.to_owned()),
275 ]
276 );
277 }
278}
279
280#[cfg(test)]
285mod shim_header {
286 extern crate std;
287
288 use std::format;
289
290 const HEADER: &str = include_str!("../shim/midi.h");
293
294 fn defined(name: &str) -> i64 {
298 let line = HEADER
299 .lines()
300 .find(|line| line.starts_with(&format!("#define {name} ")))
301 .unwrap_or_else(|| panic!("{name} is not defined in shim/midi.h"));
302 let value = line.split_whitespace().nth(2).expect("a value");
303 value
304 .trim_start_matches('(')
305 .trim_end_matches(')')
306 .parse()
307 .expect("a number")
308 }
309
310 #[test]
311 fn the_constants_match_the_header() {
312 assert_eq!(
313 defined("BELA_MIDI_MESSAGE_MAX"),
314 i64::try_from(super::BELA_MIDI_MESSAGE_MAX).expect("a small buffer size")
315 );
316 assert_eq!(
317 defined("BELA_MIDI_NO_SUCH_PORT"),
318 i64::from(super::BELA_MIDI_NO_SUCH_PORT)
319 );
320 assert_eq!(
321 defined("BELA_MIDI_ALREADY_OPEN"),
322 i64::from(super::BELA_MIDI_ALREADY_OPEN)
323 );
324 }
325}