Skip to content

Commit

Permalink
rust: macros: take string literals in module!
Browse files Browse the repository at this point in the history
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: Rust-for-Linux#252
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Gary Guo <[email protected]>
[Reworded, adapted for upstream and applied latest changes]
Signed-off-by: Miguel Ojeda <[email protected]>
  • Loading branch information
nbdd0121 authored and ojeda committed Dec 4, 2022
1 parent b44becc commit b13c988
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 25 deletions.
24 changes: 18 additions & 6 deletions rust/macros/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
try_literal(it).and_then(|byte_string| {
if byte_string.starts_with("b\"") && byte_string.ends_with('\"') {
Some(byte_string[2..byte_string.len() - 1].to_string())
pub(crate) fn try_string(it: &mut token_stream::IntoIter) -> Option<String> {
try_literal(it).and_then(|string| {
if string.starts_with('\"') && string.ends_with('\"') {
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 {
None
}
Expand All @@ -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 {
try_byte_string(it).expect("Expected byte string")
pub(crate) fn expect_string(it: &mut token_stream::IntoIter) -> 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) {
Expand Down
12 changes: 6 additions & 6 deletions rust/macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ use proc_macro::TokenStream;
///
/// module!{
/// type: MyModule,
/// name: b"my_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own kernel module!",
/// license: b"GPL",
/// name: "my_kernel_module",
/// author: "Rust for Linux Contributors",
/// description: "My very own kernel module!",
/// license: "GPL",
/// params: {
/// my_i32: i32 {
/// default: 42,
/// permissions: 0o000,
/// description: b"Example of i32",
/// description: "Example of i32",
/// },
/// writeable_i32: i32 {
/// default: 42,
/// permissions: 0o644,
/// description: b"Example of i32",
/// description: "Example of i32",
/// },
/// },
/// }
Expand Down
10 changes: 5 additions & 5 deletions rust/macros/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ impl ModuleInfo {

match key.as_str() {
"type" => info.type_ = expect_ident(it),
"name" => info.name = expect_byte_string(it),
"author" => info.author = Some(expect_byte_string(it)),
"description" => info.description = Some(expect_byte_string(it)),
"license" => info.license = expect_byte_string(it),
"alias" => info.alias = Some(expect_byte_string(it)),
"name" => info.name = expect_string_ascii(it),
"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)),
_ => panic!(
"Unknown key \"{}\". Valid keys are: {:?}.",
key, EXPECTED_KEYS
Expand Down
8 changes: 4 additions & 4 deletions samples/rust/rust_minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use kernel::prelude::*;

module! {
type: RustMinimal,
name: b"rust_minimal",
author: b"Rust for Linux Contributors",
description: b"Rust minimal sample",
license: b"GPL",
name: "rust_minimal",
author: "Rust for Linux Contributors",
description: "Rust minimal sample",
license: "GPL",
}

struct RustMinimal {
Expand Down
8 changes: 4 additions & 4 deletions samples/rust/rust_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use kernel::prelude::*;

module! {
type: RustPrint,
name: b"rust_print",
author: b"Rust for Linux Contributors",
description: b"Rust printing macros sample",
license: b"GPL",
name: "rust_print",
author: "Rust for Linux Contributors",
description: "Rust printing macros sample",
license: "GPL",
}

struct RustPrint;
Expand Down

0 comments on commit b13c988

Please sign in to comment.