From b06557f71cfe24195a58964819d28a3b2f3dfe4a Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Thu, 21 Jul 2022 13:04:43 +0200 Subject: [PATCH 01/11] Added strcpy --- Cargo.toml | 2 +- src/lib.rs | 3 +++ src/strcpy.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/strcpy.rs diff --git a/Cargo.toml b/Cargo.toml index 17a0214..50cfc33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "tinyrlibc" version = "0.2.2" authors = ["Jonathan 'theJPster' Pallant "] -edition = "2018" +edition = "2021" description = "Tiny, incomplete C library for bare-metal targets, written in Stable (but Unsafe) Rust" license-file = "LICENCES.md" readme = "README.md" diff --git a/src/lib.rs b/src/lib.rs index ccc13aa..2dbdebc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,9 @@ pub use self::strncmp::strncmp; mod strncpy; pub use self::strncpy::strncpy; +mod strcpy; +pub use self::strcpy::strcpy; + mod strlen; pub use self::strlen::strlen; diff --git a/src/strcpy.rs b/src/strcpy.rs new file mode 100644 index 0000000..2bf357c --- /dev/null +++ b/src/strcpy.rs @@ -0,0 +1,47 @@ +//! Rust implementation of C library function `strcpy` +//! +//! Copyright (c) Dion Dokter 2022 +//! Licensed under the Blue Oak Model Licence 1.0.0 + +use crate::CChar; + +/// Rust implementation of C library function `strcpy`. Passing NULL +/// (core::ptr::null()) gives undefined behaviour. +#[no_mangle] +pub unsafe extern "C" fn strcpy(dest: *mut CChar, src: *const CChar) -> *const CChar { + let mut i = 0isize; + loop { + *dest.offset(i) = *src.offset(i); + + if *src.offset(i) == '\0' as u8 { + break; + } + + i += 1; + } + dest +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn short() { + let src = b"hi\0"; + let mut dest = *b"abcdef"; // no null terminator + let result = unsafe { strcpy(dest.as_mut_ptr(), src.as_ptr()) }; + assert_eq!( + unsafe { core::slice::from_raw_parts(result, 6) }, + *b"hi\0def" + ); + } + + #[test] + fn two() { + let src = b"hi\0"; + let mut dest = [0u8; 3]; + let result = unsafe { strcpy(dest.as_mut_ptr(), src.as_ptr()) }; + assert_eq!(unsafe { core::slice::from_raw_parts(result, 3) }, b"hi\0"); + } +} From 8d925c4b4047735363d9762720c0506393e6992b Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Thu, 21 Jul 2022 13:06:08 +0200 Subject: [PATCH 02/11] Clippy fixes --- build.rs | 2 -- src/strcpy.rs | 2 +- src/strstr.rs | 2 +- src/strtol.rs | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index e2415ba..d861a84 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,3 @@ -use cc; - fn main() { // Build our snprintf substitute (which has to be C as Rust doesn't do varargs) cc::Build::new() diff --git a/src/strcpy.rs b/src/strcpy.rs index 2bf357c..fcf67f7 100644 --- a/src/strcpy.rs +++ b/src/strcpy.rs @@ -13,7 +13,7 @@ pub unsafe extern "C" fn strcpy(dest: *mut CChar, src: *const CChar) -> *const C loop { *dest.offset(i) = *src.offset(i); - if *src.offset(i) == '\0' as u8 { + if *src.offset(i) == b'\0' { break; } diff --git a/src/strstr.rs b/src/strstr.rs index 64eb58e..cb4ac9e 100644 --- a/src/strstr.rs +++ b/src/strstr.rs @@ -17,7 +17,7 @@ pub unsafe extern "C" fn strstr(haystack: *const CChar, needle: *const CChar) -> } let mut len = 0; for (inner_idx, nec) in CStringIter::new(needle).enumerate() { - let hsc = *haystack_trim.offset(inner_idx as isize); + let hsc = *haystack_trim.add(inner_idx); if hsc != nec { break; } diff --git a/src/strtol.rs b/src/strtol.rs index f3dbf01..602c7e3 100644 --- a/src/strtol.rs +++ b/src/strtol.rs @@ -15,7 +15,7 @@ use crate::{CChar, CLong, CStringIter}; pub unsafe extern "C" fn strtol(s: *const CChar) -> CLong { let mut result: CLong = 0; for c in CStringIter::new(s) { - if c >= b'0' && c <= b'9' { + if (b'0'..=b'9').contains(&c) { result *= 10; result += (c - b'0') as CLong; } else { From 3cd319d0b9e86138e6be71c810a4f20d234d58fa Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 26 Aug 2022 10:56:34 +0200 Subject: [PATCH 03/11] Added strtoul --- src/lib.rs | 3 + src/strtoul.rs | 150 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 src/strtoul.rs diff --git a/src/lib.rs b/src/lib.rs index 2dbdebc..49d3930 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,9 @@ pub use self::strlen::strlen; mod strtol; pub use self::strtol::strtol; +mod strtoul; +pub use self::strtoul::strtoul; + mod strstr; pub use self::strstr::strstr; diff --git a/src/strtoul.rs b/src/strtoul.rs new file mode 100644 index 0000000..05e7dfe --- /dev/null +++ b/src/strtoul.rs @@ -0,0 +1,150 @@ +use crate::{CChar, CInt, CLong, CULong}; + +#[no_mangle] +pub unsafe extern "C" fn strtoul( + nptr: *const CChar, + endptr: *mut *const CChar, + mut base: CInt, +) -> CULong { + let mut s = nptr; + + let mut c = *s; + s = s.offset(1); + while isspace(c) { + c = *s; + s = s.offset(1); + } + + let neg = if c == b'-' { + c = *s; + s = s.offset(1); + true + } else { + if c == b'+' { + c = *s; + s = s.offset(1); + } + false + }; + + if (base == 0 || base == 16) && c == b'0' && (*s == b'x' || *s == b'X') { + c = *s.offset(1); + s = s.offset(2); + base = 16; + } + + if base == 0 { + base = if c == b'0' { 8 } else { 10 }; + } + + let cutoff = CULong::MAX / base as CULong; + let cutlim = CULong::MAX % base as CULong; + + let mut acc = 0; + let mut any = 0; + + loop { + if isdigit(c) { + c -= b'0'; + } else if isalpha(c) { + c -= if isupper(c) { b'A' - 10 } else { b'a' - 10 }; + } else { + break; + } + + if c as CInt >= base { + break; + } + + if any < 0 { + c = *s; + s = s.offset(1); + continue; + } + + if acc > cutoff || (acc == cutoff && c as CULong > cutlim) { + any = -1; + acc = CULong::MAX; + } else { + any = 1; + acc *= base as CULong; + acc += c as CULong; + } + + c = *s; + s = s.offset(1); + } + if neg && any > 0 { + acc = -(acc as CLong) as _; + } + + if !endptr.is_null() { + (*endptr) = if any != 0 { + s.offset(-1) + } else { + core::ptr::null() + }; + } + + acc +} + +fn isspace(argument: CChar) -> bool { + const SPACE_CHARACTERS: [u8; 6] = [b' ', b'\n', b'\t', b'v', b'f', b'r']; + SPACE_CHARACTERS + .into_iter() + .any(|space_char| argument == space_char) +} + +fn isdigit(argument: CChar) -> bool { + (b'0'..=b'9').contains(&argument) +} + +fn isalpha(argument: CChar) -> bool { + (b'a'..=b'z').contains(&argument) || (b'A'..=b'Z').contains(&argument) +} + +fn isupper(argument: CChar) -> bool { + (b'A'..=b'Z').contains(&argument) +} + +#[cfg(test)] +mod tests { + use core::ptr::null_mut; + + use super::*; + + #[test] + fn parse_multi_string() { + let string = b"10 200000000000000000000000000000 30 -40\0"; + + let mut s = string.as_ptr(); + + let results = [ + (10, unsafe { s.offset(2) }), + (u32::MAX, unsafe { s.offset(33) }), + (30, unsafe { s.offset(36) }), + (-40i32 as u32, unsafe { s.offset(40) }), + ]; + + for (result_number, result_ptr) in results { + let number = unsafe { strtoul(s, &mut s as *mut _, 10) }; + + assert_eq!(number, result_number); + assert_eq!(s, result_ptr); + } + } + + #[test] + fn parse_hex() { + assert_eq!( + unsafe { strtoul(b"0xAA123\0".as_ptr(), null_mut(), 0) }, + 0xAA123 + ); + assert_eq!(unsafe { strtoul(b"0X00\0".as_ptr(), null_mut(), 0) }, 0x00); + assert_eq!( + unsafe { strtoul(b"-0x123456F\0".as_ptr(), null_mut(), 0) }, + (-0x123456Fi32) as u32 + ); + } +} From bb20ae18c24086b4176601472fbbc5f618c7bc72 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 20 Sep 2022 13:13:22 +0200 Subject: [PATCH 04/11] snprintf can now handle precision specifiers for strings --- src/snprintf.c | 46 +++++++++++++++++++++++++++++++++++++--- src/snprintf.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/snprintf.c b/src/snprintf.c index d954e04..1ae2502 100644 --- a/src/snprintf.c +++ b/src/snprintf.c @@ -62,6 +62,11 @@ extern int32_t itoa(int64_t i, char* s, size_t s_len, uint8_t radix); */ extern int32_t utoa(uint64_t i, char* s, size_t s_len, uint8_t radix); +/** + * This is provided by `strtoul.rs`. It converts a string to a long. + */ +extern unsigned long int strtoul(const char* str, char** endptr, int base); + /* ======================================================================== * * * Public Function Definitions @@ -91,7 +96,7 @@ extern int32_t utoa(uint64_t i, char* s, size_t s_len, uint8_t radix); * - f (decimal floating point) * - g (the shorter of %e and %f) * - G (the shorter of %E and %f) - * - qualifiers: L, width, precision, -, +, space-pad, zero-pad, etc + * - qualifiers: L, width, (non-string) precision, -, +, space-pad, zero-pad, etc * * @param str the output buffer to write to * @param size the size of the output buffer @@ -107,6 +112,8 @@ int vsnprintf( bool is_escape = false; int is_long = 0; bool is_size_t = false; + unsigned long precision = -1; + while ( *fmt ) { if ( is_escape ) @@ -315,12 +322,40 @@ int vsnprintf( // Render %s { const char *s = va_arg( ap, const char* ); - for ( const char* p = s; *p != '\0'; p++ ) + unsigned long count = precision; + + while (count > 0 && *s != '\0') { - write_output( *p, str, size, &written ); + write_output(*s, str, size, &written); + + s++; + if (precision != -1) { + count--; + } } } break; + case '.': + // Render a precision specifier + { + // Next up is either a number or a '*' that signifies that the number is in the arguments list + char next = *++fmt; + + if (next == '*') + { + precision = va_arg( ap, int ); + } + else + { + precision = strtoul(fmt, &fmt, 10); + // Strtoul sets the fmt pointer to the char after the number, + // however the code expects the char before that. + fmt--; + } + + is_escape = true; + } + break; case '%': write_output( '%', str, size, &written ); break; @@ -329,6 +364,11 @@ int vsnprintf( break; } fmt++; + + if (!is_escape) { + // Reset precision if it hasn't just been assigned + precision = -1; + } } else { diff --git a/src/snprintf.rs b/src/snprintf.rs index 4ef3e6e..cb502ac 100644 --- a/src/snprintf.rs +++ b/src/snprintf.rs @@ -16,7 +16,9 @@ mod test { let mut buf = [b'\0'; 32]; assert_eq!( unsafe { snprintf(buf.as_mut_ptr(), buf.len(), "Hi\0".as_ptr()) }, - 2 + 2, + "{}", + String::from_utf8_lossy(&buf).escape_debug(), ); assert_eq!( unsafe { strcmp(buf.as_ptr() as *const u8, b"Hi\0" as *const u8) }, @@ -37,7 +39,9 @@ mod test { "World\0".as_ptr(), ) }, - 13 + 13, + "{}", + String::from_utf8_lossy(&buf).escape_debug(), ); assert_eq!( unsafe { strcmp(buf.as_ptr() as *const u8, b"Hello, World!\0" as *const u8) }, @@ -86,7 +90,9 @@ mod test { 0xcafe1234u64, ) }, - 53 + 53, + "{}", + String::from_utf8_lossy(&buf).escape_debug(), ); assert_eq!( unsafe { @@ -120,7 +126,9 @@ mod test { 0xcafe1234u64, ) }, - 53 + 53, + "{}", + String::from_utf8_lossy(&buf).escape_debug(), ); assert_eq!( unsafe { @@ -132,4 +140,44 @@ mod test { 0 ); } + + #[test] + fn non_null_terminated_with_length() { + let mut buf = [b'\0'; 64]; + assert_eq!( + unsafe { + snprintf( + buf.as_mut_ptr(), + buf.len(), + "%.*s\0".as_ptr(), + 5, + "01234567890123456789\0".as_ptr(), + ) + }, + 5, + "{}", + String::from_utf8_lossy(&buf).escape_debug(), + ); + assert_eq!( + unsafe { strcmp(buf.as_ptr() as *const u8, b"01234\0" as *const u8,) }, + 0 + ); + assert_eq!( + unsafe { + snprintf( + buf.as_mut_ptr(), + buf.len(), + "%.10s\0".as_ptr(), + "01234567890123456789\0".as_ptr(), + ) + }, + 10, + "{}", + String::from_utf8_lossy(&buf).escape_debug(), + ); + assert_eq!( + unsafe { strcmp(buf.as_ptr() as *const u8, b"0123456789\0" as *const u8,) }, + 0 + ); + } } From 3a9af53a0aba7055d8023120a8f1b922b939ff18 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 21 Oct 2022 10:09:22 +0200 Subject: [PATCH 05/11] Added docs --- src/strtoul.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/strtoul.rs b/src/strtoul.rs index 486929b..64a1635 100644 --- a/src/strtoul.rs +++ b/src/strtoul.rs @@ -1,5 +1,13 @@ use crate::{CChar, CInt, CLong, CULong}; +/// Rust implementation of C library function [`strtoul`](https://cplusplus.com/reference/cstdlib/strtoul/). +/// +/// Passing NULL (core::ptr::null()) gives undefined behaviour. +/// +/// Convert a string to an unsigned long integer. +/// +/// Ignores `locale' stuff. Assumes that the upper and lower case +/// alphabets and digits are each contiguous. #[no_mangle] pub unsafe extern "C" fn strtoul( nptr: *const CChar, From db039c80604c0cb3601d39c2f98838af53035672 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 24 Oct 2022 13:26:15 +0200 Subject: [PATCH 06/11] Added license information --- LICENCES.md | 31 ++++++++++++++++++++++++++++++- src/strtoul.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/LICENCES.md b/LICENCES.md index 7a84c0d..afa49d8 100644 --- a/LICENCES.md +++ b/LICENCES.md @@ -52,4 +52,33 @@ No contributor can revoke this license. ***As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this -software or this license, under any kind of legal claim.*** \ No newline at end of file +software or this license, under any kind of legal claim.*** + +# Copyright (c) 1990 Regents of the University of California + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. [rescinded 22 July 1999] +4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/src/strtoul.rs b/src/strtoul.rs index 64a1635..498570c 100644 --- a/src/strtoul.rs +++ b/src/strtoul.rs @@ -1,3 +1,34 @@ +//! Copyright (c) 1990 Regents of the University of California. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! 1. Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! 2. Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! 3. [rescinded 22 July 1999] +//! 4. Neither the name of the University nor the names of its contributors +//! may be used to endorse or promote products derived from this software +//! without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +//! ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +//! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +//! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +//! OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +//! HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +//! OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +//! SUCH DAMAGE. +//! +//! Translated from https://github.com/gcc-mirror/gcc/blob/97d1ed67fc6a5773c8c00875bfa3616a457cf5f9/libiberty/strtoul.c + + use crate::{CChar, CInt, CLong, CULong}; /// Rust implementation of C library function [`strtoul`](https://cplusplus.com/reference/cstdlib/strtoul/). From 943344287bc589368460ee0d061cad7493485039 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 24 Oct 2022 13:26:32 +0200 Subject: [PATCH 07/11] fmt --- src/strtoul.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/strtoul.rs b/src/strtoul.rs index 498570c..df0370d 100644 --- a/src/strtoul.rs +++ b/src/strtoul.rs @@ -25,16 +25,15 @@ //! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY //! OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF //! SUCH DAMAGE. -//! +//! //! Translated from https://github.com/gcc-mirror/gcc/blob/97d1ed67fc6a5773c8c00875bfa3616a457cf5f9/libiberty/strtoul.c - use crate::{CChar, CInt, CLong, CULong}; /// Rust implementation of C library function [`strtoul`](https://cplusplus.com/reference/cstdlib/strtoul/). /// /// Passing NULL (core::ptr::null()) gives undefined behaviour. -/// +/// /// Convert a string to an unsigned long integer. /// /// Ignores `locale' stuff. Assumes that the upper and lower case From f8a39b61a26a1248c8faecf7683da059275e5c3a Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 24 Oct 2022 13:34:49 +0200 Subject: [PATCH 08/11] Tested with invalid non-null-terminated input strings --- src/atoi.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atoi.rs b/src/atoi.rs index 0ab4d55..56642f5 100644 --- a/src/atoi.rs +++ b/src/atoi.rs @@ -10,9 +10,9 @@ use crate::{strtol, CChar, CInt, CLong}; /// /// ``` /// use tinyrlibc::atoi; -/// assert_eq!(unsafe { atoi(b"123".as_ptr()) }, 123); -/// assert_eq!(unsafe { atoi(b"123x".as_ptr()) }, 123); -/// assert_eq!(unsafe { atoi(b"".as_ptr()) }, 0); +/// assert_eq!(unsafe { atoi(b"123\0".as_ptr()) }, 123); +/// assert_eq!(unsafe { atoi(b"123x\0".as_ptr()) }, 123); +/// assert_eq!(unsafe { atoi(b"\0".as_ptr()) }, 0); /// ``` #[no_mangle] pub unsafe extern "C" fn atoi(s: *const CChar) -> CInt { From 27bab2b2fc1b53f10500d743a799665aab866c58 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Mon, 24 Oct 2022 21:01:43 +0200 Subject: [PATCH 09/11] Fixed isspace --- src/strtoul.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/strtoul.rs b/src/strtoul.rs index df0370d..504b4eb 100644 --- a/src/strtoul.rs +++ b/src/strtoul.rs @@ -128,7 +128,11 @@ pub unsafe extern "C" fn strtoul( } fn isspace(argument: CChar) -> bool { - const SPACE_CHARACTERS: [u8; 6] = [b' ', b'\n', b'\t', b'v', b'f', b'r']; + // Rust doesn't support "\v" + const VERTICAL_TAB: u8 = 0x0B; + // Rust doesn't support "\f" + const FEED: u8 = 0x0C; + const SPACE_CHARACTERS: [u8; 6] = [b' ', b'\n', b'\t', VERTICAL_TAB, FEED, b'\r']; SPACE_CHARACTERS .into_iter() .any(|space_char| argument == space_char) From fa93fb21f9f568cc613be07d168070bb98f6eb14 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 25 Oct 2022 13:33:52 +0200 Subject: [PATCH 10/11] Nicer space character check --- src/strtoul.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/strtoul.rs b/src/strtoul.rs index 504b4eb..46d8023 100644 --- a/src/strtoul.rs +++ b/src/strtoul.rs @@ -133,9 +133,8 @@ fn isspace(argument: CChar) -> bool { // Rust doesn't support "\f" const FEED: u8 = 0x0C; const SPACE_CHARACTERS: [u8; 6] = [b' ', b'\n', b'\t', VERTICAL_TAB, FEED, b'\r']; - SPACE_CHARACTERS - .into_iter() - .any(|space_char| argument == space_char) + + SPACE_CHARACTERS.contains(&argument) } fn isdigit(argument: CChar) -> bool { From 75bb2be83c50593f04146d6738b6bdc6abd09c99 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Thu, 10 Nov 2022 10:56:54 +0100 Subject: [PATCH 11/11] fmt --- src/strtoul.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strtoul.rs b/src/strtoul.rs index 46d8023..ba6fc36 100644 --- a/src/strtoul.rs +++ b/src/strtoul.rs @@ -133,7 +133,7 @@ fn isspace(argument: CChar) -> bool { // Rust doesn't support "\f" const FEED: u8 = 0x0C; const SPACE_CHARACTERS: [u8; 6] = [b' ', b'\n', b'\t', VERTICAL_TAB, FEED, b'\r']; - + SPACE_CHARACTERS.contains(&argument) }