rust: macros: take string literals in module!
Instead of taking binary string literals, take string ones instead, making it easier for users to define a module, i.e. instead of calling `module!` like: module! { ... name: b"rust_minimal", ... } now it is called as: module! { ... name: "rust_minimal", ... } Module names, aliases and license strings are restricted to ASCII only. However, the author and the description allows UTF-8. For simplicity (avoid parsing), escape sequences and raw string literals are not yet handled. Link: https://github.com/Rust-for-Linux/linux/issues/252 Link: https://lore.kernel.org/lkml/YukvvPOOu8uZl7+n@yadro.com/ Signed-off-by: Gary Guo <gary@garyguo.net> [Reworded, adapted for upstream and applied latest changes] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
b44becc5ee
commit
b13c9880f9
@ -18,10 +18,16 @@ pub(crate) fn try_literal(it: &mut token_stream::IntoIter) -> Option<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn try_byte_string(it: &mut token_stream::IntoIter) -> Option<String> {
|
pub(crate) fn try_string(it: &mut token_stream::IntoIter) -> Option<String> {
|
||||||
try_literal(it).and_then(|byte_string| {
|
try_literal(it).and_then(|string| {
|
||||||
if byte_string.starts_with("b\"") && byte_string.ends_with('\"') {
|
if string.starts_with('\"') && string.ends_with('\"') {
|
||||||
Some(byte_string[2..byte_string.len() - 1].to_string())
|
let content = &string[1..string.len() - 1];
|
||||||
|
if content.contains('\\') {
|
||||||
|
panic!("Escape sequences in string literals not yet handled");
|
||||||
|
}
|
||||||
|
Some(content.to_string())
|
||||||
|
} else if string.starts_with("r\"") {
|
||||||
|
panic!("Raw string literals are not yet handled");
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -40,8 +46,14 @@ pub(crate) fn expect_punct(it: &mut token_stream::IntoIter) -> char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn expect_byte_string(it: &mut token_stream::IntoIter) -> String {
|
pub(crate) fn expect_string(it: &mut token_stream::IntoIter) -> String {
|
||||||
try_byte_string(it).expect("Expected byte string")
|
try_string(it).expect("Expected string")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn expect_string_ascii(it: &mut token_stream::IntoIter) -> String {
|
||||||
|
let string = try_string(it).expect("Expected string");
|
||||||
|
assert!(string.is_ascii(), "Expected ASCII string");
|
||||||
|
string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
|
pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
|
||||||
|
@ -25,20 +25,20 @@ use proc_macro::TokenStream;
|
|||||||
///
|
///
|
||||||
/// module!{
|
/// module!{
|
||||||
/// type: MyModule,
|
/// type: MyModule,
|
||||||
/// name: b"my_kernel_module",
|
/// name: "my_kernel_module",
|
||||||
/// author: b"Rust for Linux Contributors",
|
/// author: "Rust for Linux Contributors",
|
||||||
/// description: b"My very own kernel module!",
|
/// description: "My very own kernel module!",
|
||||||
/// license: b"GPL",
|
/// license: "GPL",
|
||||||
/// params: {
|
/// params: {
|
||||||
/// my_i32: i32 {
|
/// my_i32: i32 {
|
||||||
/// default: 42,
|
/// default: 42,
|
||||||
/// permissions: 0o000,
|
/// permissions: 0o000,
|
||||||
/// description: b"Example of i32",
|
/// description: "Example of i32",
|
||||||
/// },
|
/// },
|
||||||
/// writeable_i32: i32 {
|
/// writeable_i32: i32 {
|
||||||
/// default: 42,
|
/// default: 42,
|
||||||
/// permissions: 0o644,
|
/// permissions: 0o644,
|
||||||
/// description: b"Example of i32",
|
/// description: "Example of i32",
|
||||||
/// },
|
/// },
|
||||||
/// },
|
/// },
|
||||||
/// }
|
/// }
|
||||||
|
@ -108,11 +108,11 @@ impl ModuleInfo {
|
|||||||
|
|
||||||
match key.as_str() {
|
match key.as_str() {
|
||||||
"type" => info.type_ = expect_ident(it),
|
"type" => info.type_ = expect_ident(it),
|
||||||
"name" => info.name = expect_byte_string(it),
|
"name" => info.name = expect_string_ascii(it),
|
||||||
"author" => info.author = Some(expect_byte_string(it)),
|
"author" => info.author = Some(expect_string(it)),
|
||||||
"description" => info.description = Some(expect_byte_string(it)),
|
"description" => info.description = Some(expect_string(it)),
|
||||||
"license" => info.license = expect_byte_string(it),
|
"license" => info.license = expect_string_ascii(it),
|
||||||
"alias" => info.alias = Some(expect_byte_string(it)),
|
"alias" => info.alias = Some(expect_string_ascii(it)),
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"Unknown key \"{}\". Valid keys are: {:?}.",
|
"Unknown key \"{}\". Valid keys are: {:?}.",
|
||||||
key, EXPECTED_KEYS
|
key, EXPECTED_KEYS
|
||||||
|
@ -6,10 +6,10 @@ use kernel::prelude::*;
|
|||||||
|
|
||||||
module! {
|
module! {
|
||||||
type: RustMinimal,
|
type: RustMinimal,
|
||||||
name: b"rust_minimal",
|
name: "rust_minimal",
|
||||||
author: b"Rust for Linux Contributors",
|
author: "Rust for Linux Contributors",
|
||||||
description: b"Rust minimal sample",
|
description: "Rust minimal sample",
|
||||||
license: b"GPL",
|
license: "GPL",
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RustMinimal {
|
struct RustMinimal {
|
||||||
|
@ -7,10 +7,10 @@ use kernel::prelude::*;
|
|||||||
|
|
||||||
module! {
|
module! {
|
||||||
type: RustPrint,
|
type: RustPrint,
|
||||||
name: b"rust_print",
|
name: "rust_print",
|
||||||
author: b"Rust for Linux Contributors",
|
author: "Rust for Linux Contributors",
|
||||||
description: b"Rust printing macros sample",
|
description: "Rust printing macros sample",
|
||||||
license: b"GPL",
|
license: "GPL",
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RustPrint;
|
struct RustPrint;
|
||||||
|
Loading…
Reference in New Issue
Block a user