add descriptions and pick a better function name

This commit is contained in:
auronandace
2026-06-12 11:13:06 +01:00
parent 0dc5247ff6
commit ecb081d8bd
6 changed files with 48 additions and 38 deletions
+16 -1
View File
@@ -1,15 +1,30 @@
use crate::platform::types::c_char;
/// An abstraction over a byte literal to provide a method to convert safely
/// to a `c_char`.
///
/// The abstraction is required so we can contain architecture specific code
/// in a central location.
pub struct ByteLiteral;
impl ByteLiteral {
pub fn cast_unchecked(input: u8) -> c_char {
/// Casts a byte literal (`u8`) to a `c_char` without using `as`.
///
/// # Panics
/// If `input` is not within the following range of ascii characters:
/// - Octal: `040`..=`176`
/// - Decimal: `30`..=`126`
/// - Hexadecimal: `20`..=`7E`
/// - Byte literals: b` `..=b`~`
pub fn cast_cchar(input: u8) -> c_char {
match input {
b' '..=b'~' => {
// `c_char` is an `i8` on these arches
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
{
input.cast_signed()
}
// `c_char` is already a `u8` on these arches
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
{
input.into()
+1 -1
View File
@@ -78,7 +78,7 @@ unsafe fn strcolcmp(mut lstr: *const c_char, mut bstr: *const c_char) -> c_int {
lstr = lstr.add(1);
bstr = bstr.add(1);
}
if *lstr != 0 || (*bstr != 0 && *bstr != ByteLiteral::cast_unchecked(b':')) {
if *lstr != 0 || (*bstr != 0 && *bstr != ByteLiteral::cast_cchar(b':')) {
1
} else {
0
+8 -13
View File
@@ -62,7 +62,7 @@ pub unsafe extern "C" fn getopt_long(
let current_arg = unsafe { *argv.offset(optind as isize) };
if unsafe {
current_arg.is_null()
|| *current_arg != ByteLiteral::cast_unchecked(b'-')
|| *current_arg != ByteLiteral::cast_cchar(b'-')
|| *current_arg.offset(1) == 0
} {
-1
@@ -75,9 +75,7 @@ pub unsafe extern "C" fn getopt_long(
// remove the '-'
let current_arg = unsafe { current_arg.offset(1) };
if unsafe { *current_arg == ByteLiteral::cast_unchecked(b'-') }
&& !longopts.is_null()
{
if unsafe { *current_arg == ByteLiteral::cast_cchar(b'-') } && !longopts.is_null() {
let current_arg = unsafe { current_arg.offset(1) };
// is a long option
for i in 0.. {
@@ -89,7 +87,7 @@ pub unsafe extern "C" fn getopt_long(
let mut end = 0;
while {
let c = unsafe { *current_arg.offset(end) };
c != 0 && c != ByteLiteral::cast_unchecked(b'=')
c != 0 && c != ByteLiteral::cast_cchar(b'=')
} {
end += 1;
}
@@ -104,20 +102,18 @@ pub unsafe extern "C" fn getopt_long(
if opt.has_arg == optional_argument {
unsafe {
if *current_arg.offset(end) == ByteLiteral::cast_unchecked(b'=')
{
if *current_arg.offset(end) == ByteLiteral::cast_cchar(b'=') {
optarg = current_arg.offset(end + 1);
}
}
} else if opt.has_arg == required_argument {
unsafe {
if *current_arg.offset(end) == ByteLiteral::cast_unchecked(b'=')
{
if *current_arg.offset(end) == ByteLiteral::cast_cchar(b'=') {
optarg = current_arg.offset(end + 1);
} else if optind < argc {
optarg = *argv.offset(optind as isize);
optind += 1;
} else if *optstring == ByteLiteral::cast_unchecked(b':') {
} else if *optstring == ByteLiteral::cast_cchar(b':') {
return c_int::from(b':');
} else {
stdio::fputs((*argv).cast_const(), &raw mut *stdio::stderr);
@@ -188,7 +184,7 @@ unsafe fn parse_arg(
CURRENT_OPT = ptr::null_mut();
optopt = c_int::from(*current_arg);
let errch = if *optstring == ByteLiteral::cast_unchecked(b':') {
let errch = if *optstring == ByteLiteral::cast_cchar(b':') {
b':'
} else {
if opterr != 0 {
@@ -236,8 +232,7 @@ unsafe fn find_option(ch: c_char, optstring: *const c_char) -> Option<GetoptOpti
while unsafe { *optstring.offset(i) != 0 } {
if unsafe { *optstring.offset(i) == ch } {
let result = if unsafe { *optstring.offset(i + 1) == ByteLiteral::cast_unchecked(b':') }
{
let result = if unsafe { *optstring.offset(i + 1) == ByteLiteral::cast_cchar(b':') } {
GetoptOption::OptArg
} else {
GetoptOption::Flag
+5 -5
View File
@@ -11,14 +11,14 @@ pub unsafe extern "C" fn basename(str: *mut c_char) -> *mut c_char {
return c".".as_ptr().cast_mut();
}
let mut end = unsafe { strlen(str) as isize - 1 };
while end >= 0 && unsafe { *str.offset(end) == ByteLiteral::cast_unchecked(b'/') } {
while end >= 0 && unsafe { *str.offset(end) == ByteLiteral::cast_cchar(b'/') } {
end -= 1;
}
if end == -1 {
return c"/".as_ptr().cast_mut();
}
let mut begin = end;
while begin >= 0 && unsafe { *str.offset(begin) != ByteLiteral::cast_unchecked(b'/') } {
while begin >= 0 && unsafe { *str.offset(begin) != ByteLiteral::cast_cchar(b'/') } {
begin -= 1;
}
unsafe {
@@ -34,13 +34,13 @@ pub unsafe extern "C" fn dirname(str: *mut c_char) -> *mut c_char {
return c".".as_ptr().cast_mut();
}
let mut end = unsafe { strlen(str) as isize - 1 };
while end > 0 && unsafe { *str.offset(end) == ByteLiteral::cast_unchecked(b'/') } {
while end > 0 && unsafe { *str.offset(end) == ByteLiteral::cast_cchar(b'/') } {
end -= 1;
}
while end >= 0 && unsafe { *str.offset(end) != ByteLiteral::cast_unchecked(b'/') } {
while end >= 0 && unsafe { *str.offset(end) != ByteLiteral::cast_cchar(b'/') } {
end -= 1;
}
while end > 0 && unsafe { *str.offset(end) == ByteLiteral::cast_unchecked(b'/') } {
while end > 0 && unsafe { *str.offset(end) == ByteLiteral::cast_cchar(b'/') } {
end -= 1;
}
if end == -1 {
+5 -5
View File
@@ -554,9 +554,9 @@ pub unsafe extern "C" fn flockfile(file: *mut FILE) {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE {
let initial_mode = unsafe { *mode };
if initial_mode != ByteLiteral::cast_unchecked(b'r')
&& initial_mode != ByteLiteral::cast_unchecked(b'w')
&& initial_mode != ByteLiteral::cast_unchecked(b'a')
if initial_mode != ByteLiteral::cast_cchar(b'r')
&& initial_mode != ByteLiteral::cast_cchar(b'w')
&& initial_mode != ByteLiteral::cast_cchar(b'a')
{
platform::ERRNO.set(errno::EINVAL);
return ptr::null_mut();
@@ -1292,7 +1292,7 @@ pub unsafe extern "C" fn tempnam(dir: *const c_char, pfx: *const c_char) -> *mut
if !out_buf.is_null() {
// copy the directory name and prefix into the allocated buffer
unsafe { out_buf.copy_from_nonoverlapping(dirname, dirname_len) };
unsafe { *out_buf.add(dirname_len) = ByteLiteral::cast_unchecked(b'/') };
unsafe { *out_buf.add(dirname_len) = ByteLiteral::cast_cchar(b'/') };
unsafe {
out_buf
.add(dirname_len + 1)
@@ -1351,7 +1351,7 @@ pub unsafe extern "C" fn tmpnam(s: *mut c_char) -> *mut c_char {
s
};
unsafe { *buf = ByteLiteral::cast_unchecked(b'/') };
unsafe { *buf = ByteLiteral::cast_cchar(b'/') };
unsafe {
#[allow(deprecated)]
tmpnam_inner(buf, 1)
+13 -13
View File
@@ -423,13 +423,13 @@ unsafe fn find_env(search: *const c_char) -> Option<(usize, *mut c_char)> {
let mut search = search;
loop {
let end_of_query =
unsafe { *search } == 0 || unsafe { *search } == ByteLiteral::cast_unchecked(b'=');
unsafe { *search } == 0 || unsafe { *search } == ByteLiteral::cast_cchar(b'=');
if unsafe { *item } == 0 {
//TODO: environ has an item without value, is this a problem?
break;
}
if unsafe { *item } == ByteLiteral::cast_unchecked(b'=') || end_of_query {
if unsafe { *item } == ByteLiteral::cast_unchecked(b'=') && end_of_query {
if unsafe { *item } == ByteLiteral::cast_cchar(b'=') || end_of_query {
if unsafe { *item } == ByteLiteral::cast_cchar(b'=') && end_of_query {
// Both keys env here
return Some((i, unsafe { item.add(1) }));
} else {
@@ -477,7 +477,7 @@ pub unsafe extern "C" fn getsubopt(
let mut found_comma = false;
while unsafe { *cursor } != 0 {
if unsafe { *cursor } == ByteLiteral::cast_unchecked(b',') {
if unsafe { *cursor } == ByteLiteral::cast_cchar(b',') {
unsafe { *cursor = 0 };
unsafe { *optionp = cursor.add(1) };
found_comma = true;
@@ -498,7 +498,7 @@ pub unsafe extern "C" fn getsubopt(
if unsafe { strncmp(start, token, token_len) } == 0 {
let suffix_char = unsafe { *start.add(token_len) };
if suffix_char == ByteLiteral::cast_unchecked(b'=') {
if suffix_char == ByteLiteral::cast_cchar(b'=') {
unsafe { *valuep = start.add(token_len + 1) };
return i as c_int;
} else if suffix_char == 0 {
@@ -756,7 +756,7 @@ where
}
for i in (len - suffix_len - 6)..(len - suffix_len) {
if unsafe { *name.offset(i as isize) } != ByteLiteral::cast_unchecked(b'X') {
if unsafe { *name.offset(i as isize) } != ByteLiteral::cast_cchar(b'X') {
platform::ERRNO.set(errno::EINVAL);
return None;
}
@@ -1260,7 +1260,7 @@ unsafe fn copy_kv(
value_len: usize,
) {
unsafe { core::ptr::copy_nonoverlapping(key, existing, key_len) };
unsafe { core::ptr::write(existing.add(key_len), ByteLiteral::cast_unchecked(b'=')) };
unsafe { core::ptr::write(existing.add(key_len), ByteLiteral::cast_cchar(b'=')) };
unsafe { core::ptr::copy_nonoverlapping(value, existing.add(key_len + 1), value_len) };
unsafe { core::ptr::write(existing.add(key_len + 1 + value_len), 0) };
}
@@ -1367,8 +1367,8 @@ pub unsafe extern "C" fn srandom(seed: c_uint) {
pub fn is_positive(ch: c_char) -> Option<(bool, isize)> {
match ch {
0 => None,
ch if ch == ByteLiteral::cast_unchecked(b'+') => Some((true, 1)),
ch if ch == ByteLiteral::cast_unchecked(b'-') => Some((false, 1)),
ch if ch == ByteLiteral::cast_cchar(b'+') => Some((true, 1)),
ch if ch == ByteLiteral::cast_cchar(b'-') => Some((false, 1)),
_ => Some((true, 0)),
}
}
@@ -1393,7 +1393,7 @@ pub unsafe fn detect_base(s: *const c_char) -> Option<(c_int, isize)> {
}
pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
if unsafe { *s } != 0 && unsafe { *s } == ByteLiteral::cast_unchecked(b'0') {
if unsafe { *s } != 0 && unsafe { *s } == ByteLiteral::cast_cchar(b'0') {
if let Some((val, idx, overflow)) = unsafe { convert_integer(s.offset(1), 8) } {
Some((val, idx + 1, overflow))
} else {
@@ -1406,10 +1406,10 @@ pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)>
}
pub unsafe fn convert_hex(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
if (unsafe { *s } != 0 && unsafe { *s } == ByteLiteral::cast_unchecked(b'0'))
if (unsafe { *s } != 0 && unsafe { *s } == ByteLiteral::cast_cchar(b'0'))
&& (unsafe { *s.offset(1) } != 0
&& (unsafe { *s.offset(1) } == ByteLiteral::cast_unchecked(b'x')
|| unsafe { *s.offset(1) } == ByteLiteral::cast_unchecked(b'X')))
&& (unsafe { *s.offset(1) } == ByteLiteral::cast_cchar(b'x')
|| unsafe { *s.offset(1) } == ByteLiteral::cast_cchar(b'X')))
{
unsafe { convert_integer(s.offset(2), 16) }
.map(|(val, idx, overflow)| (val, idx + 2, overflow))