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 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).