From: "Benno Lossin" <lossin@kernel.org>
To: "Timur Tabi" <ttabi@nvidia.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Danilo Krummrich" <dakr@kernel.org>,
<rust-for-linux@vger.kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>
Subject: Re: [PATCH] rust: introduce sfile macro for easier code tracing
Date: Thu, 29 May 2025 22:14:44 +0200 [thread overview]
Message-ID: <DA8X4RXQKX5J.N4S9TWX90OU9@kernel.org> (raw)
In-Reply-To: <20250529184547.1447995-1-ttabi@nvidia.com>
On Thu May 29, 2025 at 8:45 PM CEST, Timur Tabi wrote:
> 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 goes 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.
>
> Unfortunately, Rust does not consider the .. operator to be const either,
> so sfind!() cannot be assigned to consts. For example, the following will
> not compile:
This is not the `..` operator, but rather the index operation of a str
(`&FILE[start..]`). It can be made const by using `from_utf8` [1] and
manually creating the correct byte slice using `unsafe` [2] instead.
[1]: https://doc.rust-lang.org/std/str/fn.from_utf8.html
[2]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html
> const SFILE: &'static str = sfile!();
>
> Signed-off-by: Timur Tabi <ttabi@nvidia.com>
> ---
> rust/kernel/print.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 48 insertions(+)
>
> diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
> index cf4714242e14..3c7b0c74bfb9 100644
> --- a/rust/kernel/print.rs
> +++ b/rust/kernel/print.rs
> @@ -414,3 +414,51 @@ macro_rules! pr_cont (
> $crate::print_macro!($crate::print::format_strings::CONT, true, $($arg)*)
> )
> );
> +
> +/// Returns just the base filename of the current file.
> +/// file!() returns the full path of the current file, which is often too long.
> +/// Use this macro to trace your code:
> +/// pr_err!("{}:{}\n", sfile!(), line!());
> +/// Note: Avoiding rfind() allows this macro to be evaluated at compile time
> +/// in most situations, such as the above pr_err!() example. However,
> +/// because .. is apparently a non-const operator, the following will not work:
> +/// const SFILE: &'static str = sfile!();
> +#[macro_export]
> +macro_rules! sfile {
> + () => {{
> + const FILE: &str = file!();
> +
> + /// Return the index of the last occurrence of @needle in @haystack,
> + /// or zero if not found. We can't use rfind() because it's not const (yet).
> + const fn find_last_or_zero(haystack: &str, needle: char) -> usize {
> + let bytes = haystack.as_bytes();
Using bytes doesn't consider non-ascii filenames (which I think we don't
have), but we could enforce that by checking `is_ascii` and panicking
otherwise.
---
Cheers,
Benno
> + let mut i = haystack.len();
> + while i > 0 {
> + i -= 1;
> + if bytes[i] == needle as u8 {
> + return i;
> + }
> + }
> + 0
> + }
> +
> + /// Return the index of the last occurrence of @needle in @haystack,
> + /// or the length of the string if not found.
> + const fn find_last_or_len(haystack: &str, needle: char) -> usize {
> + let len = haystack.len();
> + let bytes = haystack.as_bytes();
> + let mut i = len;
> + while i > 0 {
> + i -= 1;
> + if bytes[i] == needle as u8 {
> + return i;
> + }
> + }
> + len
> + }
> +
> + let start = find_last_or_zero(FILE, '/') + 1;
> + let len = find_last_or_len(&FILE[start..], '.');
> + &FILE[start..start+len]
> + }};
> +}
next prev parent reply other threads:[~2025-05-29 20:14 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-29 18:45 [PATCH] rust: introduce sfile macro for easier code tracing Timur Tabi
2025-05-29 20:14 ` Benno Lossin [this message]
2025-06-03 17:15 ` Timur Tabi
2025-06-03 21:54 ` Benno Lossin
2025-05-29 20:21 ` Miguel Ojeda
2025-06-03 18:15 ` Timur Tabi
2025-06-03 21:58 ` Benno Lossin
2025-06-03 22:05 ` Timur Tabi
2025-06-03 22:15 ` Miguel Ojeda
2025-06-04 23:12 ` Timur Tabi
2025-06-05 3:20 ` Miguel Ojeda
2025-06-03 22:15 ` Miguel Ojeda
2025-06-03 23:29 ` Timur Tabi
2025-06-04 10:28 ` Miguel Ojeda
2025-06-04 15:16 ` Benno Lossin
2025-06-04 15:41 ` Miguel Ojeda
2025-06-05 6:05 ` Greg KH
2025-06-04 20:38 ` Timur Tabi
2025-06-05 6:07 ` Greg KH
2025-06-05 15:02 ` Timur Tabi
2025-06-05 15:21 ` gregkh
2025-06-05 15:38 ` Miguel Ojeda
2025-06-05 16:42 ` gregkh
2025-06-05 17:39 ` Miguel Ojeda
2025-06-06 15:50 ` Miguel Ojeda
2025-05-30 3:47 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DA8X4RXQKX5J.N4S9TWX90OU9@kernel.org \
--to=lossin@kernel.org \
--cc=aliceryhl@google.com \
--cc=dakr@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=ttabi@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.