Skip to content

Commit 1f96a0f

Browse files
committed
Switch to Rust param ops for all ints
1 parent 0164184 commit 1f96a0f

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

rust/kernel/module_param.rs

+72-2
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,76 @@ pub trait ModuleParam : core::fmt::Display + core::marker::Sized {
4343
}
4444
}
4545

46+
/// Trait for parsing integers. Strings begining with `0x`, `0o`, or `0b` are
47+
/// parsed as hex, octal, or binary respectively. Strings beginning with `0`
48+
/// otherwise are parsed as octal. Anything else is parsed as decimal. A
49+
/// leading `+` or `-` is also permitted. Any string parsed by `kstrtol` or
50+
/// `kstrtoul` will be successfully parsed.
51+
trait ParseInt : Sized {
52+
fn from_str_radix(src: &str, radix: u32) -> Result<Self, core::num::ParseIntError>;
53+
fn checked_neg(self) -> Option<Self>;
54+
55+
fn from_str_unsigned(src: &str) -> Result<Self, core::num::ParseIntError> {
56+
let (radix, digits) = if let Some(n) = src.strip_prefix("0x") {
57+
(16, n)
58+
} else if let Some(n) = src.strip_prefix("0X") {
59+
(16, n)
60+
} else if let Some(n) = src.strip_prefix("0o") {
61+
(8, n)
62+
} else if let Some(n) = src.strip_prefix("0O") {
63+
(8, n)
64+
} else if let Some(n) = src.strip_prefix("0b") {
65+
(2, n)
66+
} else if let Some(n) = src.strip_prefix("0B") {
67+
(2, n)
68+
} else if src.starts_with("0") {
69+
(8, src)
70+
} else {
71+
(10, src)
72+
};
73+
Self::from_str_radix(digits, radix)
74+
}
75+
76+
fn from_str(src: &str) -> Option<Self> {
77+
match src.bytes().next() {
78+
None => None,
79+
Some(b'-') => Self::from_str_unsigned(&src[1..]).ok()?.checked_neg(),
80+
Some(b'+') => Some(Self::from_str_unsigned(&src[1..]).ok()?),
81+
Some(_) => Some(Self::from_str_unsigned(src).ok()?),
82+
}
83+
}
84+
}
85+
86+
macro_rules! impl_parse_int {
87+
($ty:ident) => {
88+
impl ParseInt for $ty {
89+
fn from_str_radix(src: &str, radix: u32) -> Result<Self, core::num::ParseIntError> {
90+
$ty::from_str_radix(src, radix)
91+
}
92+
fn checked_neg(self) -> Option<Self> {
93+
self.checked_neg()
94+
}
95+
}
96+
}
97+
}
98+
99+
impl_parse_int!(i8);
100+
impl_parse_int!(u8);
101+
impl_parse_int!(i16);
102+
impl_parse_int!(u16);
103+
impl_parse_int!(i32);
104+
impl_parse_int!(u32);
105+
impl_parse_int!(i64);
106+
impl_parse_int!(u64);
107+
impl_parse_int!(isize);
108+
impl_parse_int!(usize);
109+
46110
macro_rules! make_param_ops {
47111
($ops:ident, $ty:ident) => {
48112
impl ModuleParam for $ty {
49113
fn try_from_param_arg(arg: &[u8]) -> Option<Self> {
50114
let utf8 = core::str::from_utf8(arg).ok()?;
51-
utf8.parse::<$ty>().ok()
115+
<$ty as crate::module_param::ParseInt>::from_str(utf8)
52116
}
53117
}
54118

@@ -62,6 +126,12 @@ macro_rules! make_param_ops {
62126
}
63127

64128
make_param_ops!(PARAM_OPS_I8, i8);
129+
make_param_ops!(PARAM_OPS_U8, u8);
130+
make_param_ops!(PARAM_OPS_I16, i16);
131+
make_param_ops!(PARAM_OPS_U16, u16);
132+
make_param_ops!(PARAM_OPS_I32, i32);
133+
make_param_ops!(PARAM_OPS_U32, u32);
65134
make_param_ops!(PARAM_OPS_I64, i64);
66-
make_param_ops!(PARAM_OPS_USIZE, usize);
135+
make_param_ops!(PARAM_OPS_U64, u64);
67136
make_param_ops!(PARAM_OPS_ISIZE, isize);
137+
make_param_ops!(PARAM_OPS_USIZE, usize);

rust/module.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,13 @@ pub fn module(ts: TokenStream) -> TokenStream {
284284
let (param_kernel_type, ops) = match param_type.as_ref() {
285285
"bool" => ("bool", "kernel::bindings::param_ops_bool"),
286286
"i8" => ("i8", "kernel::module_param::PARAM_OPS_I8"),
287-
"u8" => ("u8", "kernel::bindings::param_ops_char"),
288-
"i16" => ("i16", "kernel::bindings::param_ops_short"),
289-
"u16" => ("u16", "kernel::bindings::param_ops_ushort"),
290-
"i32" => ("i32", "kernel::bindings::param_ops_int"),
291-
"u32" => ("u32", "kernel::bindings::param_ops_uint"),
287+
"u8" => ("u8", "kernel::module_param::PARAM_OPS_U8"),
288+
"i16" => ("i16", "kernel::module_param::PARAM_OPS_I16"),
289+
"u16" => ("u16", "kernel::module_param::PARAM_OPS_U16"),
290+
"i32" => ("i32", "kernel::module_param::PARAM_OPS_I32"),
291+
"u32" => ("u32", "kernel::module_param::PARAM_OPS_U32"),
292292
"i64" => ("i64", "kernel::module_param::PARAM_OPS_I64"),
293-
"u64" => ("u64", "kernel::bindings::param_ops_ullong"),
293+
"u64" => ("u64", "kernel::module_param::PARAM_OPS_U64"),
294294
"isize" => ("isize", "kernel::module_param::PARAM_OPS_ISIZE"),
295295
"usize" => ("usize", "kernel::module_param::PARAM_OPS_USIZE"),
296296
"str" => ("charp", "kernel::bindings::param_ops_charp"),

0 commit comments

Comments
 (0)