Skip to content

Commit 2f36e86

Browse files
Wassasineldruin
authored andcommitted
Add strncpy.
1 parent aab6275 commit 2f36e86

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This crate basically came about so that the [nrfxlib](https://github.com/NordicP
1212
* atoi
1313
* strcmp
1414
* strncmp
15+
* strncpy
1516
* strlen
1617
* strtol
1718
* strstr

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ pub use self::strcmp::strcmp;
1919
mod strncmp;
2020
pub use self::strncmp::strncmp;
2121

22+
mod strncpy;
23+
pub use self::strncpy::strncpy;
24+
2225
mod strlen;
2326
pub use self::strlen::strlen;
2427

src/strncpy.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Rust implementation of C library function `strncpy`
2+
//!
3+
//! Copyright (c) Wouter 'Wassasin' Geraedts 2021
4+
//! Licensed under the Blue Oak Model Licence 1.0.0
5+
6+
use crate::CChar;
7+
8+
/// Rust implementation of C library function `strncmp`. Passing NULL
9+
/// (core::ptr::null()) gives undefined behaviour.
10+
#[no_mangle]
11+
pub unsafe extern "C" fn strncpy(
12+
dest: *mut CChar,
13+
src: *const CChar,
14+
count: usize,
15+
) -> *const CChar {
16+
let mut i = 0isize;
17+
while i < count as isize {
18+
*dest.offset(i) = *src.offset(i);
19+
let c = *dest.offset(i);
20+
i += 1;
21+
if c == 0 {
22+
break;
23+
}
24+
}
25+
for j in i..count as isize {
26+
*dest.offset(j) = 0;
27+
}
28+
dest
29+
}
30+
31+
#[cfg(test)]
32+
mod test {
33+
use super::*;
34+
35+
#[test]
36+
fn short() {
37+
let src = b"hi\0";
38+
let mut dest = *b"abcdef"; // no null terminator
39+
let result = unsafe { strncpy(dest.as_mut_ptr(), src.as_ptr(), 5) };
40+
assert_eq!(
41+
unsafe { core::slice::from_raw_parts(result, 5) },
42+
*b"hi\0\0\0"
43+
);
44+
}
45+
46+
#[test]
47+
fn two() {
48+
let src = b"hi\0";
49+
let mut dest = [0u8; 2]; // no space for null terminator
50+
let result = unsafe { strncpy(dest.as_mut_ptr(), src.as_ptr(), 2) };
51+
assert_eq!(unsafe { core::slice::from_raw_parts(result, 2) }, b"hi");
52+
}
53+
}

0 commit comments

Comments
 (0)