Re: [PATCH] rust: str: add to_ascii_{upper,lower}case() to CString

From: Danilo Krummrich
Date: Tue Jan 23 2024 - 12:25:02 EST


On Mon, Jan 22, 2024 at 03:12:04PM -0800, Greg KH wrote:
> On Mon, Jan 22, 2024 at 11:38:34PM +0100, Danilo Krummrich wrote:
> > On Mon, Jan 22, 2024 at 11:35:29AM -0800, Greg KH wrote:
> > > On Mon, Jan 22, 2024 at 07:45:57PM +0100, Danilo Krummrich wrote:
> > > > Add functions to convert a CString to upper- / lowercase assuming all
> > > > characters are ASCII encoded.
> > > >
> > > > Signed-off-by: Danilo Krummrich <dakr@xxxxxxxxxx>
> > > > ---
> > > > rust/kernel/str.rs | 10 ++++++++++
> > > > 1 file changed, 10 insertions(+)
> > > >
> > > > diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> > > > index 7d848b83add4..d21151d89861 100644
> > > > --- a/rust/kernel/str.rs
> > > > +++ b/rust/kernel/str.rs
> > > > @@ -581,6 +581,16 @@ pub fn try_from_fmt(args: fmt::Arguments<'_>) -> Result<Self, Error> {
> > > > // exist in the buffer.
> > > > Ok(Self { buf })
> > > > }
> > > > +
> > > > + /// Converts the whole CString to lowercase.
> > > > + pub fn to_ascii_lowercase(&mut self) {
> > > > + self.buf.make_ascii_lowercase();
> > > > + }
> > > > +
> > > > + /// Converts the whole CString to uppercase.
> > > > + pub fn to_ascii_uppercase(&mut self) {
> > > > + self.buf.make_ascii_uppercase();
> > > > + }
> > >
> > > How are you handling locales?
> >
> > For ASCII only? Not at all, I guess.
>
> Ah, this is ascii, yes, sorry. So this is a replacement of
> toupper()/tolower() in the C api?

It's not a replacement, but it's kinda analogous to that, since the CString
module is mainly used for interoperability with kernel APIs that take C strings.

And I say mainly, because there is no other string implementation in kernel
Rust, hence it might be used independed of whether interoperability is required
or not.

>
> > However, std::slice::make_ascii_{lower,upper]case() doesn't seem to handle the
> > extended range, which tolower() / toupper(), according to _ctype[], does. Do
> > you mean that?
>
> You should support whatever those functions in the kernel support today,
> otherwise why add it? And why not just call the kernel function to be
> sure?

Well, given that CString serves as interoperability layer for kernel APIs that
take C strings, I agree that seems natural.

On the other hand, CString and CStr are designed after the implementation in the
Rust std library and there were requests already to align those functions as
well.

We also need to consider that simply wrapping tolower() and toupper() would make
slice::make_ascii_{lower,upper]case(), str::make_ascii_{lower,upper]case(),
char::make_ascii_{lower,upper]case() and CString::make_ascii_{lower,upper]case()
inconsistent. The former ones already only consider 'a' to 'z' and 'A' to 'Z'
respectively.

As already mentioned in [1], it might just depend on whether we see CString only
as interoperability layer or as the way to deal with strings in kernel Rust in
general.

Just to clarify, personally I'm not worried about whether we consider the
extended range in this specific case or not. I think it's more interesting to
generlly figure out if, for such modules, we want the caller to expect C
bindings to be called or C logic to applied respectively, or if we want the
caller to expect that everything is aligned with the Rust std library.

[1] https://rust-for-linux.zulipchat.com/#narrow/stream/288089-General/topic/String.20manipulation.20in.20kernel.20Rust

- Danilo

>
> thanks,
>
> greg k-h
>