Skip to content

Commit

Permalink
Add strspn.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanpallant committed Nov 22, 2024
1 parent 3ae2f1d commit 057fc14
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ all = [
"strncmp",
"strncpy",
"strrchr",
"strspn",
"strstr",
"strtoimax",
"strtol",
Expand Down Expand Up @@ -71,6 +72,7 @@ strncasecmp = []
strncmp = []
strncpy = []
strrchr = []
strspn = []
strstr = []
strtoimax = []
strtol = []
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ mod strncasecmp;
mod strncmp;
mod strncpy;
mod strrchr;
mod strspn;
mod strstr;
mod strtol;

Expand Down Expand Up @@ -79,6 +80,8 @@ pub use self::strncmp::strncmp;
pub use self::strncpy::strncpy;
#[cfg(feature = "strrchr")]
pub use self::strrchr::strrchr;
#[cfg(feature = "strspn")]
pub use self::strspn::strspn;
#[cfg(feature = "strstr")]
pub use self::strstr::strstr;
#[cfg(feature = "strtoimax")]
Expand Down
83 changes: 83 additions & 0 deletions src/strspn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Rust implementation of C library function `strspn`
//!
//! Copyright (c) Ferrous Systems UK Ltd
//! Licensed under the Blue Oak Model Licence 1.0.0
use crate::{CChar, CInt};

/// Rust implementation of C library function `strspn`
#[cfg_attr(feature = "strspn", no_mangle)]
pub unsafe extern "C" fn strspn(s: *const CChar, charset: *const CChar) -> usize {
if s.is_null() {
return 0;
}
if charset.is_null() {
return 0;
}

let s = unsafe { core::ffi::CStr::from_ptr(s.cast()) };

let charset = unsafe { core::ffi::CStr::from_ptr(charset.cast()) };

for (idx, b) in s.to_bytes().iter().enumerate() {
if !is_c_in_charset(*b, charset) {
return idx;
}
}

s.count_bytes()

Check failure on line 28 in src/strspn.rs

View workflow job for this annotation

GitHub Actions / clippy

use of unstable library feature 'cstr_count_bytes'

error[E0658]: use of unstable library feature 'cstr_count_bytes' --> src/strspn.rs:28:4 | 28 | s.count_bytes() | ^^^^^^^^^^^ | = note: see issue #114441 <https://github.com/rust-lang/rust/issues/114441> for more information
}

fn is_c_in_charset(c: u8, charset: &core::ffi::CStr) -> bool {
for b in charset.to_bytes() {
if c == *b {
return true;
}
}
false
}

#[cfg(test)]
mod test {
#[test]
fn complete() {
let charset = c"0123456789";
let s = c"987654321";
assert_eq!(
unsafe { super::strspn(s.as_ptr().cast(), charset.as_ptr().cast()) },
9
);
}

#[test]
fn subset() {
let charset = c"0123456789";
let s = c"98xx7654321";
assert_eq!(
unsafe { super::strspn(s.as_ptr().cast(), charset.as_ptr().cast()) },
2
);
}

#[test]
fn empty_charset() {
let charset = c"";
let s = c"AABBCCDD";
assert_eq!(
unsafe { super::strspn(s.as_ptr().cast(), charset.as_ptr().cast()) },
0
);
}

#[test]
fn empty_string() {
let charset = c"0123456789";
let s = c"";
assert_eq!(
unsafe { super::strspn(s.as_ptr().cast(), charset.as_ptr().cast()) },
0
);
}
}

// End of file

0 comments on commit 057fc14

Please sign in to comment.