Browse Source

Use libc from crates.io

The libc crate has newlib bindings now, so we don't have to maintain them in-tree anymore
pull/10/head
Fenrir 8 years ago
parent
commit
eec80b496b
  1. 14
      ctr-libc/Cargo.toml
  2. 1
      ctr-libc/README.md
  3. 131
      ctr-libc/src/constants.rs
  4. 39
      ctr-libc/src/functions.rs
  5. 177
      ctr-libc/src/lib.rs
  6. 7
      ctr-std/Cargo.toml
  7. 2
      ctr-std/src/lib.rs
  8. 21
      ctr-std/src/sys/unix/memchr.rs
  9. 230
      ctr-std/src/sys_common/memchr.rs
  10. 5
      ctr-std/src/sys_common/mod.rs
  11. 5
      ctru-sys/Cargo.toml
  12. 2
      ctru-sys/src/lib.rs

14
ctr-libc/Cargo.toml

@ -1,14 +0,0 @@
[package]
name = "ctr-libc"
version = "0.1.0"
authors = ["Fenrir <fenrirwolf@gmail.com>", "The Rust Project Developers"]
license = "MIT/Apache 2.0"
description = """
A library for types and bindings to native C functions found in newlib
for devkitARM
"""
[features]
default = ["use_std"]
use_std = []

1
ctr-libc/README.md

@ -1 +0,0 @@
Extended libc bindings for use with ctr-std. This library is experimental. Use of some functions might result in undefined symbols.

131
ctr-libc/src/constants.rs

@ -1,131 +0,0 @@
// Many of these constants are unused/unnecessary. But let's keep them around for now.
pub const STDIN_FILENO: ::c_int = 0;
pub const STDOUT_FILENO: ::c_int = 1;
pub const STDERR_FILENO: ::c_int = 2;
pub const EPERM: ::c_int = 1;
pub const ENOENT: ::c_int = 2;
pub const ESRCH: ::c_int = 3;
pub const EINTR: ::c_int = 4;
pub const EIO: ::c_int = 5;
pub const ENXIO: ::c_int = 6;
pub const E2BIG: ::c_int = 7;
pub const ENOEXEC: ::c_int = 8;
pub const EBADF: ::c_int = 9;
pub const ECHILD: ::c_int = 10;
pub const EAGAIN: ::c_int = 11;
pub const ENOMEM: ::c_int = 12;
pub const EACCES: ::c_int = 13;
pub const EFAULT: ::c_int = 14;
pub const EBUSY: ::c_int = 16;
pub const EEXIST: ::c_int = 17;
pub const EXDEV: ::c_int = 18;
pub const ENODEV: ::c_int = 19;
pub const ENOTDIR: ::c_int = 20;
pub const EISDIR: ::c_int = 21;
pub const EINVAL: ::c_int = 22;
pub const ENFILE: ::c_int = 23;
pub const EMFILE: ::c_int = 24;
pub const ENOTTY: ::c_int = 25;
pub const ETXTBSY: ::c_int = 26;
pub const EFBIG: ::c_int = 27;
pub const ENOSPC: ::c_int = 28;
pub const ESPIPE: ::c_int = 29;
pub const EROFS: ::c_int = 30;
pub const EMLINK: ::c_int = 31;
pub const EPIPE: ::c_int = 32;
pub const EDOM: ::c_int = 33;
pub const ERANGE: ::c_int = 34;
pub const ENOMSG: ::c_int = 35;
pub const EIDRM: ::c_int = 36;
pub const EDEADLK: ::c_int = 45;
pub const ENOLCK: ::c_int = 46;
pub const ENOSTR: ::c_int = 60;
pub const ENODATA: ::c_int = 61;
pub const ETIME: ::c_int = 62;
pub const ENOSR: ::c_int = 63;
pub const ENOLINK: ::c_int = 67;
pub const EPROTO: ::c_int = 71;
pub const EMULTIHOP: ::c_int = 74;
pub const EBADMSG: ::c_int = 77;
pub const EFTYPE: ::c_int = 79;
pub const ENOSYS: ::c_int = 88;
pub const ENOTEMPTY: ::c_int = 90;
pub const ENAMETOOLONG: ::c_int = 91;
pub const ELOOP: ::c_int = 92;
pub const EOPNOTSUPP: ::c_int = 95;
pub const EPFNOSUPPORT: ::c_int = 96;
pub const ECONNRESET: ::c_int = 104;
pub const ENOBUFS: ::c_int = 105;
pub const EAFNOSUPPORT: ::c_int = 106;
pub const EPROTOTYPE: ::c_int = 107;
pub const ENOTSOCK: ::c_int = 108;
pub const ENOPROTOOPT: ::c_int = 109;
pub const ECONNREFUSED: ::c_int = 111;
pub const EADDRINUSE: ::c_int = 112;
pub const ECONNABORTED: ::c_int = 113;
pub const ENETUNREACH: ::c_int = 114;
pub const ENETDOWN: ::c_int = 115;
pub const ETIMEDOUT: ::c_int = 116;
pub const EHOSTDOWN: ::c_int = 117;
pub const EHOSTUNREACH: ::c_int = 118;
pub const EINPROGRESS: ::c_int = 119;
pub const EALREADY: ::c_int = 120;
pub const EDESTADDRREQ: ::c_int = 121;
pub const EMSGSIZE: ::c_int = 122;
pub const EPROTONOSUPPORT: ::c_int = 123;
pub const EADDRNOTAVAIL: ::c_int = 125;
pub const ENETRESET: ::c_int = 126;
pub const EISCONN: ::c_int = 127;
pub const ENOTCONN: ::c_int = 128;
pub const ETOOMANYREFS: ::c_int = 129;
pub const EDQUOT: ::c_int = 132;
pub const ESTALE: ::c_int = 133;
pub const ENOTSUP: ::c_int = 134;
pub const EILSEQ: ::c_int = 138;
pub const EOVERFLOW: ::c_int = 139;
pub const ECANCELED: ::c_int = 140;
pub const ENOTRECOVERABLE: ::c_int = 141;
pub const EOWNERDEAD: ::c_int = 142;
pub const EWOULDBLOCK: ::c_int = 11;
pub const __ELASTERROR: ::c_int = 2000;
pub const O_RDONLY: ::c_int = 0;
pub const O_WRONLY: ::c_int = 1;
pub const O_RDWR: ::c_int = 2;
pub const O_APPEND: ::c_int = 8;
pub const O_CREAT: ::c_int = 512;
pub const O_TRUNC: ::c_int = 1024;
pub const O_EXCL: ::c_int = 2048;
pub const O_SYNC: ::c_int = 8192;
pub const O_NONBLOCK: ::c_int = 16384;
pub const O_NOCTTY: ::c_int = 32768;
pub const FD_CLOEXEC: ::c_int = 1;
pub const S_IFIFO: ::mode_t = 4096;
pub const S_IFCHR: ::mode_t = 8192;
pub const S_IFDIR: ::mode_t = 16384;
pub const S_IFBLK: ::mode_t = 24576;
pub const S_IFREG: ::mode_t = 32768;
pub const S_IFLNK: ::mode_t = 40960;
pub const S_IFSOCK: ::mode_t = 49152;
pub const S_IFMT: ::mode_t = 61440;
pub const DT_FIFO: u8 = 1;
pub const DT_CHR: u8 = 2;
pub const DT_DIR: u8 = 4;
pub const DT_BLK: u8 = 6;
pub const DT_REG: u8 = 8;
pub const DT_LNK: u8 = 10;
pub const DT_SOCK: u8 = 12;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_ACCMODE: ::c_int = 3;
pub const SEEK_SET: ::c_int = 0;
pub const SEEK_CUR: ::c_int = 1;
pub const SEEK_END: ::c_int = 2;
pub const SIG_IGN: ::sighandler_t = 1 as ::sighandler_t;
pub const SIGPIPE: ::c_int = 13;

39
ctr-libc/src/functions.rs

@ -1,39 +0,0 @@
extern "C" {
pub fn abort() -> !;
pub fn chdir(dir: *const ::c_char) -> ::c_int;
pub fn chmod(path: *const ::c_char, mode: ::mode_t) -> ::c_int;
pub fn close(fd: ::c_int) -> ::c_int;
pub fn closedir(dirp: *mut ::DIR) -> ::c_int;
pub fn exit(status: ::c_int) -> !;
pub fn fchmod(fd: ::c_int, mode: ::mode_t) -> ::c_int;
pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int;
pub fn fdatasync(fd: ::c_int) -> ::c_int;
pub fn free(p: *mut ::c_void);
pub fn fstat(fildes: ::c_int, buf: *mut ::stat) -> ::c_int;
pub fn ftruncate(fd: ::c_int, length: ::off_t) -> ::c_int;
pub fn fsync(fd: ::c_int) -> ::c_int;
pub fn getcwd(buf: *mut ::c_char, size: ::size_t) -> *mut ::c_char;
pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int;
pub fn link(src: *const ::c_char, dst: *const ::c_char) -> ::c_int;
pub fn lstat(path: *const ::c_char, buf: *mut ::stat) -> ::c_int;
pub fn lseek(fd: ::c_int, offset: ::off_t, whence: ::c_int) -> ::off_t;
pub fn memchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void;
pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void;
pub fn mkdir(path: *const ::c_char, mode: ::mode_t) -> ::c_int;
pub fn open(path: *const ::c_char, oflag: ::c_int, ...) -> ::c_int;
pub fn opendir(dirname: *const ::c_char) -> *mut ::DIR;
pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: ::off_t) -> ::ssize_t;
pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: ::off_t) -> ::ssize_t;
pub fn read(fd: ::c_int, puf: *mut ::c_void, count: ::size_t) -> ::ssize_t;
pub fn readlink(path: *const ::c_char, buf: *mut ::c_char, bufsz: ::size_t) -> ::ssize_t;
pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) -> ::c_int;
pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char;
pub fn rename(oldname: *const ::c_char, newname: *const ::c_char) -> ::c_int;
pub fn rmdir(path: *const ::c_char) -> ::c_int;
pub fn signal(signum: ::c_int, handler: ::sighandler_t) -> ::sighandler_t;
pub fn stat(path: *const ::c_char, buf: *mut ::stat) -> ::c_int;
pub fn strlen(cs: *const ::c_char) -> ::size_t;
pub fn symlink(path1: *const ::c_char, path2: *const ::c_char) -> ::c_int;
pub fn unlink(c: *const ::c_char) -> ::c_int;
pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t;
}

177
ctr-libc/src/lib.rs

@ -1,177 +0,0 @@
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(bad_style, overflowing_literals, improper_ctypes, non_camel_case_types)]
#![no_std]
mod constants;
mod functions;
pub use constants::*;
pub use functions::*;
#[link(name = "c")]
#[link(name = "m")]
extern {}
#[repr(u8)]
pub enum c_void {
__variant1,
__variant2,
}
// char is u8 on ARM
pub type c_char = u8;
pub type c_schar = i8;
pub type c_uchar = u8;
pub type c_short = i16;
pub type c_ushort = u16;
pub type c_int = i32;
pub type c_uint = u32;
pub type c_float = f32;
pub type c_double = f64;
pub type c_longlong = i64;
pub type c_ulonglong = u64;
// 4 bytes on ARM
pub type c_long = i32;
pub type c_ulong = u32;
pub type size_t = usize;
pub type ptrdiff_t = isize;
pub type intptr_t = isize;
pub type uintptr_t = usize;
pub type ssize_t = isize;
// devkitARM says wchar_t is 4 bytes. Nintendo's API says it's 2 bytes.
// hope you never have to interact between the two...
pub type wchar_t = c_int;
pub type int8_t = i8;
pub type uint8_t = u8;
pub type int16_t = i16;
pub type uint16_t = u16;
pub type int32_t = i32;
pub type uint32_t = u32;
pub type int64_t = i64;
pub type uint64_t = u64;
pub type time_t = i32;
pub type clockid_t = c_int;
pub type mode_t = u32;
pub type sighandler_t = size_t;
pub type dev_t = u32;
pub type nlink_t = u32;
pub type uid_t = u32;
pub type gid_t = u32;
pub type off_t = i64;
pub type blksize_t = i32;
pub type blkcnt_t = c_ulong;
pub type fsblkcnt_t = uint64_t;
pub type fsfilcnt_t = uint32_t;
pub type ino_t = u32;
pub type suseconds_t = i32;
pub type error_t = c_int;
pub enum timezone {}
pub enum _reent {}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct timeval {
pub tv_sec: time_t,
pub tv_usec: suseconds_t,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct timespec {
pub tv_sec: time_t,
pub tv_nsec: c_long,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct itimerspec {
pub it_interval: timespec,
pub it_value: timespec,
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct tm {
pub tm_sec: c_int,
pub tm_min: c_int,
pub tm_hour: c_int,
pub tm_mday: c_int,
pub tm_mon: c_int,
pub tm_year: c_int,
pub tm_wday: c_int,
pub tm_yday: c_int,
pub tm_isdst: c_int,
}
pub enum DIR {}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_mode: mode_t,
pub st_nlink: nlink_t,
pub st_uid: uid_t,
pub st_gid: gid_t,
pub st_rdev: dev_t,
pub st_size: off_t,
pub st_atime: time_t,
pub st_spare1: c_long,
pub st_mtime: time_t,
pub st_spare2: c_long,
pub st_ctime: time_t,
pub st_spare3: c_long,
pub st_blksize: blksize_t,
pub st_blocks: blkcnt_t,
pub st_spare4: [c_long; 2usize],
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct statvfs {
pub f_bsize: c_ulong,
pub f_frsize: c_ulong,
pub f_blocks: fsblkcnt_t,
pub f_bfree: fsblkcnt_t,
pub f_bavail: fsblkcnt_t,
pub f_files: fsfilcnt_t,
pub f_ffree: fsfilcnt_t,
pub f_favail: fsfilcnt_t,
pub f_fsid: c_ulong,
pub f_flag: c_ulong,
pub f_namemax: c_ulong,
}
#[repr(C)]
#[derive(Copy)]
pub struct dirent {
pub d_ino: ino_t,
pub d_type: c_uchar,
pub d_name: [c_char; 256usize],
}
impl Clone for dirent {
fn clone(&self) -> Self { *self }
}

7
ctr-std/Cargo.toml

@ -6,11 +6,12 @@ license = "MIT/Apache 2.0"
[dependencies.compiler_builtins] [dependencies.compiler_builtins]
git = "https://github.com/rust-lang-nursery/compiler-builtins" git = "https://github.com/rust-lang-nursery/compiler-builtins"
[dependencies.ctr-libc] [dependencies.libc]
path = "../ctr-libc" version = "0.2"
default-features = false
[dependencies.ctru-sys] [dependencies.ctru-sys]
path = "../ctru-sys" path = "../ctru-sys"
[dependencies.alloc_system] [dependencies.alloc_system]
version = "0.1.1" version = "0.1"

2
ctr-std/src/lib.rs

@ -63,12 +63,12 @@ extern crate collections as core_collections;
extern crate alloc; extern crate alloc;
extern crate std_unicode; extern crate std_unicode;
extern crate alloc_system; extern crate alloc_system;
extern crate libc;
// compiler-rt intrinsics // compiler-rt intrinsics
extern crate compiler_builtins; extern crate compiler_builtins;
// 3ds-specific dependencies // 3ds-specific dependencies
extern crate ctr_libc as libc;
extern crate ctru_sys as libctru; extern crate ctru_sys as libctru;
// The standard macros that are not built-in to the compiler. // The standard macros that are not built-in to the compiler.

21
ctr-std/src/sys/unix/memchr.rs

@ -28,24 +28,11 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
} }
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
// turns out that newlib doesn't have memrchr(), so we
#[cfg(target_os = "linux")] // use the fallback version instead
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> { fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
use libc; ::sys_common::memchr::fallback::memrchr(needle, haystack)
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
if haystack.is_empty() {return None}
let p = unsafe {
libc::memrchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len())
};
if p.is_null() {
None
} else {
Some(p as usize - (haystack.as_ptr() as usize))
}
} }
memrchr_specific(needle, haystack) memrchr_specific(needle, haystack)
} }

230
ctr-std/src/sys_common/memchr.rs

@ -0,0 +1,230 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
#[allow(dead_code)]
pub mod fallback {
use cmp;
use mem;
const LO_U64: u64 = 0x0101010101010101;
const HI_U64: u64 = 0x8080808080808080;
// use truncation
const LO_USIZE: usize = LO_U64 as usize;
const HI_USIZE: usize = HI_U64 as usize;
/// Return `true` if `x` contains any zero byte.
///
/// From *Matters Computational*, J. Arndt
///
/// "The idea is to subtract one from each of the bytes and then look for
/// bytes where the borrow propagated all the way to the most significant
/// bit."
#[inline]
fn contains_zero_byte(x: usize) -> bool {
x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
}
#[cfg(target_pointer_width = "32")]
#[inline]
fn repeat_byte(b: u8) -> usize {
let mut rep = (b as usize) << 8 | b as usize;
rep = rep << 16 | rep;
rep
}
#[cfg(target_pointer_width = "64")]
#[inline]
fn repeat_byte(b: u8) -> usize {
let mut rep = (b as usize) << 8 | b as usize;
rep = rep << 16 | rep;
rep = rep << 32 | rep;
rep
}
/// Return the first index matching the byte `a` in `text`.
pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
// Scan for a single byte value by reading two `usize` words at a time.
//
// Split `text` in three parts
// - unaligned initial part, before the first word aligned address in text
// - body, scan by 2 words at a time
// - the last remaining part, < 2 word size
let len = text.len();
let ptr = text.as_ptr();
let usize_bytes = mem::size_of::<usize>();
// search up to an aligned boundary
let align = (ptr as usize) & (usize_bytes- 1);
let mut offset;
if align > 0 {
offset = cmp::min(usize_bytes - align, len);
if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
return Some(index);
}
} else {
offset = 0;
}
// search the body of the text
let repeated_x = repeat_byte(x);
if len >= 2 * usize_bytes {
while offset <= len - 2 * usize_bytes {
unsafe {
let u = *(ptr.offset(offset as isize) as *const usize);
let v = *(ptr.offset((offset + usize_bytes) as isize) as *const usize);
// break if there is a matching byte
let zu = contains_zero_byte(u ^ repeated_x);
let zv = contains_zero_byte(v ^ repeated_x);
if zu || zv {
break;
}
}
offset += usize_bytes * 2;
}
}
// find the byte after the point the body loop stopped
text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
}
/// Return the last index matching the byte `a` in `text`.
pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
// Scan for a single byte value by reading two `usize` words at a time.
//
// Split `text` in three parts
// - unaligned tail, after the last word aligned address in text
// - body, scan by 2 words at a time
// - the first remaining bytes, < 2 word size
let len = text.len();
let ptr = text.as_ptr();
let usize_bytes = mem::size_of::<usize>();
// search to an aligned boundary
let end_align = (ptr as usize + len) & (usize_bytes - 1);
let mut offset;
if end_align > 0 {
offset = if end_align >= len { 0 } else { len - end_align };
if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
return Some(offset + index);
}
} else {
offset = len;
}
// search the body of the text
let repeated_x = repeat_byte(x);
while offset >= 2 * usize_bytes {
unsafe {
let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize);
let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize);
// break if there is a matching byte
let zu = contains_zero_byte(u ^ repeated_x);
let zv = contains_zero_byte(v ^ repeated_x);
if zu || zv {
break;
}
}
offset -= 2 * usize_bytes;
}
// find the byte before the point the body loop stopped
text[..offset].iter().rposition(|elt| *elt == x)
}
// test fallback implementations on all platforms
#[test]
fn matches_one() {
assert_eq!(Some(0), memchr(b'a', b"a"));
}
#[test]
fn matches_begin() {
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
}
#[test]
fn matches_end() {
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
}
#[test]
fn matches_nul() {
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
}
#[test]
fn matches_past_nul() {
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
}
#[test]
fn no_match_empty() {
assert_eq!(None, memchr(b'a', b""));
}
#[test]
fn no_match() {
assert_eq!(None, memchr(b'a', b"xyz"));
}
#[test]
fn matches_one_reversed() {
assert_eq!(Some(0), memrchr(b'a', b"a"));
}
#[test]
fn matches_begin_reversed() {
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
}
#[test]
fn matches_end_reversed() {
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
}
#[test]
fn matches_nul_reversed() {
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
}
#[test]
fn matches_past_nul_reversed() {
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
}
#[test]
fn no_match_empty_reversed() {
assert_eq!(None, memrchr(b'a', b""));
}
#[test]
fn no_match_reversed() {
assert_eq!(None, memrchr(b'a', b"xyz"));
}
#[test]
fn each_alignment_reversed() {
let mut data = [1u8; 64];
let needle = 2;
let pos = 40;
data[pos] = needle;
for start in 0..16 {
assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
}
}
}

5
ctr-std/src/sys_common/mod.rs

@ -27,6 +27,7 @@
pub mod at_exit_imp; pub mod at_exit_imp;
pub mod condvar; pub mod condvar;
pub mod io; pub mod io;
pub mod memchr;
pub mod mutex; pub mod mutex;
pub mod poison; pub mod poison;
pub mod remutex; pub mod remutex;
@ -76,10 +77,6 @@ pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())} if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())}
} }
macro_rules! rtabort {
($($t:tt)*) => (::sys_common::util::abort(format_args!($($t)*)))
}
// Computes (value*numer)/denom without overflow, as long as both // Computes (value*numer)/denom without overflow, as long as both
// (numer*denom) and the overall result fit into i64 (which is the case // (numer*denom) and the overall result fit into i64 (which is the case
// for our time conversions). // for our time conversions).

5
ctru-sys/Cargo.toml

@ -4,5 +4,6 @@ version = "0.3.0"
authors = ["Ronald Kinard <furyhunter600@gmail.com>"] authors = ["Ronald Kinard <furyhunter600@gmail.com>"]
license = "https://en.wikipedia.org/wiki/Zlib_License" license = "https://en.wikipedia.org/wiki/Zlib_License"
[dependencies] [dependencies.libc]
ctr-libc = { path = "../ctr-libc" } version = "0.2"
default-features = false

2
ctru-sys/src/lib.rs

@ -8,7 +8,7 @@
#![allow(non_camel_case_types, non_snake_case, overflowing_literals)] #![allow(non_camel_case_types, non_snake_case, overflowing_literals)]
#![feature(untagged_unions)] #![feature(untagged_unions)]
extern crate ctr_libc as libc; extern crate libc;
pub mod applets; pub mod applets;
pub mod console; pub mod console;

Loading…
Cancel
Save