Skip to content

Commit d265b8e

Browse files
jacobbramleyAmanieu
authored andcommitted
Check and pass the ACLE licence on to generated tests.
The generated tests are transient, and aren't committed, so this is primarily a safety check.
1 parent 1775b3e commit d265b8e

File tree

3 files changed

+86
-15
lines changed

3 files changed

+86
-15
lines changed

crates/intrinsic-test/LICENSE-MIT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2021-2022 The Rust Project Developers
1+
Copyright (c) 2021-2023 The Rust Project Developers
22

33
Permission is hereby granted, free of charge, to any
44
person obtaining a copy of this software and associated

crates/intrinsic-test/src/acle_csv_parser.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,53 @@ use crate::argument::{Argument, ArgumentList, Constraint};
66
use crate::intrinsic::Intrinsic;
77
use crate::types::{IntrinsicType, TypeKind};
88

9-
pub fn get_acle_intrinsics(filename: &str) -> Vec<Intrinsic> {
9+
pub struct CsvMetadata {
10+
notices: String,
11+
spdx_lic: String,
12+
}
13+
14+
impl CsvMetadata {
15+
fn new<'a>(header: impl Iterator<Item = &'a str>) -> Self {
16+
lazy_static! {
17+
static ref SPDX_LICENSE_IDENTIFIER: Regex =
18+
Regex::new(r#"SPDX-License-Identifier:(.*)"#).unwrap();
19+
}
20+
21+
let notices = header.map(|line| format!("{line}\n")).collect::<String>();
22+
let spdx_lic = match SPDX_LICENSE_IDENTIFIER
23+
.captures_iter(&notices)
24+
.exactly_one()
25+
{
26+
Ok(caps) => {
27+
let cap = caps.get(1).unwrap().as_str().trim();
28+
// Ensure that (unlikely) ACLE licence changes don't go unnoticed.
29+
assert_eq!(cap, "Apache-2.0");
30+
cap.to_string()
31+
}
32+
Err(caps_iter) => panic!(
33+
"Expected exactly one SPDX-License-Identifier, found {}.",
34+
caps_iter.count()
35+
),
36+
};
37+
38+
Self { notices, spdx_lic }
39+
}
40+
41+
pub fn spdx_license_identifier(&self) -> &str {
42+
self.spdx_lic.as_str()
43+
}
44+
45+
pub fn notices_lines(&self) -> impl Iterator<Item = &str> {
46+
self.notices.lines()
47+
}
48+
}
49+
50+
pub fn get_acle_intrinsics(filename: &str) -> (CsvMetadata, Vec<Intrinsic>) {
1051
let data = std::fs::read_to_string(filename).expect("Failed to open ACLE intrinsics file");
1152

53+
let comment_header = data.lines().map_while(|l| l.strip_prefix("<COMMENT>\t"));
54+
let meta = CsvMetadata::new(comment_header);
55+
1256
let data = data
1357
.lines()
1458
.filter_map(|l| {
@@ -51,7 +95,7 @@ pub fn get_acle_intrinsics(filename: &str) -> Vec<Intrinsic> {
5195
}
5296
}
5397

54-
intrinsics.to_vec()
98+
(meta, intrinsics.to_vec())
5599
}
56100

57101
impl Into<Intrinsic> for ACLEIntrinsicLine {

crates/intrinsic-test/src/main.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use itertools::Itertools;
1414
use rayon::prelude::*;
1515
use types::TypeKind;
1616

17-
use crate::acle_csv_parser::get_acle_intrinsics;
17+
use crate::acle_csv_parser::{get_acle_intrinsics, CsvMetadata};
1818
use crate::argument::Argument;
1919

2020
mod acle_csv_parser;
@@ -70,6 +70,7 @@ fn gen_code_c(
7070
}
7171

7272
fn generate_c_program(
73+
notices: &str,
7374
header_files: &[&str],
7475
intrinsic: &Intrinsic,
7576
p64_armv7_workaround: bool,
@@ -81,7 +82,7 @@ fn generate_c_program(
8182
.collect_vec();
8283

8384
format!(
84-
r#"{header_files}
85+
r#"{notices}{header_files}
8586
#include <iostream>
8687
#include <cstring>
8788
#include <iomanip>
@@ -157,15 +158,15 @@ fn gen_code_rust(intrinsic: &Intrinsic, constraints: &[&Argument], name: String)
157158
}
158159
}
159160

160-
fn generate_rust_program(intrinsic: &Intrinsic, a32: bool) -> String {
161+
fn generate_rust_program(notices: &str, intrinsic: &Intrinsic, a32: bool) -> String {
161162
let constraints = intrinsic
162163
.arguments
163164
.iter()
164165
.filter(|i| i.has_constraint())
165166
.collect_vec();
166167

167168
format!(
168-
r#"#![feature(simd_ffi)]
169+
r#"{notices}#![feature(simd_ffi)]
169170
#![feature(link_llvm_intrinsics)]
170171
#![feature(stdsimd)]
171172
#![allow(overflowing_literals)]
@@ -217,30 +218,52 @@ fn compile_c(c_filename: &str, intrinsic: &Intrinsic, compiler: &str, a32: bool)
217218
}
218219
}
219220

220-
fn build_c(intrinsics: &Vec<Intrinsic>, compiler: &str, a32: bool) -> bool {
221+
fn build_notices(csv_metadata: &CsvMetadata, line_prefix: &str) -> String {
222+
let mut notices = format!(
223+
"\
224+
{line_prefix}This is a transient test file, not intended for distribution. Some aspects of the
225+
{line_prefix}test are derived from a CSV specification, published with the following notices:
226+
{line_prefix}
227+
"
228+
);
229+
let lines = csv_metadata
230+
.notices_lines()
231+
.map(|line| format!("{line_prefix} {line}\n"));
232+
notices.extend(lines);
233+
notices.push_str("\n");
234+
notices
235+
}
236+
237+
fn build_c(notices: &str, intrinsics: &Vec<Intrinsic>, compiler: &str, a32: bool) -> bool {
221238
let _ = std::fs::create_dir("c_programs");
222239
intrinsics
223240
.par_iter()
224241
.map(|i| {
225242
let c_filename = format!(r#"c_programs/{}.cpp"#, i.name);
226243
let mut file = File::create(&c_filename).unwrap();
227244

228-
let c_code = generate_c_program(&["arm_neon.h", "arm_acle.h"], &i, a32);
245+
let c_code = generate_c_program(notices, &["arm_neon.h", "arm_acle.h"], &i, a32);
229246
file.write_all(c_code.into_bytes().as_slice()).unwrap();
230247
compile_c(&c_filename, &i, compiler, a32)
231248
})
232249
.find_any(|x| !x)
233250
.is_none()
234251
}
235252

236-
fn build_rust(intrinsics: &Vec<Intrinsic>, toolchain: &str, a32: bool) -> bool {
253+
fn build_rust(
254+
notices: &str,
255+
spdx_lic: &str,
256+
intrinsics: &Vec<Intrinsic>,
257+
toolchain: &str,
258+
a32: bool,
259+
) -> bool {
237260
intrinsics.iter().for_each(|i| {
238261
let rust_dir = format!(r#"rust_programs/{}"#, i.name);
239262
let _ = std::fs::create_dir_all(&rust_dir);
240263
let rust_filename = format!(r#"{rust_dir}/main.rs"#);
241264
let mut file = File::create(&rust_filename).unwrap();
242265

243-
let c_code = generate_rust_program(&i, a32);
266+
let c_code = generate_rust_program(notices, &i, a32);
244267
file.write_all(c_code.into_bytes().as_slice()).unwrap();
245268
});
246269

@@ -249,9 +272,10 @@ fn build_rust(intrinsics: &Vec<Intrinsic>, toolchain: &str, a32: bool) -> bool {
249272
.write_all(
250273
format!(
251274
r#"[package]
252-
name = "intrinsic-test"
275+
name = "intrinsic-test-programs"
253276
version = "{version}"
254277
authors = ["{authors}"]
278+
license = "{spdx_lic}"
255279
edition = "2018"
256280
[workspace]
257281
[dependencies]
@@ -371,7 +395,7 @@ fn main() {
371395
};
372396
let a32 = matches.is_present("A32");
373397

374-
let intrinsics = get_acle_intrinsics(filename);
398+
let (csv_metadata, intrinsics) = get_acle_intrinsics(filename);
375399

376400
let mut intrinsics = intrinsics
377401
.into_iter()
@@ -394,11 +418,14 @@ fn main() {
394418
.collect::<Vec<_>>();
395419
intrinsics.dedup();
396420

397-
if !build_c(&intrinsics, cpp_compiler, a32) {
421+
let notices = build_notices(&csv_metadata, "// ");
422+
let spdx_lic = csv_metadata.spdx_license_identifier();
423+
424+
if !build_c(&notices, &intrinsics, cpp_compiler, a32) {
398425
std::process::exit(2);
399426
}
400427

401-
if !build_rust(&intrinsics, &toolchain, a32) {
428+
if !build_rust(&notices, spdx_lic, &intrinsics, &toolchain, a32) {
402429
std::process::exit(3);
403430
}
404431

0 commit comments

Comments
 (0)