From 2a7d01f02d873f75f8ba4cac9e637d3daef4935e Mon Sep 17 00:00:00 2001 From: Peter Limkilde Svendsen Date: Tue, 19 Nov 2024 00:20:40 +0000 Subject: [PATCH] Add docs for string.h, add missing functions --- src/header/string/mod.rs | 294 +++++++++++++++++++++++---------------- 1 file changed, 174 insertions(+), 120 deletions(-) diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index ae1de489f2..ac5830a0b5 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -1,4 +1,6 @@ -//! string implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html +//! `string.h` implementation. +//! +//! See . use core::{iter::once, mem, ptr, slice, usize}; @@ -10,6 +12,7 @@ use crate::{ platform::{self, types::*}, }; +/// See . #[no_mangle] pub unsafe extern "C" fn memccpy( dest: *mut c_void, @@ -28,6 +31,7 @@ pub unsafe extern "C" fn memccpy( (dest as *mut u8).add(dist + 1) as *mut c_void } +/// See . #[no_mangle] pub unsafe extern "C" fn memchr( haystack: *const c_void, @@ -42,6 +46,7 @@ pub unsafe extern "C" fn memchr( } } +/// See . #[no_mangle] pub unsafe extern "C" fn memcmp(s1: *const c_void, s2: *const c_void, n: size_t) -> c_int { let (div, rem) = (n / mem::size_of::(), n % mem::size_of::()); @@ -74,6 +79,7 @@ pub unsafe extern "C" fn memcmp(s1: *const c_void, s2: *const c_void, n: size_t) 0 } +/// See . #[no_mangle] pub unsafe extern "C" fn memcpy(s1: *mut c_void, s2: *const c_void, n: size_t) -> *mut c_void { let mut i = 0; @@ -125,6 +131,7 @@ pub unsafe extern "C" fn memmem( .cast_mut() } +/// See . #[no_mangle] pub unsafe extern "C" fn memmove(s1: *mut c_void, s2: *const c_void, n: size_t) -> *mut c_void { if s2 < s1 as *const c_void { @@ -145,6 +152,7 @@ pub unsafe extern "C" fn memmove(s1: *mut c_void, s2: *const c_void, n: size_t) s1 } +/// Non-POSIX, see . #[no_mangle] pub unsafe extern "C" fn memrchr( haystack: *const c_void, @@ -159,6 +167,7 @@ pub unsafe extern "C" fn memrchr( } } +/// See . #[no_mangle] pub unsafe extern "C" fn memset(s: *mut c_void, c: c_int, n: size_t) -> *mut c_void { for i in 0..n { @@ -167,7 +176,31 @@ pub unsafe extern "C" fn memset(s: *mut c_void, c: c_int, n: size_t) -> *mut c_v s } -/// See . +/// See . +// #[no_mangle] +pub extern "C" fn stpcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_char { + unimplemented!(); +} + +/// See . +// #[no_mangle] +pub extern "C" fn stpncpy(s1: *mut c_char, s2: *const c_char, n: size_t) -> *mut c_char { + unimplemented!(); +} + +/// Non-POSIX, see . +#[no_mangle] +pub unsafe extern "C" fn strcasestr(haystack: *const c_char, needle: *const c_char) -> *mut c_char { + inner_strstr(haystack, needle, !32) +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_char { + strncat(s1, s2, usize::MAX) +} + +/// See . /// /// # Safety /// The caller is required to ensure that `s` is a valid pointer to a buffer @@ -189,17 +222,22 @@ pub unsafe extern "C" fn strchr(mut s: *const c_char, c: c_int) -> *mut c_char { ptr.cast_mut() } +/// See . #[no_mangle] pub unsafe extern "C" fn strcmp(s1: *const c_char, s2: *const c_char) -> c_int { strncmp(s1, s2, usize::MAX) } +/// See . #[no_mangle] pub unsafe extern "C" fn strcoll(s1: *const c_char, s2: *const c_char) -> c_int { // relibc has no locale stuff (yet) strcmp(s1, s2) } +// TODO: strcoll_l + +/// See . #[no_mangle] pub unsafe extern "C" fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char { let src_iter = unsafe { NulTerminated::new(src) }; @@ -238,16 +276,139 @@ pub unsafe fn inner_strspn(s1: *const c_char, s2: *const c_char, cmp: bool) -> s i } +/// See . #[no_mangle] pub unsafe extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> size_t { inner_strspn(s1, s2, false) } +/// See . #[no_mangle] pub unsafe extern "C" fn strdup(s1: *const c_char) -> *mut c_char { strndup(s1, usize::MAX) } +/// See . +#[no_mangle] +pub unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char { + use core::fmt::Write; + + static mut strerror_buf: [u8; 256] = [0; 256]; + + let mut w = platform::StringWriter(strerror_buf.as_mut_ptr(), strerror_buf.len()); + + if errnum >= 0 && errnum < STR_ERROR.len() as c_int { + let _ = w.write_str(STR_ERROR[errnum as usize]); + } else { + let _ = w.write_fmt(format_args!("Unknown error {}", errnum)); + } + + strerror_buf.as_mut_ptr() as *mut c_char +} + +// TODO: strerror_l + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int { + let msg = strerror(errnum); + let len = strlen(msg); + + if len >= buflen { + if buflen != 0 { + memcpy(buf as *mut c_void, msg as *const c_void, buflen - 1); + *buf.add(buflen - 1) = 0; + } + return ERANGE as c_int; + } + memcpy(buf as *mut c_void, msg as *const c_void, len + 1); + + 0 +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strlcat(dst: *mut c_char, src: *const c_char, n: size_t) -> size_t { + let len = strlen(dst) as isize; + let d = dst.offset(len); + + strlcpy(d, src, n) +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strlcpy(dst: *mut c_char, src: *const c_char, n: size_t) -> size_t { + let mut i = 0; + + while *src.add(i) != 0 && i < n { + *dst.add(i) = *src.add(i); + i += 1; + } + + *dst.add(i) = 0; + + i as size_t +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t { + unsafe { NulTerminated::new(s) }.count() +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strncat(s1: *mut c_char, s2: *const c_char, n: size_t) -> *mut c_char { + let len = strlen(s1 as *const c_char); + let mut i = 0; + while i < n { + let b = *s2.add(i); + if b == 0 { + break; + } + + *s1.add(len + i) = b; + i += 1; + } + *s1.add(len + i) = 0; + + s1 +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int { + let s1 = core::slice::from_raw_parts(s1 as *const c_uchar, n); + let s2 = core::slice::from_raw_parts(s2 as *const c_uchar, n); + + for (&a, &b) in s1.iter().zip(s2.iter()) { + let val = (a as c_int) - (b as c_int); + if a != b || a == 0 { + return val; + } + } + + 0 +} + +/// See . +#[no_mangle] +pub unsafe extern "C" fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char { + let mut i = 0; + + while *src.add(i) != 0 && i < n { + *dst.add(i) = *src.add(i); + i += 1; + } + + for i in i..n { + *dst.add(i) = 0; + } + + dst +} + +/// See . #[no_mangle] pub unsafe extern "C" fn strndup(s1: *const c_char, size: size_t) -> *mut c_char { let len = strnlen(s1, size); @@ -267,50 +428,13 @@ pub unsafe extern "C" fn strndup(s1: *const c_char, size: size_t) -> *mut c_char buffer } -#[no_mangle] -pub unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char { - use core::fmt::Write; - - static mut strerror_buf: [u8; 256] = [0; 256]; - - let mut w = platform::StringWriter(strerror_buf.as_mut_ptr(), strerror_buf.len()); - - if errnum >= 0 && errnum < STR_ERROR.len() as c_int { - let _ = w.write_str(STR_ERROR[errnum as usize]); - } else { - let _ = w.write_fmt(format_args!("Unknown error {}", errnum)); - } - - strerror_buf.as_mut_ptr() as *mut c_char -} - -#[no_mangle] -pub unsafe extern "C" fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: size_t) -> c_int { - let msg = strerror(errnum); - let len = strlen(msg); - - if len >= buflen { - if buflen != 0 { - memcpy(buf as *mut c_void, msg as *const c_void, buflen - 1); - *buf.add(buflen - 1) = 0; - } - return ERANGE as c_int; - } - memcpy(buf as *mut c_void, msg as *const c_void, len + 1); - - 0 -} - -#[no_mangle] -pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t { - unsafe { NulTerminated::new(s) }.count() -} - +/// See . #[no_mangle] pub unsafe extern "C" fn strnlen(s: *const c_char, size: size_t) -> size_t { unsafe { NulTerminated::new(s) }.take(size).count() } +/// Non-POSIX, see . #[no_mangle] pub unsafe extern "C" fn strnlen_s(s: *const c_char, size: size_t) -> size_t { if s.is_null() { @@ -320,60 +444,7 @@ pub unsafe extern "C" fn strnlen_s(s: *const c_char, size: size_t) -> size_t { } } -#[no_mangle] -pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_char { - strncat(s1, s2, usize::MAX) -} - -#[no_mangle] -pub unsafe extern "C" fn strncat(s1: *mut c_char, s2: *const c_char, n: size_t) -> *mut c_char { - let len = strlen(s1 as *const c_char); - let mut i = 0; - while i < n { - let b = *s2.add(i); - if b == 0 { - break; - } - - *s1.add(len + i) = b; - i += 1; - } - *s1.add(len + i) = 0; - - s1 -} - -#[no_mangle] -pub unsafe extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int { - let s1 = core::slice::from_raw_parts(s1 as *const c_uchar, n); - let s2 = core::slice::from_raw_parts(s2 as *const c_uchar, n); - - for (&a, &b) in s1.iter().zip(s2.iter()) { - let val = (a as c_int) - (b as c_int); - if a != b || a == 0 { - return val; - } - } - - 0 -} - -#[no_mangle] -pub unsafe extern "C" fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char { - let mut i = 0; - - while *src.add(i) != 0 && i < n { - *dst.add(i) = *src.add(i); - i += 1; - } - - for i in i..n { - *dst.add(i) = 0; - } - - dst -} - +/// See . #[no_mangle] pub unsafe extern "C" fn strpbrk(s1: *const c_char, s2: *const c_char) -> *mut c_char { let p = s1.add(strcspn(s1, s2)); @@ -384,6 +455,7 @@ pub unsafe extern "C" fn strpbrk(s1: *const c_char, s2: *const c_char) -> *mut c } } +/// See . #[no_mangle] pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char { let len = strlen(s) as isize; @@ -398,6 +470,7 @@ pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char { ptr::null_mut() } +/// See . #[no_mangle] pub unsafe extern "C" fn strsignal(sig: c_int) -> *mut c_char { signal::SIGNAL_STRINGS @@ -406,6 +479,7 @@ pub unsafe extern "C" fn strsignal(sig: c_int) -> *mut c_char { .as_ptr() as *mut c_char } +/// See . #[no_mangle] pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> size_t { inner_strspn(s1, s2, true) @@ -435,21 +509,20 @@ unsafe fn inner_strstr( ptr::null_mut() } +/// See . #[no_mangle] pub unsafe extern "C" fn strstr(haystack: *const c_char, needle: *const c_char) -> *mut c_char { inner_strstr(haystack, needle, !0) } -#[no_mangle] -pub unsafe extern "C" fn strcasestr(haystack: *const c_char, needle: *const c_char) -> *mut c_char { - inner_strstr(haystack, needle, !32) -} +/// See . #[no_mangle] pub unsafe extern "C" fn strtok(s1: *mut c_char, delimiter: *const c_char) -> *mut c_char { static mut HAYSTACK: *mut c_char = ptr::null_mut(); strtok_r(s1, delimiter, &mut HAYSTACK) } +/// See . #[no_mangle] pub unsafe extern "C" fn strtok_r( s: *mut c_char, @@ -486,6 +559,7 @@ pub unsafe extern "C" fn strtok_r( token } +/// See . #[no_mangle] pub unsafe extern "C" fn strxfrm(s1: *mut c_char, s2: *const c_char, n: size_t) -> size_t { // relibc has no locale stuff (yet) @@ -496,24 +570,4 @@ pub unsafe extern "C" fn strxfrm(s1: *mut c_char, s2: *const c_char, n: size_t) len } -#[no_mangle] -pub unsafe extern "C" fn strlcpy(dst: *mut c_char, src: *const c_char, n: size_t) -> size_t { - let mut i = 0; - - while *src.add(i) != 0 && i < n { - *dst.add(i) = *src.add(i); - i += 1; - } - - *dst.add(i) = 0; - - i as size_t -} - -#[no_mangle] -pub unsafe extern "C" fn strlcat(dst: *mut c_char, src: *const c_char, n: size_t) -> size_t { - let len = strlen(dst) as isize; - let d = dst.offset(len); - - strlcpy(d, src, n) -} +// TODO: strxfrm_l