Skip to content

Commit f0a00a2

Browse files
committed
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 ab7963f commit f0a00a2

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)