Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 0d32984

Browse files
committed
WIP: Verification of libm API
1 parent 311f945 commit 0d32984

File tree

6 files changed

+128
-0
lines changed

6 files changed

+128
-0
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[workspace]
22
members = [
33
"crates/libm",
4+
"crates/libm-analyze",
5+
"crates/libm-verify",
46
"crates/compiler-builtins-smoke-test",
57
"crates/libm-bench",
68
]

crates/libm-analyze/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "libm-analyze"
3+
version = "0.1.0"
4+
authors = ["gnzlbg <[email protected]>"]
5+
edition = "2018"
6+
7+
[lib]
8+
proc-macro = true
9+
test = false
10+
11+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12+
13+
[dependencies]
14+
syn = { version = "0.15", features = ["full", "extra-traits"] }
15+
quote = "0.6"
16+
walkdir = "2.2.8"

crates/libm-analyze/src/lib.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#![feature(proc_macro_diagnostic)]
2+
3+
extern crate proc_macro;
4+
use self::proc_macro::TokenStream;
5+
6+
#[proc_macro]
7+
pub fn for_each_api(input: TokenStream) -> TokenStream {
8+
let files = get_libm_files();
9+
let functions = get_functions(files);
10+
input
11+
}
12+
13+
/// Traverses the libm crate directory, parsing all .rs files
14+
fn get_libm_files() -> Vec<(syn::File, String)> {
15+
let root_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
16+
dbg!(&root_dir);
17+
let libm_dir = root_dir
18+
.parent()
19+
.expect("couldn't access crates/ dir")
20+
.join("libm");
21+
dbg!(&libm_dir);
22+
let libm_src_dir = libm_dir.join("src");
23+
dbg!(&libm_src_dir);
24+
25+
let mut files = Vec::new();
26+
for entry in walkdir::WalkDir::new(libm_src_dir)
27+
.into_iter()
28+
.filter_map(|e| e.ok())
29+
{
30+
use std::io::Read;
31+
let file_path = entry.path();
32+
if file_path.is_dir()
33+
|| !file_path
34+
.to_str()
35+
.expect("can't format file path")
36+
.ends_with(".rs")
37+
{
38+
continue;
39+
}
40+
41+
eprintln!("{}", file_path.display());
42+
let mut file_string = String::new();
43+
std::fs::File::open(&file_path)
44+
.unwrap_or_else(|_| panic!("can't open file at path: {}", file_path.display()))
45+
.read_to_string(&mut file_string)
46+
.expect("failed to read file to string");
47+
let file = syn::parse_file(&file_string).expect("failed to parse");
48+
files.push((file, file_path.to_str().unwrap().to_string()));
49+
}
50+
files
51+
}
52+
53+
struct FnSig {
54+
ident: syn::Ident,
55+
unsafety: bool,
56+
constness: bool,
57+
asyncness: bool,
58+
attrs: Vec<syn::Attribute>,
59+
abi: &'static str,
60+
61+
}
62+
63+
/// Extracts all public functions from the libm files.
64+
fn get_functions(files: Vec<(syn::File, String)>) {
65+
//let mut functions = Vec::new();
66+
for item in files.iter().flat_map(|f| f.0.items.iter()) {
67+
match item {
68+
syn::Item::Fn(syn::ItemFn {
69+
vis: syn::Visibility::Public(_),
70+
ident,
71+
constness,
72+
asyncness,
73+
unsafety,
74+
attrs,
75+
abi,
76+
decl,
77+
block: _,
78+
}) => {
79+
if let Some(syn::Abi { name: Some(l), extern_token: _ }) = abi {
80+
println!("{:#?}", l);
81+
if l.value() != "C" {
82+
l.span().unwrap().warning(
83+
"public libm function is not `extern \"C\""
84+
).emit();
85+
}
86+
} else {
87+
ident.span().unwrap().warning(
88+
"public libm function is not `extern \"C\""
89+
).emit();
90+
}
91+
println!("{:#?}", ident);
92+
}
93+
_ => (),
94+
}
95+
}
96+
}

crates/libm-verify/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "libm-verify"
3+
version = "0.1.0"
4+
authors = ["gnzlbg <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dev-dependencies]
10+
libm-analyze = { path = "../libm-analyze" }

crates/libm-verify/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//! TODO

crates/libm-verify/tests/musl.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#![cfg(test)]
2+
3+
libm_analyze::for_each_api!(const X: i32 = 0;);

0 commit comments

Comments
 (0)