From 62ec524dba1833396963ad995a2af3f51fdbe4e4 Mon Sep 17 00:00:00 2001 From: sander Date: Fri, 15 Mar 2024 09:45:17 +0100 Subject: [PATCH 1/4] add strncasecmp --- Cargo.toml | 2 ++ src/lib.rs | 4 ++++ src/strncasecmp.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/strncasecmp.rs diff --git a/Cargo.toml b/Cargo.toml index 79a379e..87122e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ all = [ "abs", "strcmp", "strncmp", + "strncasecmp", "strcpy", "strncpy", "strlen", @@ -46,6 +47,7 @@ all = [ abs = [] strcmp = [] strncmp = [] +strncasecmp = [] strcpy = [] strncpy = [] strlen = [] diff --git a/src/lib.rs b/src/lib.rs index e5db6f4..12f5030 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,6 +43,10 @@ mod strncmp; #[cfg(feature = "strncmp")] pub use self::strncmp::strncmp; +mod strncasecmp; +#[cfg(feature = "strncasecmp")] +pub use self::strncasecmp::strncasecmp; + mod strcpy; #[cfg(feature = "strcpy")] pub use self::strcpy::strcpy; diff --git a/src/strncasecmp.rs b/src/strncasecmp.rs new file mode 100644 index 0000000..7041755 --- /dev/null +++ b/src/strncasecmp.rs @@ -0,0 +1,53 @@ +//! Rust implementation of C library function `strncasecmp` +//! +//! Licensed under the Blue Oak Model Licence 1.0.0 + +use crate::{CChar, CInt}; + +/// Rust implementation of C library function `strncasecmp`. Passing NULL +/// (core::ptr::null()) gives undefined behaviour. +#[cfg_attr(feature = "strncasecmp", no_mangle)] +pub unsafe extern "C" fn strncasecmp(s1: *const CChar, s2: *const CChar, n: usize) -> CInt { + for i in 0..n as isize { + let s1_i = s1.offset(i); + let s2_i = s2.offset(i); + + let val = (*s1_i).to_ascii_lowercase() as CInt - (*s2_i).to_ascii_lowercase() as CInt; + if val != 0 || *s1_i == 0 { + return val; + } + } + 0 +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn matches() { + let a = b"abc\0"; + let b = b"AbCDEF\0"; + let result = unsafe { strncasecmp(a.as_ptr(), b.as_ptr(), 3) }; + // Match! + assert_eq!(result, 0); + } + + #[test] + fn no_match() { + let a = b"123\0"; + let b = b"x1234\0"; + let result = unsafe { strncasecmp(a.as_ptr(), b.as_ptr(), 3) }; + // No match, first string first + assert!(result < 0); + } + + #[test] + fn no_match2() { + let a = b"bbbbb\0"; + let b = b"aaaaa\0"; + let result = unsafe { strncasecmp(a.as_ptr(), b.as_ptr(), 3) }; + // No match, second string first + assert!(result > 0); + } +} From 9671ce9453d33dee831d0d7cb68153e8a804262a Mon Sep 17 00:00:00 2001 From: sander Date: Fri, 15 Mar 2024 09:47:56 +0100 Subject: [PATCH 2/4] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79bf4ed..2f4c59c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* None +* [#23] - Add `strncasecmp` ## v0.3.0 (2022-10-18) From 83499ec24ffdf7a3c1311fc238555fa7fa441223 Mon Sep 17 00:00:00 2001 From: sander Date: Fri, 15 Mar 2024 16:33:36 +0100 Subject: [PATCH 3/4] strncasecmp: use `add` instead of `offset` to avoid casting --- src/strncasecmp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/strncasecmp.rs b/src/strncasecmp.rs index 7041755..d8cc45b 100644 --- a/src/strncasecmp.rs +++ b/src/strncasecmp.rs @@ -8,9 +8,9 @@ use crate::{CChar, CInt}; /// (core::ptr::null()) gives undefined behaviour. #[cfg_attr(feature = "strncasecmp", no_mangle)] pub unsafe extern "C" fn strncasecmp(s1: *const CChar, s2: *const CChar, n: usize) -> CInt { - for i in 0..n as isize { - let s1_i = s1.offset(i); - let s2_i = s2.offset(i); + for i in 0..n { + let s1_i = s1.add(i); + let s2_i = s2.add(i); let val = (*s1_i).to_ascii_lowercase() as CInt - (*s2_i).to_ascii_lowercase() as CInt; if val != 0 || *s1_i == 0 { From e733587364dc8cefe678d80f0d6a9053482a9185 Mon Sep 17 00:00:00 2001 From: sander Date: Fri, 15 Mar 2024 16:40:49 +0100 Subject: [PATCH 4/4] README: add strncasecmp --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a5e000a..ac155e0 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ This crate basically came about so that the [nrfxlib](https://github.com/NordicP * isupper * strcmp * strncmp +* strncasecmp * strcpy * strncpy * strlen