Skip to content

Commit 262e1cd

Browse files
committed
Move macro helpers into helpers submodule
Signed-off-by: Finn Behrens <[email protected]>
1 parent bc33ea8 commit 262e1cd

File tree

3 files changed

+158
-152
lines changed

3 files changed

+158
-152
lines changed

rust/macros/helpers.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
use proc_macro::{token_stream, Group, TokenTree};
4+
5+
pub(crate) fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
6+
if let Some(TokenTree::Ident(ident)) = it.next() {
7+
Some(ident.to_string())
8+
} else {
9+
None
10+
}
11+
}
12+
13+
pub(crate) fn try_literal(it: &mut token_stream::IntoIter) -> Option<String> {
14+
if let Some(TokenTree::Literal(literal)) = it.next() {
15+
Some(literal.to_string())
16+
} else {
17+
None
18+
}
19+
}
20+
21+
pub(crate) fn try_byte_string(it: &mut token_stream::IntoIter) -> Option<String> {
22+
try_literal(it).and_then(|byte_string| {
23+
if byte_string.starts_with("b\"") && byte_string.ends_with('\"') {
24+
Some(byte_string[2..byte_string.len() - 1].to_string())
25+
} else {
26+
None
27+
}
28+
})
29+
}
30+
31+
pub(crate) fn expect_ident(it: &mut token_stream::IntoIter) -> String {
32+
try_ident(it).expect("Expected Ident")
33+
}
34+
35+
pub(crate) fn expect_punct(it: &mut token_stream::IntoIter) -> char {
36+
if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") {
37+
punct.as_char()
38+
} else {
39+
panic!("Expected Punct");
40+
}
41+
}
42+
43+
pub(crate) fn expect_literal(it: &mut token_stream::IntoIter) -> String {
44+
try_literal(it).expect("Expected Literal")
45+
}
46+
47+
pub(crate) fn expect_group(it: &mut token_stream::IntoIter) -> Group {
48+
if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") {
49+
group
50+
} else {
51+
panic!("Expected Group");
52+
}
53+
}
54+
55+
pub(crate) fn expect_byte_string(it: &mut token_stream::IntoIter) -> String {
56+
try_byte_string(it).expect("Expected byte string")
57+
}
58+
59+
#[derive(Clone, PartialEq)]
60+
pub(crate) enum ParamType {
61+
Ident(String),
62+
Array { vals: String, max_length: usize },
63+
}
64+
65+
pub(crate) fn expect_array_fields(it: &mut token_stream::IntoIter) -> ParamType {
66+
assert_eq!(expect_punct(it), '<');
67+
let vals = expect_ident(it);
68+
assert_eq!(expect_punct(it), ',');
69+
let max_length_str = expect_literal(it);
70+
let max_length = max_length_str
71+
.parse::<usize>()
72+
.expect("Expected usize length");
73+
assert_eq!(expect_punct(it), '>');
74+
ParamType::Array { vals, max_length }
75+
}
76+
77+
pub(crate) fn expect_type(it: &mut token_stream::IntoIter) -> ParamType {
78+
if let TokenTree::Ident(ident) = it
79+
.next()
80+
.expect("Reached end of token stream for param type")
81+
{
82+
match ident.to_string().as_ref() {
83+
"ArrayParam" => expect_array_fields(it),
84+
_ => ParamType::Ident(ident.to_string()),
85+
}
86+
} else {
87+
panic!("Expected Param Type")
88+
}
89+
}
90+
91+
pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
92+
if it.next().is_some() {
93+
panic!("Expected end");
94+
}
95+
}
96+
97+
pub(crate) fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
98+
assert_eq!(expect_ident(it), expected_name);
99+
assert_eq!(expect_punct(it), ':');
100+
let literal = expect_literal(it);
101+
assert_eq!(expect_punct(it), ',');
102+
literal
103+
}
104+
105+
pub(crate) fn get_byte_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
106+
assert_eq!(expect_ident(it), expected_name);
107+
assert_eq!(expect_punct(it), ':');
108+
let byte_string = expect_byte_string(it);
109+
assert_eq!(expect_punct(it), ',');
110+
byte_string
111+
}
112+
113+
pub(crate) fn permissions_are_readonly(perms: &str) -> bool {
114+
let (radix, digits) = if let Some(n) = perms.strip_prefix("0x") {
115+
(16, n)
116+
} else if let Some(n) = perms.strip_prefix("0o") {
117+
(8, n)
118+
} else if let Some(n) = perms.strip_prefix("0b") {
119+
(2, n)
120+
} else {
121+
(10, perms)
122+
};
123+
match u32::from_str_radix(digits, radix) {
124+
Ok(perms) => perms & 0o222 == 0,
125+
Err(_) => false,
126+
}
127+
}
128+
129+
#[cfg(test)]
130+
mod tests {
131+
use super::*;
132+
133+
#[test]
134+
fn test_permissions_are_readonly() {
135+
assert!(permissions_are_readonly("0b000000000"));
136+
assert!(permissions_are_readonly("0o000"));
137+
assert!(permissions_are_readonly("000"));
138+
assert!(permissions_are_readonly("0x000"));
139+
140+
assert!(!permissions_are_readonly("0b111111111"));
141+
assert!(!permissions_are_readonly("0o777"));
142+
assert!(!permissions_are_readonly("511"));
143+
assert!(!permissions_are_readonly("0x1ff"));
144+
145+
assert!(permissions_are_readonly("0o014"));
146+
assert!(permissions_are_readonly("0o015"));
147+
148+
assert!(!permissions_are_readonly("0o214"));
149+
assert!(!permissions_are_readonly("0o024"));
150+
assert!(!permissions_are_readonly("0o012"));
151+
152+
assert!(!permissions_are_readonly("0o315"));
153+
assert!(!permissions_are_readonly("0o065"));
154+
assert!(!permissions_are_readonly("0o017"));
155+
}
156+
}

rust/macros/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
//! Crate for all kernel procedural macros.
44
5+
mod helpers;
56
mod module;
67

78
use proc_macro::TokenStream;

rust/macros/module.rs

Lines changed: 1 addition & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -2,113 +2,7 @@
22

33
use proc_macro::{token_stream, Delimiter, Group, Literal, TokenStream, TokenTree};
44

5-
fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
6-
if let Some(TokenTree::Ident(ident)) = it.next() {
7-
Some(ident.to_string())
8-
} else {
9-
None
10-
}
11-
}
12-
13-
fn try_literal(it: &mut token_stream::IntoIter) -> Option<String> {
14-
if let Some(TokenTree::Literal(literal)) = it.next() {
15-
Some(literal.to_string())
16-
} else {
17-
None
18-
}
19-
}
20-
21-
fn try_byte_string(it: &mut token_stream::IntoIter) -> Option<String> {
22-
try_literal(it).and_then(|byte_string| {
23-
if byte_string.starts_with("b\"") && byte_string.ends_with('\"') {
24-
Some(byte_string[2..byte_string.len() - 1].to_string())
25-
} else {
26-
None
27-
}
28-
})
29-
}
30-
31-
fn expect_ident(it: &mut token_stream::IntoIter) -> String {
32-
try_ident(it).expect("Expected Ident")
33-
}
34-
35-
fn expect_punct(it: &mut token_stream::IntoIter) -> char {
36-
if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") {
37-
punct.as_char()
38-
} else {
39-
panic!("Expected Punct");
40-
}
41-
}
42-
43-
fn expect_literal(it: &mut token_stream::IntoIter) -> String {
44-
try_literal(it).expect("Expected Literal")
45-
}
46-
47-
fn expect_group(it: &mut token_stream::IntoIter) -> Group {
48-
if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") {
49-
group
50-
} else {
51-
panic!("Expected Group");
52-
}
53-
}
54-
55-
fn expect_byte_string(it: &mut token_stream::IntoIter) -> String {
56-
try_byte_string(it).expect("Expected byte string")
57-
}
58-
59-
#[derive(Clone, PartialEq)]
60-
enum ParamType {
61-
Ident(String),
62-
Array { vals: String, max_length: usize },
63-
}
64-
65-
fn expect_array_fields(it: &mut token_stream::IntoIter) -> ParamType {
66-
assert_eq!(expect_punct(it), '<');
67-
let vals = expect_ident(it);
68-
assert_eq!(expect_punct(it), ',');
69-
let max_length_str = expect_literal(it);
70-
let max_length = max_length_str
71-
.parse::<usize>()
72-
.expect("Expected usize length");
73-
assert_eq!(expect_punct(it), '>');
74-
ParamType::Array { vals, max_length }
75-
}
76-
77-
fn expect_type(it: &mut token_stream::IntoIter) -> ParamType {
78-
if let TokenTree::Ident(ident) = it
79-
.next()
80-
.expect("Reached end of token stream for param type")
81-
{
82-
match ident.to_string().as_ref() {
83-
"ArrayParam" => expect_array_fields(it),
84-
_ => ParamType::Ident(ident.to_string()),
85-
}
86-
} else {
87-
panic!("Expected Param Type")
88-
}
89-
}
90-
91-
fn expect_end(it: &mut token_stream::IntoIter) {
92-
if it.next().is_some() {
93-
panic!("Expected end");
94-
}
95-
}
96-
97-
fn get_literal(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
98-
assert_eq!(expect_ident(it), expected_name);
99-
assert_eq!(expect_punct(it), ':');
100-
let literal = expect_literal(it);
101-
assert_eq!(expect_punct(it), ',');
102-
literal
103-
}
104-
105-
fn get_byte_string(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
106-
assert_eq!(expect_ident(it), expected_name);
107-
assert_eq!(expect_punct(it), ':');
108-
let byte_string = expect_byte_string(it);
109-
assert_eq!(expect_punct(it), ',');
110-
byte_string
111-
}
5+
use crate::helpers::*;
1126

1137
struct ModInfoBuilder<'a> {
1148
module: &'a str,
@@ -184,22 +78,6 @@ impl<'a> ModInfoBuilder<'a> {
18478
}
18579
}
18680

187-
fn permissions_are_readonly(perms: &str) -> bool {
188-
let (radix, digits) = if let Some(n) = perms.strip_prefix("0x") {
189-
(16, n)
190-
} else if let Some(n) = perms.strip_prefix("0o") {
191-
(8, n)
192-
} else if let Some(n) = perms.strip_prefix("0b") {
193-
(2, n)
194-
} else {
195-
(10, perms)
196-
};
197-
match u32::from_str_radix(digits, radix) {
198-
Ok(perms) => perms & 0o222 == 0,
199-
Err(_) => false,
200-
}
201-
}
202-
20381
fn param_ops_path(param_type: &str) -> &'static str {
20482
match param_type {
20583
"bool" => "kernel::module_param::PARAM_OPS_BOOL",
@@ -723,32 +601,3 @@ pub fn module_misc_device(ts: TokenStream) -> TokenStream {
723601
.parse()
724602
.expect("Error parsing formatted string into token stream.")
725603
}
726-
727-
#[cfg(test)]
728-
mod tests {
729-
use super::*;
730-
731-
#[test]
732-
fn test_permissions_are_readonly() {
733-
assert!(permissions_are_readonly("0b000000000"));
734-
assert!(permissions_are_readonly("0o000"));
735-
assert!(permissions_are_readonly("000"));
736-
assert!(permissions_are_readonly("0x000"));
737-
738-
assert!(!permissions_are_readonly("0b111111111"));
739-
assert!(!permissions_are_readonly("0o777"));
740-
assert!(!permissions_are_readonly("511"));
741-
assert!(!permissions_are_readonly("0x1ff"));
742-
743-
assert!(permissions_are_readonly("0o014"));
744-
assert!(permissions_are_readonly("0o015"));
745-
746-
assert!(!permissions_are_readonly("0o214"));
747-
assert!(!permissions_are_readonly("0o024"));
748-
assert!(!permissions_are_readonly("0o012"));
749-
750-
assert!(!permissions_are_readonly("0o315"));
751-
assert!(!permissions_are_readonly("0o065"));
752-
assert!(!permissions_are_readonly("0o017"));
753-
}
754-
}

0 commit comments

Comments
 (0)