Skip to content

Commit 39867fe

Browse files
asahilinaojeda
authored andcommitted
rust: macros: Allow specifying multiple module aliases
Modules can (and usually do) have multiple alias tags, in order to specify multiple possible device matches for autoloading. Allow this by changing the alias ModuleInfo field to an Option<Vec<String>>. Note: For normal device IDs this is autogenerated by modpost (which is not properly integrated with Rust support yet), so it is useful to be able to manually add device match aliases for now, and should still be useful in the future for corner cases that modpost does not handle. This pulls in the expect_group() helper from the rfl/rust branch (with credit to authors). Co-developed-by: Miguel Ojeda <[email protected]> Signed-off-by: Miguel Ojeda <[email protected]> Co-developed-by: Finn Behrens <[email protected]> Signed-off-by: Finn Behrens <[email protected]> Co-developed-by: Sumera Priyadarsini <[email protected]> Signed-off-by: Sumera Priyadarsini <[email protected]> Reviewed-by: Vincenzo Palazzo <[email protected]> Signed-off-by: Asahi Lina <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 318c3cc commit 39867fe

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

rust/macros/helpers.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0
22

3-
use proc_macro::{token_stream, TokenTree};
3+
use proc_macro::{token_stream, Group, TokenTree};
44

55
pub(crate) fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
66
if let Some(TokenTree::Ident(ident)) = it.next() {
@@ -56,6 +56,14 @@ pub(crate) fn expect_string_ascii(it: &mut token_stream::IntoIter) -> String {
5656
string
5757
}
5858

59+
pub(crate) fn expect_group(it: &mut token_stream::IntoIter) -> Group {
60+
if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") {
61+
group
62+
} else {
63+
panic!("Expected Group");
64+
}
65+
}
66+
5967
pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
6068
if it.next().is_some() {
6169
panic!("Expected end");

rust/macros/module.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
use crate::helpers::*;
4-
use proc_macro::{token_stream, Literal, TokenStream, TokenTree};
4+
use proc_macro::{token_stream, Delimiter, Literal, TokenStream, TokenTree};
55
use std::fmt::Write;
66

7+
fn expect_string_array(it: &mut token_stream::IntoIter) -> Vec<String> {
8+
let group = expect_group(it);
9+
assert_eq!(group.delimiter(), Delimiter::Bracket);
10+
let mut values = Vec::new();
11+
let mut it = group.stream().into_iter();
12+
13+
while let Some(val) = try_string(&mut it) {
14+
assert!(val.is_ascii(), "Expected ASCII string");
15+
values.push(val);
16+
match it.next() {
17+
Some(TokenTree::Punct(punct)) => assert_eq!(punct.as_char(), ','),
18+
None => break,
19+
_ => panic!("Expected ',' or end of array"),
20+
}
21+
}
22+
values
23+
}
24+
725
struct ModInfoBuilder<'a> {
826
module: &'a str,
927
counter: usize,
@@ -78,7 +96,7 @@ struct ModuleInfo {
7896
name: String,
7997
author: Option<String>,
8098
description: Option<String>,
81-
alias: Option<String>,
99+
alias: Option<Vec<String>>,
82100
}
83101

84102
impl ModuleInfo {
@@ -112,7 +130,7 @@ impl ModuleInfo {
112130
"author" => info.author = Some(expect_string(it)),
113131
"description" => info.description = Some(expect_string(it)),
114132
"license" => info.license = expect_string_ascii(it),
115-
"alias" => info.alias = Some(expect_string_ascii(it)),
133+
"alias" => info.alias = Some(expect_string_array(it)),
116134
_ => panic!(
117135
"Unknown key \"{}\". Valid keys are: {:?}.",
118136
key, EXPECTED_KEYS
@@ -163,8 +181,10 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
163181
modinfo.emit("description", &description);
164182
}
165183
modinfo.emit("license", &info.license);
166-
if let Some(alias) = info.alias {
167-
modinfo.emit("alias", &alias);
184+
if let Some(aliases) = info.alias {
185+
for alias in aliases {
186+
modinfo.emit("alias", &alias);
187+
}
168188
}
169189

170190
// Built-in modules also export the `file` modinfo string.

0 commit comments

Comments
 (0)