diff --git a/src/librlibc/lib.rs b/src/librlibc/lib.rs index 3e45964cd12..c7295125f42 100644 --- a/src/librlibc/lib.rs +++ b/src/librlibc/lib.rs @@ -21,22 +21,26 @@ //! the system libc library. #![crate_name = "rlibc"] +#![experimental] #![license = "MIT/ASL2"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/master/")] -#![feature(intrinsics)] +#![feature(intrinsics, phase)] #![no_std] -#![experimental] // This library defines the builtin functions, so it would be a shame for // LLVM to optimize these function calls to themselves! #![no_builtins] -#[cfg(test)] extern crate std; #[cfg(test)] extern crate native; +#[cfg(test)] extern crate test; +#[cfg(test)] extern crate debug; + +#[cfg(test)] #[phase(plugin, link)] extern crate std; +#[cfg(test)] #[phase(plugin, link)] extern crate core; // Require the offset intrinsics for LLVM to properly optimize the // implementations below. If pointer arithmetic is done through integers the @@ -102,4 +106,100 @@ pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: uint) -> i32 { return 0; } -#[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows +#[cfg(test)] +mod test { + use core::option::{Some, None}; + use core::iter::Iterator; + use core::collections::Collection; + use core::str::StrSlice; + use core::slice::{MutableVector, ImmutableVector}; + + use super::{memcmp, memset, memcpy, memmove}; + + #[test] + fn memcmp_single_byte_pointers() { + unsafe { + assert_eq!(memcmp(&0xFAu8, &0xFAu8, 1), 0x00); + assert!(memcmp(&0xEFu8, &0xFEu8, 1) < 0x00); + } + } + + #[test] + fn memcmp_strings() { + { + let (x, z) = ("Hello!", "Good Bye."); + let l = x.len(); + unsafe { + assert_eq!(memcmp(x.as_ptr(), x.as_ptr(), l), 0); + assert!(memcmp(x.as_ptr(), z.as_ptr(), l) > 0); + assert!(memcmp(z.as_ptr(), x.as_ptr(), l) < 0); + } + } + { + let (x, z) = ("hey!", "hey."); + let l = x.len(); + unsafe { + assert!(memcmp(x.as_ptr(), z.as_ptr(), l) < 0); + } + } + } + + #[test] + fn memset_single_byte_pointers() { + let mut x: u8 = 0xFF; + unsafe { + memset(&mut x, 0xAA, 1); + assert_eq!(x, 0xAA); + memset(&mut x, 0x00, 1); + assert_eq!(x, 0x00); + x = 0x01; + memset(&mut x, 0x12, 0); + assert_eq!(x, 0x01); + } + } + + #[test] + fn memset_array() { + let mut buffer = [b'X', .. 100]; + unsafe { + memset(buffer.as_mut_ptr(), b'#' as i32, buffer.len()); + } + for byte in buffer.iter() { assert_eq!(*byte, b'#'); } + } + + #[test] + fn memcpy_and_memcmp_arrays() { + let (src, mut dst) = ([b'X', .. 100], [b'Y', .. 100]); + unsafe { + assert!(memcmp(src.as_ptr(), dst.as_ptr(), 100) != 0); + let _ = memcpy(dst.as_mut_ptr(), src.as_ptr(), 100); + assert_eq!(memcmp(src.as_ptr(), dst.as_ptr(), 100), 0); + } + } + + #[test] + fn memmove_overlapping() { + { + let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ]; + unsafe { + memmove(&mut buffer[4], &buffer[0], 6); + let mut i = 0; + for byte in b"0123012345".iter() { + assert_eq!(buffer[i], *byte); + i += 1; + } + } + } + { + let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ]; + unsafe { + memmove(&mut buffer[0], &buffer[4], 6); + let mut i = 0; + for byte in b"4567896789".iter() { + assert_eq!(buffer[i], *byte); + i += 1; + } + } + } + } +}