rust/kernel/str/parse_int.rs
Source file repositories/reference/linux-study-clean/rust/kernel/str/parse_int.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/str/parse_int.rs- Extension
.rs- Size
- 5730 bytes
- Lines
- 149
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function strip_radixfunction from_str
Annotated Snippet
fn strip_radix(src: &BStr) -> (u32, &BStr) {
match src.deref() {
[b'0', b'x' | b'X', rest @ ..] => (16, rest.as_ref()),
[b'0', b'o' | b'O', rest @ ..] => (8, rest.as_ref()),
[b'0', b'b' | b'B', rest @ ..] => (2, rest.as_ref()),
// NOTE: We are including the leading zero to be able to parse
// literal `0` here. If we removed it as a radix prefix, we would
// not be able to parse `0`.
[b'0', ..] => (8, src),
_ => (10, src),
}
}
/// Trait for parsing string representations of integers.
///
/// Strings beginning with `0x`, `0o`, or `0b` are parsed as hex, octal, or
/// binary respectively. Strings beginning with `0` otherwise are parsed as
/// octal. Anything else is parsed as decimal. A leading `+` or `-` is also
/// permitted. Any string parsed by [`kstrtol()`] or [`kstrtoul()`] will be
/// successfully parsed.
///
/// [`kstrtol()`]: https://docs.kernel.org/core-api/kernel-api.html#c.kstrtol
/// [`kstrtoul()`]: https://docs.kernel.org/core-api/kernel-api.html#c.kstrtoul
///
/// # Examples
///
/// ```
/// # use kernel::str::parse_int::ParseInt;
/// # use kernel::b_str;
///
/// assert_eq!(Ok(0u8), u8::from_str(b_str!("0")));
///
/// assert_eq!(Ok(0xa2u8), u8::from_str(b_str!("0xa2")));
/// assert_eq!(Ok(-0xa2i32), i32::from_str(b_str!("-0xa2")));
///
/// assert_eq!(Ok(-0o57i8), i8::from_str(b_str!("-0o57")));
/// assert_eq!(Ok(0o57i8), i8::from_str(b_str!("057")));
///
/// assert_eq!(Ok(0b1001i16), i16::from_str(b_str!("0b1001")));
/// assert_eq!(Ok(-0b1001i16), i16::from_str(b_str!("-0b1001")));
///
/// assert_eq!(Ok(127i8), i8::from_str(b_str!("127")));
/// assert!(i8::from_str(b_str!("128")).is_err());
/// assert_eq!(Ok(-128i8), i8::from_str(b_str!("-128")));
/// assert!(i8::from_str(b_str!("-129")).is_err());
/// assert_eq!(Ok(255u8), u8::from_str(b_str!("255")));
/// assert!(u8::from_str(b_str!("256")).is_err());
/// ```
pub trait ParseInt: private::FromStrRadix + TryFrom<u64> {
/// Parse a string according to the description in [`Self`].
fn from_str(src: &BStr) -> Result<Self> {
match src.deref() {
[b'-', rest @ ..] => {
let (radix, digits) = strip_radix(rest.as_ref());
// 2's complement values range from -2^(b-1) to 2^(b-1)-1.
// So if we want to parse negative numbers as positive and
// later multiply by -1, we have to parse into a larger
// integer. We choose `u64` as sufficiently large.
//
// NOTE: 128 bit integers are not available on all
// platforms, hence the choice of 64 bits.
let val =
u64::from_str_radix(core::str::from_utf8(digits).map_err(|_| EINVAL)?, radix)
.map_err(|_| EINVAL)?;
Self::from_u64_negated(val)
}
_ => {
let (radix, digits) = strip_radix(src);
Self::from_str_radix(digits, radix).map_err(|_| EINVAL)
}
}
}
}
macro_rules! impl_parse_int {
($($ty:ty),*) => {
$(
impl private::FromStrRadix for $ty {
fn from_str_radix(src: &BStr, radix: u32) -> Result<Self> {
<$ty>::from_str_radix(core::str::from_utf8(src).map_err(|_| EINVAL)?, radix)
.map_err(|_| EINVAL)
}
fn from_u64_negated(value: u64) -> Result<Self> {
const ABS_MIN: u64 = {
#[allow(unused_comparisons)]
if <$ty>::MIN < 0 {
1u64 << (<$ty>::BITS - 1)
} else {
0
Annotation
- Detected declarations: `function strip_radix`, `function from_str`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.