Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3//! Rust standard library vendored code.
  4//!
  5//! The contents of this file come from the Rust standard library, hosted in
  6//! the <https://github.com/rust-lang/rust> repository, licensed under
  7//! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
  8//! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
  9
 10/// [`std::dbg`], but using [`pr_info`] instead of [`eprintln`].
 11///
 12/// Prints and returns the value of a given expression for quick and dirty
 13/// debugging.
 14///
 15/// An example:
 16///
 17/// ```rust
 18/// let a = 2;
 19/// # #[expect(clippy::disallowed_macros)]
 20/// let b = dbg!(a * 2) + 1;
 21/// //      ^-- prints: [src/main.rs:3:9] a * 2 = 4
 22/// assert_eq!(b, 5);
 23/// ```
 24///
 25/// The macro works by using the `Debug` implementation of the type of
 26/// the given expression to print the value with [`printk`] along with the
 27/// source location of the macro invocation as well as the source code
 28/// of the expression.
 29///
 30/// Invoking the macro on an expression moves and takes ownership of it
 31/// before returning the evaluated expression unchanged. If the type
 32/// of the expression does not implement `Copy` and you don't want
 33/// to give up ownership, you can instead borrow with `dbg!(&expr)`
 34/// for some expression `expr`.
 35///
 36/// The `dbg!` macro works exactly the same in release builds.
 37/// This is useful when debugging issues that only occur in release
 38/// builds or when debugging in release mode is significantly faster.
 39///
 40/// Note that the macro is intended as a temporary debugging tool to be
 41/// used during development. Therefore, avoid committing `dbg!` macro
 42/// invocations into the kernel tree.
 43///
 44/// For debug output that is intended to be kept in the kernel tree,
 45/// use [`pr_debug`] and similar facilities instead.
 46///
 47/// # Stability
 48///
 49/// The exact output printed by this macro should not be relied upon
 50/// and is subject to future changes.
 51///
 52/// # Further examples
 53///
 54/// With a method call:
 55///
 56/// ```rust
 57/// # #[expect(clippy::disallowed_macros)]
 58/// fn foo(n: usize) {
 59///     if dbg!(n.checked_sub(4)).is_some() {
 60///         // ...
 61///     }
 62/// }
 63///
 64/// foo(3)
 65/// ```
 66///
 67/// This prints to the kernel log:
 68///
 69/// ```text,ignore
 70/// [src/main.rs:3:8] n.checked_sub(4) = None
 71/// ```
 72///
 73/// Naive factorial implementation:
 74///
 75/// ```rust
 76/// # #![expect(clippy::disallowed_macros)]
 77/// fn factorial(n: u32) -> u32 {
 78///     if dbg!(n <= 1) {
 79///         dbg!(1)
 80///     } else {
 81///         dbg!(n * factorial(n - 1))
 82///     }
 83/// }
 84///
 85/// dbg!(factorial(4));
 86/// ```
 87///
 88/// This prints to the kernel log:
 89///
 90/// ```text,ignore
 91/// [src/main.rs:3:8] n <= 1 = false
 92/// [src/main.rs:3:8] n <= 1 = false
 93/// [src/main.rs:3:8] n <= 1 = false
 94/// [src/main.rs:3:8] n <= 1 = true
 95/// [src/main.rs:4:9] 1 = 1
 96/// [src/main.rs:5:9] n * factorial(n - 1) = 2
 97/// [src/main.rs:5:9] n * factorial(n - 1) = 6
 98/// [src/main.rs:5:9] n * factorial(n - 1) = 24
 99/// [src/main.rs:11:1] factorial(4) = 24
100/// ```
101///
102/// The `dbg!(..)` macro moves the input:
103///
104/// ```ignore
105/// /// A wrapper around `usize` which importantly is not Copyable.
106/// #[derive(Debug)]
107/// struct NoCopy(usize);
108///
109/// let a = NoCopy(42);
110/// let _ = dbg!(a); // <-- `a` is moved here.
111/// let _ = dbg!(a); // <-- `a` is moved again; error!
112/// ```
113///
114/// You can also use `dbg!()` without a value to just print the
115/// file and line whenever it's reached.
116///
117/// Finally, if you want to `dbg!(..)` multiple values, it will treat them as
118/// a tuple (and return it, too):
119///
120/// ```
121/// # #![expect(clippy::disallowed_macros)]
122/// assert_eq!(dbg!(1usize, 2u32), (1, 2));
123/// ```
124///
125/// However, a single argument with a trailing comma will still not be treated
126/// as a tuple, following the convention of ignoring trailing commas in macro
127/// invocations. You can use a 1-tuple directly if you need one:
128///
129/// ```
130/// # #![expect(clippy::disallowed_macros)]
131/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored
132/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple
133/// ```
134///
135/// [`std::dbg`]: https://doc.rust-lang.org/std/macro.dbg.html
136/// [`eprintln`]: https://doc.rust-lang.org/std/macro.eprintln.html
137/// [`printk`]: https://docs.kernel.org/core-api/printk-basics.html
138/// [`pr_info`]: crate::pr_info!
139/// [`pr_debug`]: crate::pr_debug!
140#[macro_export]
141macro_rules! dbg {
142    // NOTE: We cannot use `concat!` to make a static string as a format argument
143    // of `pr_info!` because `file!` could contain a `{` or
144    // `$val` expression could be a block (`{ .. }`), in which case the `pr_info!`
145    // will be malformed.
146    () => {
147        $crate::pr_info!("[{}:{}:{}]\n", ::core::file!(), ::core::line!(), ::core::column!())
148    };
149    ($val:expr $(,)?) => {
150        // Use of `match` here is intentional because it affects the lifetimes
151        // of temporaries - https://stackoverflow.com/a/48732525/1063961
152        match $val {
153            tmp => {
154                $crate::pr_info!("[{}:{}:{}] {} = {:#?}\n",
155                    ::core::file!(), ::core::line!(), ::core::column!(),
156                    ::core::stringify!($val), &tmp);
157                tmp
158            }
159        }
160    };
161    ($($val:expr),+ $(,)?) => {
162        ($($crate::dbg!($val)),+,)
163    };
164}