Skip to content

Commit

Permalink
rust: macros: Allow specifying multiple module aliases
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Asahi Lina <lina@asahilina.net>
  • Loading branch information
asahilina authored and fbq committed Mar 6, 2023
1 parent f4338c6 commit 1ac0a3c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
10 changes: 9 additions & 1 deletion rust/macros/helpers.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0

use proc_macro::{token_stream, Punct, TokenTree};
use proc_macro::{token_stream, Group, Punct, TokenTree};

pub(crate) fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
if let Some(TokenTree::Ident(ident)) = it.next() {
Expand Down Expand Up @@ -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");
Expand Down
30 changes: 25 additions & 5 deletions 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,
Expand Down Expand Up @@ -78,7 +96,7 @@ struct ModuleInfo {
name: String,
author: Option<String>,
description: Option<String>,
alias: Option<String>,
alias: Option<Vec<String>>,
}

impl ModuleInfo {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 1ac0a3c

Please sign in to comment.