@@ -4,10 +4,11 @@
//!
//! C header: [`include/uapi/asm-generic/errno-base.h`](srctree/include/uapi/asm-generic/errno-base.h)
-use crate::{alloc::AllocError, str::CStr};
+use crate::alloc::AllocError;
use alloc::alloc::LayoutError;
+use core::ffi::CStr;
use core::fmt;
use core::num::TryFromIntError;
use core::str::Utf8Error;
@@ -142,7 +143,7 @@ pub fn name(&self) -> Option<&'static CStr> {
None
} else {
// SAFETY: The string returned by `errname` is static and `NUL`-terminated.
- Some(unsafe { CStr::from_char_ptr(ptr) })
+ Some(unsafe { CStr::from_ptr(ptr) })
}
}
@@ -164,7 +165,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
None => f.debug_tuple("Error").field(&-self.0).finish(),
// SAFETY: These strings are ASCII-only.
Some(name) => f
- .debug_tuple(unsafe { core::str::from_utf8_unchecked(name) })
+ .debug_tuple(unsafe { core::str::from_utf8_unchecked(name.to_bytes()) })
.finish(),
}
}
@@ -56,13 +56,15 @@ macro_rules! kunit_assert {
break 'out;
}
- static FILE: &'static $crate::str::CStr = $crate::c_str!($file);
+ static FILE: &'static core::ffi::CStr = $file;
static LINE: i32 = core::line!() as i32 - $diff;
- static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition));
+ static CONDITION: &'static core::ffi::CStr = $crate::c_str!(stringify!($condition));
// SAFETY: FFI call without safety requirements.
let kunit_test = unsafe { $crate::bindings::kunit_get_current_test() };
if kunit_test.is_null() {
+ use kernel::str::CStrExt;
+
// The assertion failed but this task is not running a KUnit test, so we cannot call
// KUnit, but at least print an error to the kernel log. This may happen if this
// macro is called from an spawned thread in a test (see
@@ -71,11 +73,13 @@ macro_rules! kunit_assert {
//
// This mimics KUnit's failed assertion format.
$crate::kunit::err(format_args!(
- " # {}: ASSERTION FAILED at {FILE}:{LINE}\n",
- $name
+ " # {}: ASSERTION FAILED at {}:{LINE}\n",
+ $name.display(),
+ FILE.display(),
));
$crate::kunit::err(format_args!(
- " Expected {CONDITION} to be true, but is false\n"
+ " Expected {} to be true, but is false\n",
+ CONDITION.display(),
));
$crate::kunit::err(format_args!(
" Failure not reported to KUnit since this is a non-KUnit task\n"
@@ -98,12 +102,12 @@ unsafe impl Sync for Location {}
unsafe impl Sync for UnaryAssert {}
static LOCATION: Location = Location($crate::bindings::kunit_loc {
- file: FILE.as_char_ptr(),
+ file: FILE.as_ptr(),
line: LINE,
});
static ASSERTION: UnaryAssert = UnaryAssert($crate::bindings::kunit_unary_assert {
assert: $crate::bindings::kunit_assert {},
- condition: CONDITION.as_char_ptr(),
+ condition: CONDITION.as_ptr(),
expected_true: true,
});
@@ -502,7 +502,7 @@ unsafe impl Sync for DriverVTable {}
pub const fn create_phy_driver<T: Driver>() -> DriverVTable {
// INVARIANT: All the fields of `struct phy_driver` are initialized properly.
DriverVTable(Opaque::new(bindings::phy_driver {
- name: T::NAME.as_char_ptr().cast_mut(),
+ name: T::NAME.as_ptr().cast_mut(),
flags: T::FLAGS,
phy_id: T::PHY_DEVICE_ID.id,
phy_id_mask: T::PHY_DEVICE_ID.mask_as_int(),
@@ -12,7 +12,7 @@
//! ```
#[doc(no_inline)]
-pub use core::pin::Pin;
+pub use core::{ffi::CStr, pin::Pin};
pub use crate::alloc::{box_ext::BoxExt, flags::*, vec_ext::VecExt};
@@ -35,7 +35,7 @@
pub use super::error::{code::*, Error, Result};
-pub use super::{str::CStr, ThisModule};
+pub use super::ThisModule;
pub use super::init::{InPlaceInit, Init, PinInit};
@@ -4,8 +4,9 @@
use crate::alloc::{flags::*, vec_ext::VecExt, AllocError};
use alloc::vec::Vec;
+use core::ffi::CStr;
use core::fmt::{self, Write};
-use core::ops::{self, Deref, DerefMut, Index};
+use core::ops::Deref;
use crate::error::{code::*, Error};
@@ -41,11 +42,11 @@ impl fmt::Display for BStr {
/// # use kernel::{fmt, b_str, str::{BStr, CString}};
/// let ascii = b_str!("Hello, BStr!");
/// let s = CString::try_from_fmt(fmt!("{}", ascii)).unwrap();
- /// assert_eq!(s.as_bytes(), "Hello, BStr!".as_bytes());
+ /// assert_eq!(s.to_bytes(), "Hello, BStr!".as_bytes());
///
/// let non_ascii = b_str!("
`CStr` became a part of `core` library in Rust 1.75. This change replaces the custom `CStr` implementation with the one from `core`. `core::CStr` behaves generally the same as the removed implementation, with the following differences: - It does not implement `Display`. - It does not provide `from_bytes_with_nul_unchecked_mut` method. - It has `as_ptr()` method instead of `as_char_ptr()`, which also returns `*const c_char`. The first two differences are handled by providing the `CStrExt` trait, with `display()` and `from_bytes_with_nul_unchecked_mut()` methods. `display()` returns a `CStrDisplay` wrapper, with a custom `Display` implementation. `DerefMut` implementation for `CString` is removed here, as it's not being used anywhere. Signed-off-by: Michal Rostecki <vadorovsky@gmail.com> --- v1 -> v2: - Do not remove `c_str` macro. While it's preferred to use C-string literals, there are two cases where `c_str` is helpful: - When working with macros, which already return a Rust string literal (e.g. `stringify!`). - When building macros, where we want to take a Rust string literal as an argument (for caller's convenience), but still use it as a C-string internally. - Use Rust literals as arguments in macros (`new_mutex`, `new_condvar`, `new_mutex`). Use the `c_str` macro to convert these literals to C-string literals. - Use `c_str` in kunit.rs for converting the output of `stringify!` to a `CStr`. - Remove `DerefMut` implementation for `CString`. v2 -> v3: - Fix the commit message. - Remove redundant braces in `use`, when only one item is imported. v3 -> v4: - Provide the `CStrExt` trait with `display()` method, which returns a `CStrDisplay` wrapper with `Display` implementation. This addresses the lack of `Display` implementation for `core::ffi::CStr`. - Provide `from_bytes_with_nul_unchecked_mut()` method in `CStrExt`, which might be useful and is going to prevent manual, unsafe casts. - Fix a typo (s/preffered/prefered/). rust/kernel/error.rs | 7 +- rust/kernel/kunit.rs | 18 +- rust/kernel/net/phy.rs | 2 +- rust/kernel/prelude.rs | 4 +- rust/kernel/str.rs | 492 +++++------------------------------- rust/kernel/sync/condvar.rs | 5 +- rust/kernel/sync/lock.rs | 6 +- rust/kernel/workqueue.rs | 2 +- scripts/rustdoc_test_gen.rs | 4 +- 9 files changed, 88 insertions(+), 452 deletions(-)