summaryrefslogtreecommitdiffstats
path: root/rust/macros
diff options
context:
space:
mode:
authorAsahi Lina <lina@asahilina.net>2023-03-23 21:35:10 +0900
committerMiguel Ojeda <ojeda@kernel.org>2023-04-10 23:55:43 +0200
commit39867fec2855cf37e5542dc6a972bce8ee191a9c (patch)
treeaee40218f3005238c7a9eb71de95ff307b95e4b9 /rust/macros
parent318c3cc8e107c2b36108132057ca90d0d56d1bd9 (diff)
downloadlinux-stable-39867fec2855cf37e5542dc6a972bce8ee191a9c.tar.gz
linux-stable-39867fec2855cf37e5542dc6a972bce8ee191a9c.tar.bz2
linux-stable-39867fec2855cf37e5542dc6a972bce8ee191a9c.zip
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 <ojeda@kernel.org> Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Co-developed-by: Finn Behrens <me@kloenk.dev> Signed-off-by: Finn Behrens <me@kloenk.dev> Co-developed-by: Sumera Priyadarsini <sylphrenadin@gmail.com> Signed-off-by: Sumera Priyadarsini <sylphrenadin@gmail.com> Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Signed-off-by: Asahi Lina <lina@asahilina.net> Link: https://lore.kernel.org/r/20230224-rust-macros-v2-1-7396e8b7018d@asahilina.net Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/macros')
-rw-r--r--rust/macros/helpers.rs10
-rw-r--r--rust/macros/module.rs30
2 files changed, 34 insertions, 6 deletions
diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs
index cf7ad950dc1e..b2bdd4d8c958 100644
--- a/rust/macros/helpers.rs
+++ b/rust/macros/helpers.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
-use proc_macro::{token_stream, TokenTree};
+use proc_macro::{token_stream, Group, TokenTree};
pub(crate) fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
if let Some(TokenTree::Ident(ident)) = it.next() {
@@ -56,6 +56,14 @@ pub(crate) fn expect_string_ascii(it: &mut token_stream::IntoIter) -> String {
string
}
+pub(crate) fn expect_group(it: &mut token_stream::IntoIter) -> Group {
+ if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") {
+ group
+ } else {
+ panic!("Expected Group");
+ }
+}
+
pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
if it.next().is_some() {
panic!("Expected end");
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index a7e363c2b044..5e7ab83908a0 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -1,9 +1,27 @@
// SPDX-License-Identifier: GPL-2.0
use crate::helpers::*;
-use proc_macro::{token_stream, Literal, TokenStream, TokenTree};
+use proc_macro::{token_stream, Delimiter, Literal, TokenStream, TokenTree};
use std::fmt::Write;
+fn expect_string_array(it: &mut token_stream::IntoIter) -> Vec<String> {
+ let group = expect_group(it);
+ assert_eq!(group.delimiter(), Delimiter::Bracket);
+ let mut values = Vec::new();
+ let mut it = group.stream().into_iter();
+
+ while let Some(val) = try_string(&mut it) {
+ assert!(val.is_ascii(), "Expected ASCII string");
+ values.push(val);
+ match it.next() {
+ Some(TokenTree::Punct(punct)) => assert_eq!(punct.as_char(), ','),
+ None => break,
+ _ => panic!("Expected ',' or end of array"),
+ }
+ }
+ values
+}
+
struct ModInfoBuilder<'a> {
module: &'a str,
counter: usize,
@@ -78,7 +96,7 @@ struct ModuleInfo {
name: String,
author: Option<String>,
description: Option<String>,
- alias: Option<String>,
+ alias: Option<Vec<String>>,
}
impl ModuleInfo {
@@ -112,7 +130,7 @@ impl ModuleInfo {
"author" => info.author = Some(expect_string(it)),
"description" => info.description = Some(expect_string(it)),
"license" => info.license = expect_string_ascii(it),
- "alias" => info.alias = Some(expect_string_ascii(it)),
+ "alias" => info.alias = Some(expect_string_array(it)),
_ => panic!(
"Unknown key \"{}\". Valid keys are: {:?}.",
key, EXPECTED_KEYS
@@ -163,8 +181,10 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
modinfo.emit("description", &description);
}
modinfo.emit("license", &info.license);
- if let Some(alias) = info.alias {
- modinfo.emit("alias", &alias);
+ if let Some(aliases) = info.alias {
+ for alias in aliases {
+ modinfo.emit("alias", &alias);
+ }
}
// Built-in modules also export the `file` modinfo string.