Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

* [#7] - Add `strtoul` and `strcpy`

[#7]: https://github.com/rust-embedded-community/tinyrlibc/pull/7

## v0.2.2 (2022-03-17)

* [#5] - Swap `i32` to `CInt` in `strchr`.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ This crate basically came about so that the [nrfxlib](https://github.com/NordicP
* atoi
* strcmp
* strncmp
* strcpy
* strncpy
* strlen
* strtol
* strtoul
* strstr
* strchr
* snprintf
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub use self::strcmp::strcmp;
mod strncmp;
pub use self::strncmp::strncmp;

mod strcpy;
pub use self::strcpy::strcpy;

mod strncpy;
pub use self::strncpy::strncpy;

Expand All @@ -28,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;

Expand Down
48 changes: 48 additions & 0 deletions src/strcpy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! Rust implementation of C library function `strcpy`
//!
//! 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 = 0;
loop {
*dest.offset(i) = *src.offset(i);
let c = *dest.offset(i);
if c == 0 {
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, 5) },
*b"hi\0de"
);
}

#[test]
fn two() {
let src = b"hi\0";
let mut dest = [0u8; 2]; // no space for null terminator
let result = unsafe { strcpy(dest.as_mut_ptr(), src.as_ptr()) };
assert_eq!(unsafe { core::slice::from_raw_parts(result, 2) }, b"hi");
}
}
68 changes: 68 additions & 0 deletions src/strtoul.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! Rust implementation of C library function `strtoul`
//!
//! Copyright (c) Jonathan 'theJPster' Pallant 2019
//! Licensed under the Blue Oak Model Licence 1.0.0

use crate::{CChar, CULong, CStringIter};

/// Rust implementation of C library function `strtoul`.
///
/// Takes a null-terminated string and interprets it as a decimal integer.
/// This integer is returned as a `CULong`. Parsing stops when the first
/// non-digit ASCII byte is seen. If no valid ASCII digit bytes are seen, this
/// function returns zero.
#[no_mangle]
pub unsafe extern "C" fn strtoul(s: *const CChar) -> CULong {
let mut result: CULong = 0;
for c in CStringIter::new(s) {
if c >= b'0' && c <= b'9' {
result *= 10;
result += (c - b'0') as CULong;
} else {
break;
}
}
result
}

#[cfg(test)]
mod test {
use super::strtoul;

#[test]
fn empty() {
let result = unsafe { strtoul(b"\0".as_ptr()) };
assert_eq!(result, 0);
}

#[test]
fn non_digit() {
let result = unsafe { strtoul(b"1234x\0".as_ptr()) };
assert_eq!(result, 1234);
}

#[test]
fn bad_number() {
let result = unsafe { strtoul(b"x\0".as_ptr()) };
assert_eq!(result, 0);
}

#[test]
fn one() {
let result = unsafe { strtoul(b"1\0".as_ptr()) };
assert_eq!(result, 1);
}

#[test]
fn hundredish() {
let result = unsafe { strtoul(b"123\0".as_ptr()) };
assert_eq!(result, 123);
}

#[test]
fn big_long() {
let result = unsafe { strtoul(b"2147483647\0".as_ptr()) };
assert_eq!(result, 2147483647);
}

}