diff options
Diffstat (limited to 'rust/macros')
| -rw-r--r-- | rust/macros/lib.rs | 142 | ||||
| -rw-r--r-- | rust/macros/module.rs | 8 | ||||
| -rw-r--r-- | rust/macros/paste.rs | 15 | 
3 files changed, 118 insertions, 47 deletions
| diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs index a626b1145e5c..4ab94e44adfe 100644 --- a/rust/macros/lib.rs +++ b/rust/macros/lib.rs @@ -30,7 +30,7 @@ use proc_macro::TokenStream;  ///  /// # Examples  /// -/// ```ignore +/// ```  /// use kernel::prelude::*;  ///  /// module!{ @@ -42,22 +42,16 @@ use proc_macro::TokenStream;  ///     alias: ["alternate_module_name"],  /// }  /// -/// struct MyModule; +/// struct MyModule(i32);  ///  /// impl kernel::Module for MyModule { -///     fn init() -> Result<Self> { -///         // If the parameter is writeable, then the kparam lock must be -///         // taken to read the parameter: -///         { -///             let lock = THIS_MODULE.kernel_param_lock(); -///             pr_info!("i32 param is:  {}\n", writeable_i32.read(&lock)); -///         } -///         // If the parameter is read only, it can be read without locking -///         // the kernel parameters: -///         pr_info!("i32 param is:  {}\n", my_i32.read()); -///         Ok(Self) +///     fn init(_module: &'static ThisModule) -> Result<Self> { +///         let foo: i32 = 42; +///         pr_info!("I contain:  {}\n", foo); +///         Ok(Self(foo))  ///     }  /// } +/// # fn main() {}  /// ```  ///  /// ## Firmware @@ -69,7 +63,7 @@ use proc_macro::TokenStream;  /// build an initramfs uses this information to put the firmware files into  /// the initramfs image.  /// -/// ```ignore +/// ```  /// use kernel::prelude::*;  ///  /// module!{ @@ -84,10 +78,11 @@ use proc_macro::TokenStream;  /// struct MyDeviceDriverModule;  ///  /// impl kernel::Module for MyDeviceDriverModule { -///     fn init() -> Result<Self> { +///     fn init(_module: &'static ThisModule) -> Result<Self> {  ///         Ok(Self)  ///     }  /// } +/// # fn main() {}  /// ```  ///  /// # Supported argument types @@ -132,7 +127,7 @@ pub fn module(ts: TokenStream) -> TokenStream {  /// calls to this function at compile time:  ///  /// ```compile_fail -/// # use kernel::error::VTABLE_DEFAULT_ERROR; +/// # // Intentionally missing `use`s to simplify `rusttest`.  /// kernel::build_error(VTABLE_DEFAULT_ERROR)  /// ```  /// @@ -142,7 +137,7 @@ pub fn module(ts: TokenStream) -> TokenStream {  ///  /// # Examples  /// -/// ```ignore +/// ```  /// use kernel::error::VTABLE_DEFAULT_ERROR;  /// use kernel::prelude::*;  /// @@ -187,12 +182,27 @@ pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream {  ///  /// # Examples  /// -/// ```ignore -/// use kernel::macro::concat_idents; +/// ``` +/// # const binder_driver_return_protocol_BR_OK: u32 = 0; +/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1; +/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2; +/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3; +/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4; +/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5; +/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6; +/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7; +/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8; +/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9; +/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10; +/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11; +/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12; +/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13; +/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; +/// use kernel::macros::concat_idents;  ///  /// macro_rules! pub_no_prefix {  ///     ($prefix:ident, $($newname:ident),+) => { -///         $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+ +///         $(pub(crate) const $newname: u32 = concat_idents!($prefix, $newname);)+  ///     };  /// }  /// @@ -238,21 +248,35 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {  ///  /// # Examples  /// -/// ```rust,ignore +/// ``` +/// # #![feature(lint_reasons)] +/// # use kernel::prelude::*; +/// # use std::{sync::Mutex, process::Command}; +/// # use kernel::macros::pin_data;  /// #[pin_data]  /// struct DriverData {  ///     #[pin] -///     queue: Mutex<Vec<Command>>, -///     buf: Box<[u8; 1024 * 1024]>, +///     queue: Mutex<KVec<Command>>, +///     buf: KBox<[u8; 1024 * 1024]>,  /// }  /// ```  /// -/// ```rust,ignore +/// ``` +/// # #![feature(lint_reasons)] +/// # use kernel::prelude::*; +/// # use std::{sync::Mutex, process::Command}; +/// # use core::pin::Pin; +/// # pub struct Info; +/// # mod bindings { +/// #     pub unsafe fn destroy_info(_ptr: *mut super::Info) {} +/// # } +/// use kernel::macros::{pin_data, pinned_drop}; +///  /// #[pin_data(PinnedDrop)]  /// struct DriverData {  ///     #[pin] -///     queue: Mutex<Vec<Command>>, -///     buf: Box<[u8; 1024 * 1024]>, +///     queue: Mutex<KVec<Command>>, +///     buf: KBox<[u8; 1024 * 1024]>,  ///     raw_info: *mut Info,  /// }  /// @@ -262,6 +286,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {  ///         unsafe { bindings::destroy_info(self.raw_info) };  ///     }  /// } +/// # fn main() {}  /// ```  ///  /// [`pin_init!`]: ../kernel/macro.pin_init.html @@ -277,13 +302,22 @@ pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {  ///  /// # Examples  /// -/// ```rust,ignore +/// ``` +/// # #![feature(lint_reasons)] +/// # use kernel::prelude::*; +/// # use macros::{pin_data, pinned_drop}; +/// # use std::{sync::Mutex, process::Command}; +/// # use core::pin::Pin; +/// # mod bindings { +/// #     pub struct Info; +/// #     pub unsafe fn destroy_info(_ptr: *mut Info) {} +/// # }  /// #[pin_data(PinnedDrop)]  /// struct DriverData {  ///     #[pin] -///     queue: Mutex<Vec<Command>>, -///     buf: Box<[u8; 1024 * 1024]>, -///     raw_info: *mut Info, +///     queue: Mutex<KVec<Command>>, +///     buf: KBox<[u8; 1024 * 1024]>, +///     raw_info: *mut bindings::Info,  /// }  ///  /// #[pinned_drop] @@ -309,12 +343,25 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {  ///  /// # Example  /// -/// ```ignore -/// use kernel::macro::paste; -/// +/// ``` +/// # const binder_driver_return_protocol_BR_OK: u32 = 0; +/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1; +/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2; +/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3; +/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4; +/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5; +/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6; +/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7; +/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8; +/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9; +/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10; +/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11; +/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12; +/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13; +/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;  /// macro_rules! pub_no_prefix {  ///     ($prefix:ident, $($newname:ident),+) => { -///         paste! { +///         kernel::macros::paste! {  ///             $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+  ///         }  ///     }; @@ -353,13 +400,26 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {  /// * `lower`: change the identifier to lower case.  /// * `upper`: change the identifier to upper case.  /// -/// ```ignore -/// use kernel::macro::paste; -/// +/// ``` +/// # const binder_driver_return_protocol_BR_OK: u32 = 0; +/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1; +/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2; +/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3; +/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4; +/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5; +/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6; +/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7; +/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8; +/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9; +/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10; +/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11; +/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12; +/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13; +/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;  /// macro_rules! pub_no_prefix {  ///     ($prefix:ident, $($newname:ident),+) => {  ///         kernel::macros::paste! { -///             $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+ +///             $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+  ///         }  ///     };  /// } @@ -390,7 +450,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {  ///  /// Literals can also be concatenated with other identifiers:  /// -/// ```ignore +/// ```  /// macro_rules! create_numbered_fn {  ///     ($name:literal, $val:literal) => {  ///         kernel::macros::paste! { @@ -418,7 +478,9 @@ pub fn paste(input: TokenStream) -> TokenStream {  ///  /// # Examples  /// -/// ```rust,ignore +/// ``` +/// use kernel::macros::Zeroable; +///  /// #[derive(Zeroable)]  /// pub struct DriverData {  ///     id: i64, diff --git a/rust/macros/module.rs b/rust/macros/module.rs index aef3b132f32b..e7a087b7e884 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -253,7 +253,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {                      #[doc(hidden)]                      #[no_mangle]                      #[link_section = \".init.text\"] -                    pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{ +                    pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{                          // SAFETY: This function is inaccessible to the outside due to the double                          // module wrapping it. It is called exactly once by the C side via its                          // unique name. @@ -292,7 +292,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {                      #[doc(hidden)]                      #[link_section = \"{initcall_section}\"]                      #[used] -                    pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init; +                    pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init;                      #[cfg(not(MODULE))]                      #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] @@ -307,7 +307,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {                      #[cfg(not(MODULE))]                      #[doc(hidden)]                      #[no_mangle] -                    pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{ +                    pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{                          // SAFETY: This function is inaccessible to the outside due to the double                          // module wrapping it. It is called exactly once by the C side via its                          // placement above in the initcall section. @@ -330,7 +330,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {                      /// # Safety                      ///                      /// This function must only be called once. -                    unsafe fn __init() -> core::ffi::c_int {{ +                    unsafe fn __init() -> kernel::ffi::c_int {{                          match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{                              Ok(m) => {{                                  // SAFETY: No data race, since `__MOD` can only be accessed by this diff --git a/rust/macros/paste.rs b/rust/macros/paste.rs index f40d42b35b58..6529a387673f 100644 --- a/rust/macros/paste.rs +++ b/rust/macros/paste.rs @@ -2,7 +2,7 @@  use proc_macro::{Delimiter, Group, Ident, Spacing, Span, TokenTree}; -fn concat(tokens: &[TokenTree], group_span: Span) -> TokenTree { +fn concat_helper(tokens: &[TokenTree]) -> Vec<(String, Span)> {      let mut tokens = tokens.iter();      let mut segments = Vec::new();      let mut span = None; @@ -46,12 +46,21 @@ fn concat(tokens: &[TokenTree], group_span: Span) -> TokenTree {                  };                  segments.push((value, sp));              } -            _ => panic!("unexpected token in paste segments"), +            Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::None => { +                let tokens = group.stream().into_iter().collect::<Vec<TokenTree>>(); +                segments.append(&mut concat_helper(tokens.as_slice())); +            } +            token => panic!("unexpected token in paste segments: {:?}", token),          };      } +    segments +} + +fn concat(tokens: &[TokenTree], group_span: Span) -> TokenTree { +    let segments = concat_helper(tokens);      let pasted: String = segments.into_iter().map(|x| x.0).collect(); -    TokenTree::Ident(Ident::new(&pasted, span.unwrap_or(group_span))) +    TokenTree::Ident(Ident::new(&pasted, group_span))  }  pub(crate) fn expand(tokens: &mut Vec<TokenTree>) { | 
