Skip to content

Commit 0f9f8c9

Browse files
authoredJan 12, 2025··
Merge pull request #4220 from rmehri01/syn-style
Rewrite `style.rs` using `syn`
2 parents 3f44946 + 94c2b14 commit 0f9f8c9

File tree

13 files changed

+857
-248
lines changed

13 files changed

+857
-248
lines changed
 

‎.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
target
22
Cargo.lock
33
*~
4-
style

‎ci/run.sh

+13-6
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ if [ -n "${QEMU:-}" ]; then
8181
fi
8282

8383
cmd="cargo test --target $target ${LIBC_CI_ZBUILD_STD+"-Zbuild-std"}"
84+
test_flags="--skip check_style"
8485

8586
# Run tests in the `libc` crate
8687
case "$target" in
@@ -101,25 +102,31 @@ if [ "$target" = "s390x-unknown-linux-gnu" ]; then
101102
passed=0
102103
until [ $n -ge $N ]; do
103104
if [ "$passed" = "0" ]; then
104-
if $cmd --no-default-features; then
105+
# shellcheck disable=SC2086
106+
if $cmd --no-default-features -- $test_flags; then
105107
passed=$((passed+1))
106108
continue
107109
fi
108110
elif [ "$passed" = "1" ]; then
109-
if $cmd; then
111+
# shellcheck disable=SC2086
112+
if $cmd -- $test_flags; then
110113
passed=$((passed+1))
111114
continue
112115
fi
113116
elif [ "$passed" = "2" ]; then
114-
if $cmd --features extra_traits; then
117+
# shellcheck disable=SC2086
118+
if $cmd --features extra_traits -- $test_flags; then
115119
break
116120
fi
117121
fi
118122
n=$((n+1))
119123
sleep 1
120124
done
121125
else
122-
$cmd --no-default-features
123-
$cmd
124-
$cmd --features extra_traits
126+
# shellcheck disable=SC2086
127+
$cmd --no-default-features -- $test_flags
128+
# shellcheck disable=SC2086
129+
$cmd -- $test_flags
130+
# shellcheck disable=SC2086
131+
$cmd --features extra_traits -- $test_flags
125132
fi

‎ci/runtest-android.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::env;
2-
use std::process::Command;
32
use std::path::{Path, PathBuf};
3+
use std::process::Command;
44

55
fn main() {
66
let args = env::args_os()
77
.skip(1)
8-
.filter(|arg| arg != "--quiet")
8+
.filter(|arg| arg != "--quiet" && arg != "--skip" && arg != "check_style")
99
.collect::<Vec<_>>();
1010
assert_eq!(args.len(), 1);
1111
let test = PathBuf::from(&args[0]);
@@ -36,14 +36,16 @@ fn main() {
3636
let stdout = String::from_utf8_lossy(&output.stdout);
3737
let stderr = String::from_utf8_lossy(&output.stderr);
3838

39-
println!("status: {}\nstdout ---\n{}\nstderr ---\n{}",
40-
output.status,
41-
stdout,
42-
stderr);
39+
println!(
40+
"status: {}\nstdout ---\n{}\nstderr ---\n{}",
41+
output.status, stdout, stderr
42+
);
4343

44-
if !stderr.lines().any(|l| (l.starts_with("PASSED ") && l.contains(" tests")) || l.starts_with("test result: ok"))
45-
&& !stdout.lines().any(|l| (l.starts_with("PASSED ") && l.contains(" tests")) || l.starts_with("test result: ok"))
46-
{
44+
if !stderr.lines().any(|l| {
45+
(l.starts_with("PASSED ") && l.contains(" tests")) || l.starts_with("test result: ok")
46+
}) && !stdout.lines().any(|l| {
47+
(l.starts_with("PASSED ") && l.contains(" tests")) || l.starts_with("test result: ok")
48+
}) {
4749
panic!("failed to find successful test run");
4850
};
4951
}

‎ci/style.rs

-213
This file was deleted.

‎ci/style.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if [ -n "${CI:-}" ]; then
99
check="--check"
1010
fi
1111

12-
rustc ci/style.rs && ./style src
12+
cargo test --manifest-path libc-test/Cargo.toml --test style -- --nocapture
1313

1414
command -v rustfmt
1515
rustfmt -V

‎libc-test/Cargo.toml

+16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ A test crate for the libc crate.
1515
[dependencies]
1616
libc = { path = "..", version = "1.0.0-alpha.1", default-features = false }
1717

18+
[dev-dependencies]
19+
syn = { version = "2.0.91", features = ["full", "visit"] }
20+
proc-macro2 = { version = "1.0.92", features = ["span-locations"] }
21+
glob = "0.3.2"
22+
annotate-snippets = { version = "0.11.5", features = ["testing-colors"] }
23+
1824
[build-dependencies]
1925
cc = "1.0.83"
2026
# FIXME: Use fork ctest until the maintainer gets back.
@@ -90,3 +96,13 @@ harness = false
9096
name = "primitive_types"
9197
path = "test/primitive_types.rs"
9298
harness = true
99+
100+
[[test]]
101+
name = "style"
102+
path = "test/check_style.rs"
103+
harness = true
104+
105+
[[test]]
106+
name = "style_tests"
107+
path = "test/style_tests.rs"
108+
harness = true

‎libc-test/test/check_style.rs

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//! Simple script to verify the coding style of this library.
2+
//!
3+
//! ## How to run
4+
//!
5+
//! The first argument to this script is the directory to run on, so running
6+
//! this script should be as simple as:
7+
//!
8+
//! ```notrust
9+
//! cargo test --test style
10+
//! ```
11+
12+
pub mod style;
13+
14+
use std::env;
15+
use std::path::Path;
16+
17+
use style::{Result, StyleChecker};
18+
19+
#[test]
20+
fn check_style() {
21+
let root_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../src");
22+
walk(&root_dir).unwrap();
23+
eprintln!("good style!");
24+
}
25+
26+
fn walk(root_dir: &Path) -> Result<()> {
27+
let mut style_checker = StyleChecker::new();
28+
29+
for entry in glob::glob(&format!(
30+
"{}/**/*.rs",
31+
root_dir.to_str().expect("dir should be valid UTF-8")
32+
))? {
33+
let entry = entry?;
34+
35+
let name = entry
36+
.file_name()
37+
.expect("file name should not end in ..")
38+
.to_str()
39+
.expect("file name should be valid UTF-8");
40+
if let "lib.rs" | "macros.rs" = &name[..] {
41+
continue;
42+
}
43+
44+
let path = entry.as_path();
45+
style_checker.check_file(path)?;
46+
style_checker.reset_state();
47+
}
48+
49+
style_checker.finalize()
50+
}

‎libc-test/test/style/mod.rs

+490
Large diffs are not rendered by default.

‎libc-test/test/style_tests.rs

+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
//! Verifies the implementation of the style checker in [style].
2+
3+
use style::StyleChecker;
4+
5+
pub mod style;
6+
7+
#[test]
8+
fn check_style_accept_correct_module_layout() {
9+
let contents = r#"
10+
use core::mem::size_of;
11+
pub type foo_t = u32;
12+
struct Foo {}
13+
pub const FOO: u32 = 0x20000;
14+
f! {}
15+
extern "C" {}
16+
mod foolib;
17+
pub use self::foolib::*;
18+
"#
19+
.to_string();
20+
21+
let mut checker = StyleChecker::new();
22+
checker.check_string(contents).unwrap();
23+
checker.finalize().unwrap();
24+
}
25+
26+
#[test]
27+
fn check_style_reject_incorrect_module_layout() {
28+
let contents = r#"
29+
use core::mem::size_of;
30+
pub type foo_t = u32;
31+
struct Foo {}
32+
pub const FOO: u32 = 0x20000;
33+
extern "C" {}
34+
f! {}
35+
mod foolib;
36+
pub use self::foolib::*;
37+
"#
38+
.to_string();
39+
40+
let mut checker = StyleChecker::new();
41+
checker.check_string(contents).unwrap();
42+
assert!(checker.finalize().is_err());
43+
}
44+
45+
#[test]
46+
fn check_style_reject_incorrect_cfg_if_layout() {
47+
let contents = r#"
48+
cfg_if! {
49+
if #[cfg(foo)] {
50+
pub type foo_t = u32;
51+
use core::mem::size_of;
52+
}
53+
}
54+
"#
55+
.to_string();
56+
57+
let mut checker = StyleChecker::new();
58+
checker.check_string(contents).unwrap();
59+
assert!(checker.finalize().is_err());
60+
}
61+
62+
#[test]
63+
fn check_style_accept_cfg_if_branch_resets_state() {
64+
let contents = r#"
65+
cfg_if! {
66+
if #[cfg(foo)] {
67+
use core::mem::size_of;
68+
pub type foo_t = u32;
69+
} else {
70+
use core::mem::align_of;
71+
}
72+
}
73+
"#
74+
.to_string();
75+
76+
let mut checker = StyleChecker::new();
77+
checker.check_string(contents).unwrap();
78+
checker.finalize().unwrap();
79+
}
80+
81+
#[test]
82+
fn check_style_reject_multiple_f_macros() {
83+
let contents = r#"
84+
f! {}
85+
f! {}
86+
"#
87+
.to_string();
88+
89+
let mut checker = StyleChecker::new();
90+
checker.check_string(contents).unwrap();
91+
assert!(checker.finalize().is_err());
92+
}
93+
94+
#[test]
95+
fn check_style_accept_cfg_ignore_target_endian_nested() {
96+
let contents = r#"
97+
pub struct Foo {
98+
#[cfg(target_endian = "little")]
99+
pub id: __u16,
100+
}
101+
"#
102+
.to_string();
103+
104+
let mut checker = StyleChecker::new();
105+
checker.check_string(contents).unwrap();
106+
checker.finalize().unwrap();
107+
}
108+
109+
#[test]
110+
fn check_style_reject_manual_copy() {
111+
let contents = r#"
112+
#[derive(Copy)]
113+
pub struct Foo {}
114+
"#
115+
.to_string();
116+
117+
let mut checker = StyleChecker::new();
118+
checker.check_string(contents).unwrap();
119+
assert!(checker.finalize().is_err());
120+
}
121+
122+
#[test]
123+
fn check_style_reject_manual_clone() {
124+
let contents = r#"
125+
#[derive(Clone)]
126+
pub struct Foo {}
127+
"#
128+
.to_string();
129+
130+
let mut checker = StyleChecker::new();
131+
checker.check_string(contents).unwrap();
132+
assert!(checker.finalize().is_err());
133+
}
134+
135+
#[test]
136+
fn check_style_accept_multiple_s_macros_with_disjoint_cfg() {
137+
let contents = r#"
138+
// Main `s!`
139+
s! {}
140+
141+
// These are not supported on a single arch. It doesn't make sense to
142+
// duplicate `foo` into every single file except one, so allow this here.
143+
#[cfg(not(target_arch = "foo"))]
144+
s! { pub struct foo { /* ... */ } }
145+
146+
// Similar to the above, no problems here
147+
#[cfg(not(target_os = "illumos"))]
148+
s! { pub struct bar { /* ... */ } }
149+
"#
150+
.to_string();
151+
152+
let mut checker = StyleChecker::new();
153+
checker.check_string(contents).unwrap();
154+
checker.finalize().unwrap();
155+
}
156+
157+
#[test]
158+
fn check_style_reject_duplicated_s_macro() {
159+
let contents = r#"
160+
s! {}
161+
s! {}
162+
"#
163+
.to_string();
164+
165+
let mut checker = StyleChecker::new();
166+
checker.check_string(contents).unwrap();
167+
assert!(checker.finalize().is_err());
168+
}
169+
170+
#[test]
171+
fn check_style_reject_duplicated_s_macro_cfg() {
172+
let contents = r#"
173+
#[cfg(not(target_arch = "foo"))]
174+
s! {}
175+
176+
#[cfg(not(target_arch = "foo"))]
177+
s! {}
178+
"#
179+
.to_string();
180+
181+
let mut checker = StyleChecker::new();
182+
checker.check_string(contents).unwrap();
183+
assert!(checker.finalize().is_err());
184+
}
185+
186+
#[test]
187+
fn check_style_reject_single_positive_s_macro_cfg() {
188+
let contents = r#"
189+
// A positive (no `not`) config: reject because this should go into
190+
// the relevant file.
191+
#[cfg(target_arch = "foo")]
192+
s! { pub struct foo { /* ... */ } }
193+
"#
194+
.to_string();
195+
196+
let mut checker = StyleChecker::new();
197+
checker.check_string(contents).unwrap();
198+
assert!(checker.finalize().is_err());
199+
}
200+
201+
#[test]
202+
fn check_style_reject_single_positive_s_macro_cfg_target_os() {
203+
let contents = r#"
204+
// A positive (no `not`) config: reject because this should go into
205+
// the relevant file.
206+
#[cfg(target_os = "foo")]
207+
s! { pub struct foo { /* ... */ } }
208+
"#
209+
.to_string();
210+
211+
let mut checker = StyleChecker::new();
212+
checker.check_string(contents).unwrap();
213+
assert!(checker.finalize().is_err());
214+
}
215+
216+
#[test]
217+
fn check_style_accept_positive_s_macro_any() {
218+
let contents = r#"
219+
// It's nicer to accept this so that we don't have to duplicate the same struct 3 times.
220+
#[cfg(any(target_arch = "foo", target_arch = "bar", target_arch = "baz"))]
221+
s! { pub struct foo { /* ... */ } }
222+
"#
223+
.to_string();
224+
225+
let mut checker = StyleChecker::new();
226+
checker.check_string(contents).unwrap();
227+
checker.finalize().unwrap();
228+
}
229+
230+
#[test]
231+
fn check_style_accept_positive_s_macro_all() {
232+
let contents = r#"
233+
#[cfg(all(target_arch = "foo", target_arch = "bar", target_arch = "baz"))]
234+
s! { pub struct foo { /* ... */ } }
235+
"#
236+
.to_string();
237+
238+
let mut checker = StyleChecker::new();
239+
checker.check_string(contents).unwrap();
240+
checker.finalize().unwrap();
241+
}
242+
243+
#[test]
244+
fn check_style_reject_duplicated_cfg_and_cfg_if() {
245+
let contents = r#"
246+
#[cfg(not(target_arch = "foo"))]
247+
s! { pub struct foo { /* ... */ } }
248+
249+
cfg_if! {
250+
if #[cfg(not(target_arch = "foo"))] {
251+
s!{ pub struct bar {} }
252+
}
253+
}
254+
"#
255+
.to_string();
256+
257+
let mut checker = StyleChecker::new();
258+
checker.check_string(contents).unwrap();
259+
assert!(checker.finalize().is_err());
260+
}

‎src/teeos/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ pub type c_long = i64;
5151

5252
pub type c_ulong = u64;
5353

54-
#[repr(align(16))]
55-
pub struct _CLongDouble(pub u128);
56-
5754
// long double in C means A float point value, which has 128bit length.
5855
// but some bit maybe not used, so the real length of long double could be 80(x86) or 128(power pc/IEEE)
5956
// this is different from f128(not stable and not included default) in Rust, so we use u128 for FFI(Rust to C).
@@ -88,6 +85,9 @@ pub type wctype_t = c_ulong;
8885

8986
pub type cmpfunc = extern "C" fn(x: *const c_void, y: *const c_void) -> c_int;
9087

88+
#[repr(align(16))]
89+
pub struct _CLongDouble(pub u128);
90+
9191
#[repr(align(8))]
9292
#[repr(C)]
9393
pub struct pthread_cond_t {

‎src/unix/linux_like/linux/mod.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -2214,18 +2214,6 @@ cfg_if! {
22142214
}
22152215
}
22162216

2217-
cfg_if! {
2218-
if #[cfg(all(
2219-
any(target_env = "gnu", target_env = "musl", target_env = "ohos"),
2220-
any(target_arch = "x86_64", target_arch = "x86")
2221-
))] {
2222-
extern "C" {
2223-
pub fn iopl(level: c_int) -> c_int;
2224-
pub fn ioperm(from: c_ulong, num: c_ulong, turn_on: c_int) -> c_int;
2225-
}
2226-
}
2227-
}
2228-
22292217
cfg_if! {
22302218
if #[cfg(any(
22312219
target_env = "gnu",
@@ -6088,6 +6076,18 @@ safe_f! {
60886076
}
60896077
}
60906078

6079+
cfg_if! {
6080+
if #[cfg(all(
6081+
any(target_env = "gnu", target_env = "musl", target_env = "ohos"),
6082+
any(target_arch = "x86_64", target_arch = "x86")
6083+
))] {
6084+
extern "C" {
6085+
pub fn iopl(level: c_int) -> c_int;
6086+
pub fn ioperm(from: c_ulong, num: c_ulong, turn_on: c_int) -> c_int;
6087+
}
6088+
}
6089+
}
6090+
60916091
cfg_if! {
60926092
if #[cfg(all(not(target_env = "uclibc"), not(target_env = "ohos")))] {
60936093
extern "C" {

‎src/unix/linux_like/linux/uclibc/x86_64/l4re.rs

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ s! {
2828
}
2929
}
3030

31-
#[cfg(target_os = "l4re")]
3231
#[allow(missing_debug_implementations)]
3332
pub struct pthread_attr_t {
3433
pub __detachstate: c_int,

‎src/wasi/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub type nfds_t = c_ulong;
4444
pub type wchar_t = i32;
4545
pub type nl_item = c_int;
4646
pub type __wasi_rights_t = u64;
47+
pub type locale_t = *mut __locale_struct;
4748

4849
s_no_extra_traits! {
4950
#[repr(align(16))]
@@ -63,8 +64,6 @@ pub enum DIR {}
6364
#[cfg_attr(feature = "extra_traits", derive(Debug))]
6465
pub enum __locale_struct {}
6566

66-
pub type locale_t = *mut __locale_struct;
67-
6867
s_paren! {
6968
// in wasi-libc clockid_t is const struct __clockid* (where __clockid is an opaque struct),
7069
// but that's an implementation detail that we don't want to have to deal with

0 commit comments

Comments
 (0)
Please sign in to comment.