rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] rust: introduce sfile macro for succinct code tracing
@ 2025-06-09 22:36 Timur Tabi
  2025-06-10  2:33 ` John Hubbard
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Timur Tabi @ 2025-06-09 22:36 UTC (permalink / raw)
  To: Miguel Ojeda, Benno Lossin, Alice Ryhl, Danilo Krummrich,
	rust-for-linux

Introduce the sfile (short file) macro that returns the stem of
the current source file filename.

Rust provides a file!() macro that is similar to C's __FILE__ predefined
macro.  Unlike __FILE__, however, file!() returns a full path, which is
klunky when used for debug traces such as

	pr_info!("{}:{}\n", file!(), line!());

sfile!() can be used in situations instead, to provide a more compact
print.  For example, if file!() returns "rust/kernel/print.rs", sfile!()
returns just "print".

The macro avoids str::rfind() because currently, that function is not
const.  The compiler emits a call to memrchr, even when called on string
literals.  Instead, the macro implements its own versions of rfind(),
allowing the compiler to generate the slice at compile time.

The macro also uses some unsafe functions in order to avoid indexing
into a str, which is necessary to fully support const contexts.

Signed-off-by: Timur Tabi <ttabi@nvidia.com>
---
 rust/kernel/print.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
index 9783d960a97a..5b0c36481e95 100644
--- a/rust/kernel/print.rs
+++ b/rust/kernel/print.rs
@@ -423,3 +423,69 @@ macro_rules! pr_cont (
         $crate::print_macro!($crate::print::format_strings::CONT, true, $($arg)*)
     )
 );
+/// Returns the index of the last occurrence of `needle` in `haystack`, or zero.
+///
+/// Identical to [`str::rfind()`], but unlike that function, this one is const.
+/// That is, the compiler can inline it when called with a string literal.
+#[inline]
+pub const fn rfind_const(haystack: &str, needle: char) -> Option<usize> {
+    let bytes = haystack.as_bytes();
+    let mut i = haystack.len();
+    while i > 0 {
+        i -= 1;
+        if bytes[i] == needle as u8 {
+            return Some(i);
+        }
+    }
+    None
+}
+
+/// Returns just the base filename of the current file.
+///
+/// This differs from the built-in [`file!()`] macro, which returns the full
+/// path of the current file.
+///
+/// Using the base filename gives you more succinct logging prints.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::sfile
+/// pr_err!("{}:{}\n", sfile!(), line!());
+/// ```
+#[macro_export]
+macro_rules! sfile {
+    () => {{
+        use kernel::print::rfind_const;
+
+        const FILE: &str = file!();
+
+        // [`.as_bytes()`] does not support non-ASCII filenames
+        assert!(FILE.is_ascii());
+
+        let start = match rfind_const(FILE, '/') {
+            Some(slash) => slash + 1,
+            None => 0,
+        };
+        let end = match rfind_const(FILE, '.') {
+            Some(dot) => dot,
+            None => FILE.len(),
+        };
+
+        // The following code the equivalent of &FILE[start..start+len],
+        // except that it allows for const contexts.  For example,
+        //   const SFILE: &'static str = sfile!();
+
+        let base_ptr: *const u8 = FILE.as_ptr();
+
+        // SAFETY: We know that `start` is <= the length of FILE, because FILE
+        // never ends in a slash.
+        let ptr: *const u8 = unsafe { base_ptr.add(start) };
+        // SAFETY: We also know that `end` < the length of FILE.
+        // If `end` < `start`, this will generate a compiler error.
+        let slice = unsafe { core::slice::from_raw_parts(ptr, end - start) };
+        // SAFETY: We know that the slice is valid UTF-8, because we checked
+        // that FILE is ASCII (via is_ascii() above).
+        unsafe { core::str::from_utf8_unchecked(slice) }
+    }};
+}

base-commit: 19272b37aa4f83ca52bdf9c16d5d81bdd1354494
prerequisite-patch-id: 4bfda16a333b9f00a139050b7c6875922961a15d
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2025-06-16 18:19 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-09 22:36 [PATCH v3] rust: introduce sfile macro for succinct code tracing Timur Tabi
2025-06-10  2:33 ` John Hubbard
2025-06-10  3:40   ` Timur Tabi
2025-06-10  8:31     ` Benno Lossin
2025-06-10  8:45 ` Benno Lossin
2025-06-13 17:03   ` Timur Tabi
2025-06-13 17:57     ` Miguel Ojeda
2025-06-13 19:14       ` Timur Tabi
2025-06-13 20:08         ` Timur Tabi
2025-06-13 19:32   ` Timur Tabi
2025-06-13 20:06     ` Timur Tabi
2025-06-14 17:08       ` Benno Lossin
2025-06-16 15:37         ` Timur Tabi
2025-06-16 18:18           ` Miguel Ojeda
2025-06-13 22:46   ` Timur Tabi
2025-06-14 18:01     ` Benno Lossin
2025-06-10  8:47 ` Miguel Ojeda
2025-06-10 19:18   ` Timur Tabi
2025-06-10 19:29     ` Miguel Ojeda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).