Fenrir
8 years ago
84 changed files with 4569 additions and 2750 deletions
@ -1,2 +1,10 @@
@@ -1,2 +1,10 @@
|
||||
[target.3ds.dependencies] |
||||
collections = {} |
||||
[dependencies.collections] |
||||
|
||||
[dependencies.ctr-libc] |
||||
path = "ctr-libc" |
||||
default-features = false |
||||
stage = 0 |
||||
|
||||
[dependencies.std] |
||||
path = "ctr-std" |
||||
stage = 1 |
||||
|
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
[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 = [] |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
Extended libc bindings for use with ctr-std. This library is experimental. Use of some functions might result in undefined symbols. |
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
// 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 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; |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
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; |
||||
} |
@ -0,0 +1,190 @@
@@ -0,0 +1,190 @@
|
||||
// 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)] |
||||
|
||||
// Attributes needed when building as part of the standard library
|
||||
#![cfg_attr(stdbuild, feature(no_std, core, core_slice_ext, staged_api, custom_attribute, cfg_target_vendor))] |
||||
#![cfg_attr(stdbuild, feature(link_cfg))] |
||||
#![cfg_attr(stdbuild, no_std)] |
||||
#![cfg_attr(stdbuild, staged_api)] |
||||
#![cfg_attr(stdbuild, allow(warnings))] |
||||
#![cfg_attr(stdbuild, unstable(feature = "libc",
|
||||
reason = "use `libc` from crates.io", |
||||
issue = "27783"))] |
||||
|
||||
#![cfg_attr(not(feature = "use_std"), no_std)] |
||||
|
||||
#[cfg(all(not(stdbuild), not(dox), feature = "use_std"))] |
||||
extern crate std as core; |
||||
|
||||
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 } |
||||
} |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
{ |
||||
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", |
||||
"llvm-target": "arm-none-eabihf", |
||||
"linker": "arm-none-eabi-gcc", |
||||
"ar": "arm-none-eabi-ar", |
||||
"target-endian": "little", |
||||
"target-pointer-width": "32", |
||||
"target-family": "unix", |
||||
"arch": "arm", |
||||
"os": "linux", |
||||
"env": "newlib", |
||||
"cpu": "mpcore", |
||||
"features": "+vfp2", |
||||
"relocation-model": "static", |
||||
"executables": true, |
||||
"exe-suffix": ".elf", |
||||
"panic-strategy": "abort", |
||||
"pre-link-args": [ |
||||
"-specs=3dsx.specs", |
||||
"-march=armv6k", |
||||
"-mtune=mpcore", |
||||
"-mfloat-abi=hard", |
||||
"-mtp=soft" |
||||
], |
||||
"post-link-args": [ |
||||
"-lc", |
||||
"-lm", |
||||
"-lsysbase", |
||||
"-lc" |
||||
] |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
[package] |
||||
name = "std" |
||||
version = "0.0.0" |
||||
license = "MIT/Apache 2.0" |
||||
|
||||
[dependencies.compiler_builtins] |
||||
git = "https://github.com/rust-lang-nursery/compiler-builtins" |
||||
|
||||
[dependencies.alloc_system] |
||||
version = "0.1.1" |
||||
|
||||
[dependencies.spin] |
||||
version = "0.4" |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
A work-in-progress port of the Rust Standard Library for the Nintendo 3DS, based on [ctrulib](https://github.com/smealum/ctrulib/) and the [devkitARM](http://devkitPro.org) toolchain. |
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
[dependencies.collections] |
||||
|
||||
[dependencies.ctr-libc] |
||||
path = "../ctr-libc" |
||||
default-features = false |
||||
stage = 1 |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
//! Utilities related to FFI bindings.
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use self::c_str::{CString, CStr, NulError, IntoStringError}; |
||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")] |
||||
pub use self::c_str::{FromBytesWithNulError}; |
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use self::os_str::{OsString, OsStr}; |
||||
|
||||
mod c_str; |
||||
mod os_str; |
@ -0,0 +1,174 @@
@@ -0,0 +1,174 @@
|
||||
#![feature(alloc)] |
||||
#![feature(allow_internal_unstable)] |
||||
#![feature(box_syntax)] |
||||
#![feature(collections)] |
||||
#![feature(const_fn)] |
||||
#![feature(compiler_builtins_lib)] |
||||
#![feature(core_intrinsics)] |
||||
#![feature(char_escape_debug)] |
||||
#![feature(float_extras)] |
||||
#![feature(fused)] |
||||
#![feature(int_error_internals)] |
||||
#![feature(lang_items)] |
||||
#![feature(macro_reexport)] |
||||
#![feature(optin_builtin_traits)] |
||||
#![feature(prelude_import)] |
||||
#![feature(raw)] |
||||
#![feature(slice_concat_ext)] |
||||
#![feature(slice_patterns)] |
||||
#![feature(staged_api)] |
||||
#![feature(str_internals)] |
||||
#![feature(thread_local)] |
||||
#![feature(try_from)] |
||||
#![feature(unicode)] |
||||
#![feature(zero_one)] |
||||
#![allow(non_camel_case_types, dead_code, unused_features)] |
||||
#![no_std] |
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
#[prelude_import] |
||||
#[allow(unused)] |
||||
use prelude::v1::*; |
||||
|
||||
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
|
||||
unreachable, unimplemented, write, writeln, try)] |
||||
extern crate core as __core; |
||||
|
||||
#[macro_use] |
||||
#[macro_reexport(vec, format)] |
||||
extern crate collections as core_collections; |
||||
|
||||
extern crate alloc; |
||||
extern crate std_unicode; |
||||
extern crate alloc_system; |
||||
|
||||
// compiler-rt intrinsics
|
||||
extern crate compiler_builtins; |
||||
|
||||
// 3ds-specific dependencies
|
||||
extern crate ctr_libc as libc; |
||||
|
||||
// stealing spin's mutex implementation for now
|
||||
extern crate spin; |
||||
|
||||
// The standard macros that are not built-in to the compiler.
|
||||
#[macro_use] |
||||
mod macros; |
||||
|
||||
// The Rust prelude
|
||||
pub mod prelude; |
||||
|
||||
// Public module declarations and reexports
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::any; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::cell; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::clone; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::cmp; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::convert; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::default; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::hash; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::intrinsics; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::iter; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::marker; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::mem; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::ops; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::ptr; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::raw; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::result; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::option; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::isize; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::i8; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::i16; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::i32; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::i64; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::usize; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::u8; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::u16; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::u32; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::u64; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use alloc::boxed; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use alloc::rc; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core_collections::borrow; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core_collections::fmt; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core_collections::slice; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core_collections::str; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core_collections::string; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core_collections::vec; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use std_unicode::char; |
||||
|
||||
pub mod f32; |
||||
pub mod f64; |
||||
|
||||
pub mod ascii; |
||||
pub mod error; |
||||
pub mod ffi; |
||||
pub mod io; |
||||
pub mod num; |
||||
pub mod os; |
||||
pub mod path; |
||||
pub mod sync; |
||||
|
||||
// Platform-abstraction modules
|
||||
#[macro_use] |
||||
mod sys_common; |
||||
mod sys; |
||||
|
||||
// Private support modules
|
||||
mod panicking; |
||||
mod memchr; |
||||
|
||||
// The runtime entry point and a few unstable public functions used by the
|
||||
// compiler
|
||||
pub mod rt; |
||||
|
||||
// NOTE: These two are "undefined" symbols that LLVM emits but that
|
||||
// we never actually use
|
||||
#[doc(hidden)] |
||||
|
||||
#[stable(feature = "3ds", since = "1.0.0")] |
||||
#[no_mangle] |
||||
pub unsafe extern "C" fn __aeabi_unwind_cpp_pr0() { |
||||
intrinsics::unreachable() |
||||
} |
||||
|
||||
#[stable(feature = "3ds", since = "1.0.0")] |
||||
#[doc(hidden)] |
||||
#[no_mangle] |
||||
pub unsafe extern "C" fn __aeabi_unwind_cpp_pr1() { |
||||
intrinsics::unreachable() |
||||
} |
@ -0,0 +1,481 @@
@@ -0,0 +1,481 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
//! Standard library macros
|
||||
//!
|
||||
//! This modules contains a set of macros which are exported from the standard
|
||||
//! library. Each macro is available for use when linking against the standard
|
||||
//! library.
|
||||
|
||||
/// The entry point for panic of Rust threads.
|
||||
///
|
||||
/// This macro is used to inject panic into a Rust thread, causing the thread to
|
||||
/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
|
||||
/// and the single-argument form of the `panic!` macro will be the value which
|
||||
/// is transmitted.
|
||||
///
|
||||
/// The multi-argument form of this macro panics with a string and has the
|
||||
/// `format!` syntax for building a string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```should_panic
|
||||
/// # #![allow(unreachable_code)]
|
||||
/// panic!();
|
||||
/// panic!("this is a terrible mistake!");
|
||||
/// panic!(4); // panic with the value of 4 to be collected elsewhere
|
||||
/// panic!("this is a {} {message}", "fancy", message = "message");
|
||||
/// ```
|
||||
#[macro_export] |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[allow_internal_unstable] |
||||
macro_rules! panic { |
||||
() => ({ |
||||
panic!("explicit panic") |
||||
}); |
||||
($msg:expr) => ({ |
||||
$crate::rt::begin_panic($msg, { |
||||
// static requires less code at runtime, more constant data
|
||||
static _FILE_LINE: (&'static str, u32) = (file!(), line!()); |
||||
&_FILE_LINE |
||||
}) |
||||
}); |
||||
($fmt:expr, $($arg:tt)+) => ({ |
||||
$crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), { |
||||
// The leading _'s are to avoid dead code warnings if this is
|
||||
// used inside a dead function. Just `#[allow(dead_code)]` is
|
||||
// insufficient, since the user may have
|
||||
// `#[forbid(dead_code)]` and which cannot be overridden.
|
||||
static _FILE_LINE: (&'static str, u32) = (file!(), line!()); |
||||
&_FILE_LINE |
||||
}) |
||||
}); |
||||
} |
||||
|
||||
/// Macro for printing to the standard output.
|
||||
///
|
||||
/// Equivalent to the `println!` macro except that a newline is not printed at
|
||||
/// the end of the message.
|
||||
///
|
||||
/// Note that stdout is frequently line-buffered by default so it may be
|
||||
/// necessary to use `io::stdout().flush()` to ensure the output is emitted
|
||||
/// immediately.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if writing to `io::stdout()` fails.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::io::{self, Write};
|
||||
///
|
||||
/// print!("this ");
|
||||
/// print!("will ");
|
||||
/// print!("be ");
|
||||
/// print!("on ");
|
||||
/// print!("the ");
|
||||
/// print!("same ");
|
||||
/// print!("line ");
|
||||
///
|
||||
/// io::stdout().flush().unwrap();
|
||||
///
|
||||
/// print!("this string has a newline, why not choose println! instead?\n");
|
||||
///
|
||||
/// io::stdout().flush().unwrap();
|
||||
/// ```
|
||||
#[macro_export] |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[allow_internal_unstable] |
||||
macro_rules! print { |
||||
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*))); |
||||
} |
||||
|
||||
/// Macro for printing to the standard output, with a newline. On all
|
||||
/// platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
|
||||
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
|
||||
///
|
||||
/// Use the `format!` syntax to write data to the standard output.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if writing to `io::stdout()` fails.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// println!();
|
||||
/// println!("hello there!");
|
||||
/// println!("format {} arguments", "some");
|
||||
/// ```
|
||||
#[macro_export] |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
macro_rules! println { |
||||
() => (print!("\n")); |
||||
($fmt:expr) => (print!(concat!($fmt, "\n"))); |
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); |
||||
} |
||||
|
||||
/// A macro to select an event from a number of receivers.
|
||||
///
|
||||
/// This macro is used to wait for the first event to occur on a number of
|
||||
/// receivers. It places no restrictions on the types of receivers given to
|
||||
/// this macro, this can be viewed as a heterogeneous select.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(mpsc_select)]
|
||||
///
|
||||
/// use std::thread;
|
||||
/// use std::sync::mpsc;
|
||||
///
|
||||
/// // two placeholder functions for now
|
||||
/// fn long_running_thread() {}
|
||||
/// fn calculate_the_answer() -> u32 { 42 }
|
||||
///
|
||||
/// let (tx1, rx1) = mpsc::channel();
|
||||
/// let (tx2, rx2) = mpsc::channel();
|
||||
///
|
||||
/// thread::spawn(move|| { long_running_thread(); tx1.send(()).unwrap(); });
|
||||
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
|
||||
///
|
||||
/// select! {
|
||||
/// _ = rx1.recv() => println!("the long running thread finished first"),
|
||||
/// answer = rx2.recv() => {
|
||||
/// println!("the answer was: {}", answer.unwrap());
|
||||
/// }
|
||||
/// }
|
||||
/// # drop(rx1.recv());
|
||||
/// # drop(rx2.recv());
|
||||
/// ```
|
||||
///
|
||||
/// For more information about select, see the `std::sync::mpsc::Select` structure.
|
||||
#[macro_export] |
||||
#[unstable(feature = "mpsc_select", issue = "27800")] |
||||
macro_rules! select { |
||||
( |
||||
$($name:pat = $rx:ident.$meth:ident() => $code:expr),+ |
||||
) => ({ |
||||
use $crate::sync::mpsc::Select; |
||||
let sel = Select::new(); |
||||
$( let mut $rx = sel.handle(&$rx); )+ |
||||
unsafe { |
||||
$( $rx.add(); )+ |
||||
} |
||||
let ret = sel.wait(); |
||||
$( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+ |
||||
{ unreachable!() } |
||||
}) |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
macro_rules! assert_approx_eq { |
||||
($a:expr, $b:expr) => ({ |
||||
let (a, b) = (&$a, &$b); |
||||
assert!((*a - *b).abs() < 1.0e-6, |
||||
"{} is not approximately equal to {}", *a, *b); |
||||
}) |
||||
} |
||||
|
||||
/// Built-in macros to the compiler itself.
|
||||
///
|
||||
/// These macros do not have any corresponding definition with a `macro_rules!`
|
||||
/// macro, but are documented here. Their implementations can be found hardcoded
|
||||
/// into libsyntax itself.
|
||||
#[cfg(dox)] |
||||
pub mod builtin { |
||||
/// The core macro for formatted string creation & output.
|
||||
///
|
||||
/// This macro produces a value of type [`fmt::Arguments`]. This value can be
|
||||
/// passed to the functions in [`std::fmt`] for performing useful functions.
|
||||
/// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
|
||||
/// proxied through this one.
|
||||
///
|
||||
/// For more information, see the documentation in [`std::fmt`].
|
||||
///
|
||||
/// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
|
||||
/// [`std::fmt`]: ../std/fmt/index.html
|
||||
/// [`format!`]: ../std/macro.format.html
|
||||
/// [`write!`]: ../std/macro.write.html
|
||||
/// [`println!`]: ../std/macro.println.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// let s = fmt::format(format_args!("hello {}", "world"));
|
||||
/// assert_eq!(s, format!("hello {}", "world"));
|
||||
///
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({ |
||||
/* compiler built-in */ |
||||
}) } |
||||
|
||||
/// Inspect an environment variable at compile time.
|
||||
///
|
||||
/// This macro will expand to the value of the named environment variable at
|
||||
/// compile time, yielding an expression of type `&'static str`.
|
||||
///
|
||||
/// If the environment variable is not defined, then a compilation error
|
||||
/// will be emitted. To not emit a compile error, use the `option_env!`
|
||||
/// macro instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let path: &'static str = env!("PATH");
|
||||
/// println!("the $PATH variable at the time of compiling was: {}", path);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Optionally inspect an environment variable at compile time.
|
||||
///
|
||||
/// If the named environment variable is present at compile time, this will
|
||||
/// expand into an expression of type `Option<&'static str>` whose value is
|
||||
/// `Some` of the value of the environment variable. If the environment
|
||||
/// variable is not present, then this will expand to `None`.
|
||||
///
|
||||
/// A compile time error is never emitted when using this macro regardless
|
||||
/// of whether the environment variable is present or not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let key: Option<&'static str> = option_env!("SECRET_KEY");
|
||||
/// println!("the secret key might be: {:?}", key);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Concatenate identifiers into one identifier.
|
||||
///
|
||||
/// This macro takes any number of comma-separated identifiers, and
|
||||
/// concatenates them all into one, yielding an expression which is a new
|
||||
/// identifier. Note that hygiene makes it such that this macro cannot
|
||||
/// capture local variables. Also, as a general rule, macros are only
|
||||
/// allowed in item, statement or expression position. That means while
|
||||
/// you may use this macro for referring to existing variables, functions or
|
||||
/// modules etc, you cannot define a new one with it.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(concat_idents)]
|
||||
///
|
||||
/// # fn main() {
|
||||
/// fn foobar() -> u32 { 23 }
|
||||
///
|
||||
/// let f = concat_idents!(foo, bar);
|
||||
/// println!("{}", f());
|
||||
///
|
||||
/// // fn concat_idents!(new, fun, name) { } // not usable in this way!
|
||||
/// # }
|
||||
/// ```
|
||||
#[unstable(feature = "concat_idents_macro", issue = "29599")] |
||||
#[macro_export] |
||||
macro_rules! concat_idents { |
||||
($($e:ident),*) => ({ /* compiler built-in */ }) |
||||
} |
||||
|
||||
/// Concatenates literals into a static string slice.
|
||||
///
|
||||
/// This macro takes any number of comma-separated literals, yielding an
|
||||
/// expression of type `&'static str` which represents all of the literals
|
||||
/// concatenated left-to-right.
|
||||
///
|
||||
/// Integer and floating point literals are stringified in order to be
|
||||
/// concatenated.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let s = concat!("test", 10, 'b', true);
|
||||
/// assert_eq!(s, "test10btrue");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// A macro which expands to the line number on which it was invoked.
|
||||
///
|
||||
/// The expanded expression has type `u32`, and the returned line is not
|
||||
/// the invocation of the `line!()` macro itself, but rather the first macro
|
||||
/// invocation leading up to the invocation of the `line!()` macro.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let current_line = line!();
|
||||
/// println!("defined on line: {}", current_line);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! line { () => ({ /* compiler built-in */ }) } |
||||
|
||||
/// A macro which expands to the column number on which it was invoked.
|
||||
///
|
||||
/// The expanded expression has type `u32`, and the returned column is not
|
||||
/// the invocation of the `column!()` macro itself, but rather the first macro
|
||||
/// invocation leading up to the invocation of the `column!()` macro.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let current_col = column!();
|
||||
/// println!("defined on column: {}", current_col);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! column { () => ({ /* compiler built-in */ }) } |
||||
|
||||
/// A macro which expands to the file name from which it was invoked.
|
||||
///
|
||||
/// The expanded expression has type `&'static str`, and the returned file
|
||||
/// is not the invocation of the `file!()` macro itself, but rather the
|
||||
/// first macro invocation leading up to the invocation of the `file!()`
|
||||
/// macro.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let this_file = file!();
|
||||
/// println!("defined in file: {}", this_file);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! file { () => ({ /* compiler built-in */ }) } |
||||
|
||||
/// A macro which stringifies its argument.
|
||||
///
|
||||
/// This macro will yield an expression of type `&'static str` which is the
|
||||
/// stringification of all the tokens passed to the macro. No restrictions
|
||||
/// are placed on the syntax of the macro invocation itself.
|
||||
///
|
||||
/// Note that the expanded results of the input tokens may change in the
|
||||
/// future. You should be careful if you rely on the output.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let one_plus_one = stringify!(1 + 1);
|
||||
/// assert_eq!(one_plus_one, "1 + 1");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Includes a utf8-encoded file as a string.
|
||||
///
|
||||
/// The file is located relative to the current file. (similarly to how
|
||||
/// modules are found)
|
||||
///
|
||||
/// This macro will yield an expression of type `&'static str` which is the
|
||||
/// contents of the file.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// let secret_key = include_str!("secret-key.ascii");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Includes a file as a reference to a byte array.
|
||||
///
|
||||
/// The file is located relative to the current file. (similarly to how
|
||||
/// modules are found)
|
||||
///
|
||||
/// This macro will yield an expression of type `&'static [u8; N]` which is
|
||||
/// the contents of the file.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// let secret_key = include_bytes!("secret-key.bin");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Expands to a string that represents the current module path.
|
||||
///
|
||||
/// The current module path can be thought of as the hierarchy of modules
|
||||
/// leading back up to the crate root. The first component of the path
|
||||
/// returned is the name of the crate currently being compiled.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// mod test {
|
||||
/// pub fn foo() {
|
||||
/// assert!(module_path!().ends_with("test"));
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// test::foo();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! module_path { () => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Boolean evaluation of configuration flags.
|
||||
///
|
||||
/// In addition to the `#[cfg]` attribute, this macro is provided to allow
|
||||
/// boolean expression evaluation of configuration flags. This frequently
|
||||
/// leads to less duplicated code.
|
||||
///
|
||||
/// The syntax given to this macro is the same syntax as [the `cfg`
|
||||
/// attribute](../reference.html#conditional-compilation).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let my_directory = if cfg!(windows) {
|
||||
/// "windows-specific-directory"
|
||||
/// } else {
|
||||
/// "unix-directory"
|
||||
/// };
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) } |
||||
|
||||
/// Parse a file as an expression or an item according to the context.
|
||||
///
|
||||
/// The file is located relative to the current file. (similarly to how
|
||||
/// modules are found)
|
||||
///
|
||||
/// Using this macro is often a bad idea, because if the file is
|
||||
/// parsed as an expression, it is going to be placed in the
|
||||
/// surrounding code unhygenically. This could result in variables
|
||||
/// or functions being different from what the file expected if
|
||||
/// there are variables or functions that have the same name in
|
||||
/// the current file.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```ignore
|
||||
/// fn foo() {
|
||||
/// include!("/path/to/a/file")
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[macro_export] |
||||
macro_rules! include { ($file:expr) => ({ /* compiler built-in */ }) } |
||||
} |
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
// 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
|
||||
|
||||
/// A safe interface to `memchr`.
|
||||
///
|
||||
/// Returns the index corresponding to the first occurrence of `needle` in
|
||||
/// `haystack`, or `None` if one is not found.
|
||||
///
|
||||
/// memchr reduces to super-optimized machine code at around an order of
|
||||
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
|
||||
/// (See benchmarks.)
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This shows how to find the first position of a byte in a byte string.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use memchr::memchr;
|
||||
///
|
||||
/// let haystack = b"the quick brown fox";
|
||||
/// assert_eq!(memchr(b'k', haystack), Some(8));
|
||||
/// ```
|
||||
#[inline] |
||||
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
::sys::memchr::memchr(needle, haystack) |
||||
} |
||||
|
||||
/// A safe interface to `memrchr`.
|
||||
///
|
||||
/// Returns the index corresponding to the last occurrence of `needle` in
|
||||
/// `haystack`, or `None` if one is not found.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This shows how to find the last position of a byte in a byte string.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use memchr::memrchr;
|
||||
///
|
||||
/// let haystack = b"the quick brown fox";
|
||||
/// assert_eq!(memrchr(b'o', haystack), Some(17));
|
||||
/// ```
|
||||
#[inline] |
||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
::sys::memchr::memrchr(needle, haystack) |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
// test the implementations for the current plattform
|
||||
use super::{memchr, memrchr}; |
||||
|
||||
#[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() { |
||||
let mut data = [1u8; 64]; |
||||
let needle = 2; |
||||
let pos = 40; |
||||
data[pos] = needle; |
||||
for start in 0..16 { |
||||
assert_eq!(Some(pos - start), memchr(needle, &data[start..])); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
// 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.
|
||||
|
||||
//! OS-specific functionality.
|
||||
|
||||
#![stable(feature = "os", since = "1.0.0")] |
||||
#![allow(missing_docs, bad_style)] |
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use sys::ext as unix; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,146 @@
@@ -0,0 +1,146 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
//! The Rust Prelude.
|
||||
//!
|
||||
//! Rust comes with a variety of things in its standard library. However, if
|
||||
//! you had to manually import every single thing that you used, it would be
|
||||
//! very verbose. But importing a lot of things that a program never uses isn't
|
||||
//! good either. A balance needs to be struck.
|
||||
//!
|
||||
//! The *prelude* is the list of things that Rust automatically imports into
|
||||
//! every Rust program. It's kept as small as possible, and is focused on
|
||||
//! things, particularly traits, which are used in almost every single Rust
|
||||
//! program.
|
||||
//!
|
||||
//! On a technical level, Rust inserts
|
||||
//!
|
||||
//! ```ignore
|
||||
//! extern crate std;
|
||||
//! ```
|
||||
//!
|
||||
//! into the crate root of every crate, and
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use std::prelude::v1::*;
|
||||
//! ```
|
||||
//!
|
||||
//! into every module.
|
||||
//!
|
||||
//! # Other preludes
|
||||
//!
|
||||
//! Preludes can be seen as a pattern to make using multiple types more
|
||||
//! convenient. As such, you'll find other preludes in the standard library,
|
||||
//! such as [`std::io::prelude`]. Various libraries in the Rust ecosystem may
|
||||
//! also define their own preludes.
|
||||
//!
|
||||
//! [`std::io::prelude`]: ../io/prelude/index.html
|
||||
//!
|
||||
//! The difference between 'the prelude' and these other preludes is that they
|
||||
//! are not automatically `use`'d, and must be imported manually. This is still
|
||||
//! easier than importing all of their constituent components.
|
||||
//!
|
||||
//! # Prelude contents
|
||||
//!
|
||||
//! The current version of the prelude (version 1) lives in
|
||||
//! [`std::prelude::v1`], and reexports the following.
|
||||
//!
|
||||
//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`]}. The marker
|
||||
//! traits indicate fundamental properties of types.
|
||||
//! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}. Various
|
||||
//! operations for both destructors and overloading `()`.
|
||||
//! * [`std::mem`]::[`drop`], a convenience function for explicitly dropping a
|
||||
//! value.
|
||||
//! * [`std::boxed`]::[`Box`], a way to allocate values on the heap.
|
||||
//! * [`std::borrow`]::[`ToOwned`], The conversion trait that defines
|
||||
//! [`to_owned()`], the generic method for creating an owned type from a
|
||||
//! borrowed type.
|
||||
//! * [`std::clone`]::[`Clone`], the ubiquitous trait that defines [`clone()`],
|
||||
//! the method for producing a copy of a value.
|
||||
//! * [`std::cmp`]::{[`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] }. The
|
||||
//! comparison traits, which implement the comparison operators and are often
|
||||
//! seen in trait bounds.
|
||||
//! * [`std::convert`]::{[`AsRef`], [`AsMut`], [`Into`], [`From`]}. Generic
|
||||
//! conversions, used by savvy API authors to create overloaded methods.
|
||||
//! * [`std::default`]::[`Default`], types that have default values.
|
||||
//! * [`std::iter`]::{[`Iterator`], [`Extend`], [`IntoIterator`],
|
||||
//! [`DoubleEndedIterator`], [`ExactSizeIterator`]}. Iterators of various
|
||||
//! kinds.
|
||||
//! * [`std::option`]::[`Option`]::{`self`, `Some`, `None`}. A type which
|
||||
//! expresses the presence or absence of a value. This type is so commonly
|
||||
//! used, its variants are also exported.
|
||||
//! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions
|
||||
//! that may succeed or fail. Like [`Option`], its variants are exported as
|
||||
//! well.
|
||||
//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical
|
||||
//! reasons, but shouldn't have to exist. It provides a few useful methods on
|
||||
//! slices.
|
||||
//! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings.
|
||||
//! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated
|
||||
//! vector.
|
||||
//!
|
||||
//! [`AsMut`]: ../convert/trait.AsMut.html
|
||||
//! [`AsRef`]: ../convert/trait.AsRef.html
|
||||
//! [`Box`]: ../boxed/struct.Box.html
|
||||
//! [`Clone`]: ../clone/trait.Clone.html
|
||||
//! [`Copy`]: ../marker/trait.Copy.html
|
||||
//! [`Default`]: ../default/trait.Default.html
|
||||
//! [`DoubleEndedIterator`]: ../iter/trait.DoubleEndedIterator.html
|
||||
//! [`Drop`]: ../ops/trait.Drop.html
|
||||
//! [`Eq`]: ../cmp/trait.Eq.html
|
||||
//! [`ExactSizeIterator`]: ../iter/trait.ExactSizeIterator.html
|
||||
//! [`Extend`]: ../iter/trait.Extend.html
|
||||
//! [`FnMut`]: ../ops/trait.FnMut.html
|
||||
//! [`FnOnce`]: ../ops/trait.FnOnce.html
|
||||
//! [`Fn`]: ../ops/trait.Fn.html
|
||||
//! [`From`]: ../convert/trait.From.html
|
||||
//! [`IntoIterator`]: ../iter/trait.IntoIterator.html
|
||||
//! [`Into`]: ../convert/trait.Into.html
|
||||
//! [`Iterator`]: ../iter/trait.Iterator.html
|
||||
//! [`Option`]: ../option/enum.Option.html
|
||||
//! [`Ord`]: ../cmp/trait.Ord.html
|
||||
//! [`PartialEq`]: ../cmp/trait.PartialEq.html
|
||||
//! [`PartialOrd`]: ../cmp/trait.PartialOrd.html
|
||||
//! [`Result`]: ../result/enum.Result.html
|
||||
//! [`Send`]: ../marker/trait.Send.html
|
||||
//! [`Sized`]: ../marker/trait.Sized.html
|
||||
//! [`SliceConcatExt`]: ../slice/trait.SliceConcatExt.html
|
||||
//! [`String`]: ../string/struct.String.html
|
||||
//! [`Sync`]: ../marker/trait.Sync.html
|
||||
//! [`ToOwned`]: ../borrow/trait.ToOwned.html
|
||||
//! [`ToString`]: ../string/trait.ToString.html
|
||||
//! [`Vec`]: ../vec/struct.Vec.html
|
||||
//! [`clone()`]: ../clone/trait.Clone.html#tymethod.clone
|
||||
//! [`drop`]: ../mem/fn.drop.html
|
||||
//! [`std::borrow`]: ../borrow/index.html
|
||||
//! [`std::boxed`]: ../boxed/index.html
|
||||
//! [`std::clone`]: ../clone/index.html
|
||||
//! [`std::cmp`]: ../cmp/index.html
|
||||
//! [`std::convert`]: ../convert/index.html
|
||||
//! [`std::default`]: ../default/index.html
|
||||
//! [`std::iter`]: ../iter/index.html
|
||||
//! [`std::marker`]: ../marker/index.html
|
||||
//! [`std::mem`]: ../mem/index.html
|
||||
//! [`std::ops`]: ../ops/index.html
|
||||
//! [`std::option`]: ../option/index.html
|
||||
//! [`std::prelude::v1`]: v1/index.html
|
||||
//! [`std::result`]: ../result/index.html
|
||||
//! [`std::slice`]: ../slice/index.html
|
||||
//! [`std::string`]: ../string/index.html
|
||||
//! [`std::vec`]: ../vec/index.html
|
||||
//! [`to_owned()`]: ../borrow/trait.ToOwned.html#tymethod.to_owned
|
||||
//! [book-closures]: ../../book/closures.html
|
||||
//! [book-dtor]: ../../book/drop.html
|
||||
//! [book-enums]: ../../book/enums.html
|
||||
//! [book-iter]: ../../book/iterators.html
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
pub mod v1; |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
//! The first version of the prelude of The Rust Standard Library.
|
||||
//!
|
||||
//! See the [module-level documentation](../index.html) for more.
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
// Reexported core operators
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce}; |
||||
|
||||
// Reexported functions
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use mem::drop; |
||||
|
||||
// Reexported types and traits
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use boxed::Box; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use borrow::ToOwned; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use clone::Clone; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use default::Default; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use option::Option::{self, Some, None}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use result::Result::{self, Ok, Err}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use slice::SliceConcatExt; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use string::{String, ToString}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
#[doc(no_inline)] pub use vec::Vec; |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
//! Useful synchronization primitives.
|
||||
//!
|
||||
//! This module contains useful safe and unsafe synchronization primitives.
|
||||
//! Most of the primitives in this module do not provide any sort of locking
|
||||
//! and/or blocking at all, but rather provide the necessary tools to build
|
||||
//! other types of concurrent primitives.
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use alloc::arc::{Arc, Weak}; |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use core::sync::atomic; |
||||
|
||||
// Easy cheat until we get proper locks based on libctru code
|
||||
#[stable(feature = "3ds", since = "1.0.0")] |
||||
pub use spin::{Mutex, MutexGuard}; |
||||
#[stable(feature = "3ds", since = "1.0.0")] |
||||
pub use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard}; |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
//! Platform-dependent platform abstraction
|
||||
//!
|
||||
//! The `std::sys` module is the abstracted interface through which
|
||||
//! `std` talks to the underlying operating system. It has different
|
||||
//! implementations for different operating system families, today
|
||||
//! just Unix and Windows.
|
||||
//!
|
||||
//! The centralization of platform-specific code in this module is
|
||||
//! enforced by the "platform abstraction layer" tidy script in
|
||||
//! `tools/tidy/pal.rs`.
|
||||
//!
|
||||
//! This module is closely related to the platform-independent system
|
||||
//! integration code in `std::sys_common`. See that module's
|
||||
//! documentation for details.
|
||||
//!
|
||||
//! In the future it would be desirable for the indepedent
|
||||
//! implementations of this module to be extracted to their own crates
|
||||
//! that `std` can link to, thus enabling their implementation
|
||||
//! out-of-tree via crate replacement. Though due to the complex
|
||||
//! inter-dependencies within `std` that will be a challenging goal to
|
||||
//! achieve.
|
||||
|
||||
pub use self::imp::*; |
||||
|
||||
#[cfg(unix)] |
||||
#[path = "unix/mod.rs"] |
||||
mod imp; |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
// 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.
|
||||
|
||||
//! Unix-specific extension to the primitives in the `std::ffi` module
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
use ffi::{OsStr, OsString}; |
||||
use mem; |
||||
use sys::os_str::Buf; |
||||
use sys_common::{FromInner, IntoInner, AsInner}; |
||||
|
||||
/// Unix-specific extensions to `OsString`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub trait OsStringExt { |
||||
/// Creates an `OsString` from a byte vector.
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
fn from_vec(vec: Vec<u8>) -> Self; |
||||
|
||||
/// Yields the underlying byte vector of this `OsString`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
fn into_vec(self) -> Vec<u8>; |
||||
} |
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
impl OsStringExt for OsString { |
||||
fn from_vec(vec: Vec<u8>) -> OsString { |
||||
FromInner::from_inner(Buf { inner: vec }) |
||||
} |
||||
fn into_vec(self) -> Vec<u8> { |
||||
self.into_inner().inner |
||||
} |
||||
} |
||||
|
||||
/// Unix-specific extensions to `OsStr`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub trait OsStrExt { |
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
fn from_bytes(slice: &[u8]) -> &Self; |
||||
|
||||
/// Gets the underlying byte view of the `OsStr` slice.
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
fn as_bytes(&self) -> &[u8]; |
||||
} |
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
impl OsStrExt for OsStr { |
||||
fn from_bytes(slice: &[u8]) -> &OsStr { |
||||
unsafe { mem::transmute(slice) } |
||||
} |
||||
fn as_bytes(&self) -> &[u8] { |
||||
&self.as_inner().inner |
||||
} |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
//! Experimental extensions to `std` for Unix platforms.
|
||||
//!
|
||||
//! For now, this module is limited to extracting file descriptors,
|
||||
//! but its functionality will grow over time.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::fs::File;
|
||||
//! use std::os::unix::prelude::*;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let f = File::create("foo.txt").unwrap();
|
||||
//! let fd = f.as_raw_fd();
|
||||
//!
|
||||
//! // use fd with native unix bindings
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")] |
||||
|
||||
pub mod ffi; |
||||
|
||||
/// A prelude for conveniently writing platform-specific code.
|
||||
///
|
||||
/// Includes all extension traits, and some important type definitions.
|
||||
#[stable(feature = "rust1", since = "1.0.0")] |
||||
pub mod prelude { |
||||
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")] |
||||
pub use super::ffi::{OsStrExt, OsStringExt}; |
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// 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
|
||||
|
||||
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
use libc; |
||||
|
||||
let p = unsafe { |
||||
libc::memchr( |
||||
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)) |
||||
} |
||||
} |
||||
|
||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
|
||||
#[cfg(target_os = "linux")] |
||||
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
use libc; |
||||
|
||||
// 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) |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
// Copyright 2014 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(missing_docs, bad_style)] |
||||
|
||||
pub mod ext; |
||||
pub mod memchr; |
||||
pub mod os; |
||||
pub mod os_str; |
||||
pub mod path; |
||||
|
||||
use io::ErrorKind; |
||||
use libc; |
||||
|
||||
pub fn decode_error_kind(errno: i32) -> ErrorKind { |
||||
match errno as libc::c_int { |
||||
libc::ECONNREFUSED => ErrorKind::ConnectionRefused, |
||||
libc::ECONNRESET => ErrorKind::ConnectionReset, |
||||
libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied, |
||||
libc::EPIPE => ErrorKind::BrokenPipe, |
||||
libc::ENOTCONN => ErrorKind::NotConnected, |
||||
libc::ECONNABORTED => ErrorKind::ConnectionAborted, |
||||
libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, |
||||
libc::EADDRINUSE => ErrorKind::AddrInUse, |
||||
libc::ENOENT => ErrorKind::NotFound, |
||||
libc::EINTR => ErrorKind::Interrupted, |
||||
libc::EINVAL => ErrorKind::InvalidInput, |
||||
libc::ETIMEDOUT => ErrorKind::TimedOut, |
||||
libc::EEXIST => ErrorKind::AlreadyExists, |
||||
|
||||
// These two constants can have the same value on some systems,
|
||||
// but different values on others, so we can't use a match
|
||||
// clause
|
||||
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => |
||||
ErrorKind::WouldBlock, |
||||
|
||||
_ => ErrorKind::Other, |
||||
} |
||||
} |
||||
|
||||
pub unsafe fn abort_internal() -> ! { |
||||
::libc::abort() |
||||
} |
@ -0,0 +1,123 @@
@@ -0,0 +1,123 @@
|
||||
// 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.
|
||||
|
||||
//! Implementation of `std::os` functionality for unix systems
|
||||
|
||||
#![allow(unused_imports)] // lots of cfg code here
|
||||
|
||||
use os::unix::prelude::*; |
||||
|
||||
use error::Error as StdError; |
||||
use ffi::{CString, CStr, OsString, OsStr}; |
||||
use fmt; |
||||
use io; |
||||
use iter; |
||||
use libc::{self, c_int, c_char, c_void}; |
||||
use marker::PhantomData; |
||||
use mem; |
||||
use memchr; |
||||
use path::{self, PathBuf}; |
||||
use ptr; |
||||
use slice; |
||||
use str; |
||||
use vec; |
||||
|
||||
const TMPBUF_SZ: usize = 128; |
||||
|
||||
extern "C" { |
||||
fn __errno() -> *mut c_int; |
||||
} |
||||
|
||||
/// Returns the platform-specific value of errno
|
||||
pub fn errno() -> i32 { |
||||
unsafe { |
||||
(*__errno()) as i32 |
||||
} |
||||
} |
||||
|
||||
/// Gets a detailed string description for the given error number.
|
||||
pub fn error_string(errno: i32) -> String { |
||||
extern { |
||||
#[cfg_attr(any(target_os = "linux", target_env = "newlib"),
|
||||
link_name = "__xpg_strerror_r")] |
||||
fn strerror_r(errnum: c_int, buf: *mut c_char, |
||||
buflen: libc::size_t) -> c_int; |
||||
} |
||||
|
||||
let mut buf = [0 as c_char; TMPBUF_SZ]; |
||||
|
||||
let p = buf.as_mut_ptr(); |
||||
unsafe { |
||||
if strerror_r(errno as c_int, p, buf.len()) < 0 { |
||||
panic!("strerror_r failure"); |
||||
} |
||||
|
||||
let p = p as *const _; |
||||
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() |
||||
} |
||||
} |
||||
|
||||
|
||||
pub struct SplitPaths<'a> { |
||||
iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>, |
||||
fn(&'a [u8]) -> PathBuf>, |
||||
} |
||||
|
||||
pub fn split_paths(unparsed: &OsStr) -> SplitPaths { |
||||
fn bytes_to_path(b: &[u8]) -> PathBuf { |
||||
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b)) |
||||
} |
||||
fn is_colon(b: &u8) -> bool { *b == b':' } |
||||
let unparsed = unparsed.as_bytes(); |
||||
SplitPaths { |
||||
iter: unparsed.split(is_colon as fn(&u8) -> bool) |
||||
.map(bytes_to_path as fn(&[u8]) -> PathBuf) |
||||
} |
||||
} |
||||
|
||||
impl<'a> Iterator for SplitPaths<'a> { |
||||
type Item = PathBuf; |
||||
fn next(&mut self) -> Option<PathBuf> { self.iter.next() } |
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } |
||||
} |
||||
|
||||
#[derive(Debug)] |
||||
pub struct JoinPathsError; |
||||
|
||||
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError> |
||||
where I: Iterator<Item=T>, T: AsRef<OsStr> |
||||
{ |
||||
let mut joined = Vec::new(); |
||||
let sep = b':'; |
||||
|
||||
for (i, path) in paths.enumerate() { |
||||
let path = path.as_ref().as_bytes(); |
||||
if i > 0 { joined.push(sep) } |
||||
if path.contains(&sep) { |
||||
return Err(JoinPathsError) |
||||
} |
||||
joined.extend_from_slice(path); |
||||
} |
||||
Ok(OsStringExt::from_vec(joined)) |
||||
} |
||||
|
||||
impl fmt::Display for JoinPathsError { |
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||
"path segment contains separator `:`".fmt(f) |
||||
} |
||||
} |
||||
|
||||
impl StdError for JoinPathsError { |
||||
fn description(&self) -> &str { "failed to join paths" } |
||||
} |
||||
|
||||
pub fn exit(code: i32) -> ! { |
||||
unsafe { libc::exit(code as c_int) } |
||||
} |
@ -0,0 +1,119 @@
@@ -0,0 +1,119 @@
|
||||
// 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.
|
||||
|
||||
/// The underlying OsString/OsStr implementation on Unix systems: just
|
||||
/// a `Vec<u8>`/`[u8]`.
|
||||
|
||||
use borrow::Cow; |
||||
use fmt::{self, Debug}; |
||||
use str; |
||||
use mem; |
||||
use sys_common::{AsInner, IntoInner}; |
||||
|
||||
#[derive(Clone, Hash)] |
||||
pub struct Buf { |
||||
pub inner: Vec<u8> |
||||
} |
||||
|
||||
pub struct Slice { |
||||
pub inner: [u8] |
||||
} |
||||
|
||||
impl Debug for Slice { |
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { |
||||
self.to_string_lossy().fmt(formatter) |
||||
} |
||||
} |
||||
|
||||
impl Debug for Buf { |
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { |
||||
self.as_slice().fmt(formatter) |
||||
} |
||||
} |
||||
|
||||
impl IntoInner<Vec<u8>> for Buf { |
||||
fn into_inner(self) -> Vec<u8> { |
||||
self.inner |
||||
} |
||||
} |
||||
|
||||
impl AsInner<[u8]> for Buf { |
||||
fn as_inner(&self) -> &[u8] { |
||||
&self.inner |
||||
} |
||||
} |
||||
|
||||
|
||||
impl Buf { |
||||
pub fn from_string(s: String) -> Buf { |
||||
Buf { inner: s.into_bytes() } |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn with_capacity(capacity: usize) -> Buf { |
||||
Buf { |
||||
inner: Vec::with_capacity(capacity) |
||||
} |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn clear(&mut self) { |
||||
self.inner.clear() |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn capacity(&self) -> usize { |
||||
self.inner.capacity() |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn reserve(&mut self, additional: usize) { |
||||
self.inner.reserve(additional) |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn reserve_exact(&mut self, additional: usize) { |
||||
self.inner.reserve_exact(additional) |
||||
} |
||||
|
||||
pub fn as_slice(&self) -> &Slice { |
||||
unsafe { mem::transmute(&*self.inner) } |
||||
} |
||||
|
||||
pub fn into_string(self) -> Result<String, Buf> { |
||||
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } ) |
||||
} |
||||
|
||||
pub fn push_slice(&mut self, s: &Slice) { |
||||
self.inner.extend_from_slice(&s.inner) |
||||
} |
||||
} |
||||
|
||||
impl Slice { |
||||
fn from_u8_slice(s: &[u8]) -> &Slice { |
||||
unsafe { mem::transmute(s) } |
||||
} |
||||
|
||||
pub fn from_str(s: &str) -> &Slice { |
||||
Slice::from_u8_slice(s.as_bytes()) |
||||
} |
||||
|
||||
pub fn to_str(&self) -> Option<&str> { |
||||
str::from_utf8(&self.inner).ok() |
||||
} |
||||
|
||||
pub fn to_string_lossy(&self) -> Cow<str> { |
||||
String::from_utf8_lossy(&self.inner) |
||||
} |
||||
|
||||
pub fn to_owned(&self) -> Buf { |
||||
Buf { inner: self.inner.to_vec() } |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
// 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.
|
||||
|
||||
use path::Prefix; |
||||
use ffi::OsStr; |
||||
|
||||
#[inline] |
||||
pub fn is_sep_byte(b: u8) -> bool { |
||||
b == b'/' |
||||
} |
||||
|
||||
#[inline] |
||||
pub fn is_verbatim_sep(b: u8) -> bool { |
||||
b == b'/' |
||||
} |
||||
|
||||
pub fn parse_prefix(_: &OsStr) -> Option<Prefix> { |
||||
None |
||||
} |
||||
|
||||
pub const MAIN_SEP_STR: &'static str = "/"; |
||||
pub const MAIN_SEP: char = '/'; |
@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
|
||||
// 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.
|
||||
use io; |
||||
use io::ErrorKind; |
||||
use io::Read; |
||||
use slice::from_raw_parts_mut; |
||||
|
||||
pub const DEFAULT_BUF_SIZE: usize = 8 * 1024; |
||||
|
||||
// Provides read_to_end functionality over an uninitialized buffer.
|
||||
// This function is unsafe because it calls the underlying
|
||||
// read function with a slice into uninitialized memory. The default
|
||||
// implementation of read_to_end for readers will zero out new memory in
|
||||
// the buf before passing it to read, but avoiding this zero can often
|
||||
// lead to a fairly significant performance win.
|
||||
//
|
||||
// Implementations using this method have to adhere to two guarantees:
|
||||
// * The implementation of read never reads the buffer provided.
|
||||
// * The implementation of read correctly reports how many bytes were written.
|
||||
pub unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> io::Result<usize> { |
||||
|
||||
let start_len = buf.len(); |
||||
buf.reserve(16); |
||||
|
||||
// Always try to read into the empty space of the vector (from the length to the capacity).
|
||||
// If the vector ever fills up then we reserve an extra byte which should trigger the normal
|
||||
// reallocation routines for the vector, which will likely double the size.
|
||||
//
|
||||
// This function is similar to the read_to_end function in std::io, but the logic about
|
||||
// reservations and slicing is different enough that this is duplicated here.
|
||||
loop { |
||||
if buf.len() == buf.capacity() { |
||||
buf.reserve(1); |
||||
} |
||||
|
||||
let buf_slice = from_raw_parts_mut(buf.as_mut_ptr().offset(buf.len() as isize), |
||||
buf.capacity() - buf.len()); |
||||
|
||||
match r.read(buf_slice) { |
||||
Ok(0) => { return Ok(buf.len() - start_len); } |
||||
Ok(n) => { let len = buf.len() + n; buf.set_len(len); }, |
||||
Err(ref e) if e.kind() == ErrorKind::Interrupted => { } |
||||
Err(e) => { return Err(e); } |
||||
} |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
#[allow(dead_code)] // not used on emscripten
|
||||
pub mod test { |
||||
use path::{Path, PathBuf}; |
||||
use env; |
||||
use rand::{self, Rng}; |
||||
use fs; |
||||
|
||||
pub struct TempDir(PathBuf); |
||||
|
||||
impl TempDir { |
||||
pub fn join(&self, path: &str) -> PathBuf { |
||||
let TempDir(ref p) = *self; |
||||
p.join(path) |
||||
} |
||||
|
||||
pub fn path<'a>(&'a self) -> &'a Path { |
||||
let TempDir(ref p) = *self; |
||||
p |
||||
} |
||||
} |
||||
|
||||
impl Drop for TempDir { |
||||
fn drop(&mut self) { |
||||
// Gee, seeing how we're testing the fs module I sure hope that we
|
||||
// at least implement this correctly!
|
||||
let TempDir(ref p) = *self; |
||||
fs::remove_dir_all(p).unwrap(); |
||||
} |
||||
} |
||||
|
||||
pub fn tmpdir() -> TempDir { |
||||
let p = env::temp_dir(); |
||||
let mut r = rand::thread_rng(); |
||||
let ret = p.join(&format!("rust-{}", r.next_u32())); |
||||
fs::create_dir(&ret).unwrap(); |
||||
TempDir(ret) |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use io::prelude::*; |
||||
use super::*; |
||||
use io; |
||||
use io::{ErrorKind, Take, Repeat, repeat}; |
||||
use slice::from_raw_parts; |
||||
|
||||
struct ErrorRepeat { |
||||
lr: Take<Repeat> |
||||
} |
||||
|
||||
fn error_repeat(byte: u8, limit: u64) -> ErrorRepeat { |
||||
ErrorRepeat { lr: repeat(byte).take(limit) } |
||||
} |
||||
|
||||
impl Read for ErrorRepeat { |
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
||||
let ret = self.lr.read(buf); |
||||
if let Ok(0) = ret { |
||||
return Err(io::Error::new(ErrorKind::Other, "")) |
||||
} |
||||
ret |
||||
} |
||||
} |
||||
|
||||
fn init_vec_data() -> Vec<u8> { |
||||
let mut vec = vec![10u8; 200]; |
||||
unsafe { vec.set_len(0); } |
||||
vec |
||||
} |
||||
|
||||
fn assert_all_eq(buf: &[u8], value: u8) { |
||||
for n in buf { |
||||
assert_eq!(*n, value); |
||||
} |
||||
} |
||||
|
||||
fn validate(buf: &Vec<u8>, good_read_len: usize) { |
||||
assert_all_eq(buf, 1u8); |
||||
let cap = buf.capacity(); |
||||
let end_slice = unsafe { from_raw_parts(buf.as_ptr().offset(good_read_len as isize), |
||||
cap - good_read_len) }; |
||||
assert_all_eq(end_slice, 10u8); |
||||
} |
||||
|
||||
#[test] |
||||
fn read_to_end_uninit_error() { |
||||
let mut er = error_repeat(1,100); |
||||
let mut vec = init_vec_data(); |
||||
if let Err(_) = unsafe { read_to_end_uninitialized(&mut er, &mut vec) } { |
||||
validate(&vec, 100); |
||||
} else { |
||||
assert!(false); |
||||
} |
||||
} |
||||
|
||||
#[test] |
||||
fn read_to_end_uninit_zero_len_vec() { |
||||
let mut er = repeat(1).take(100); |
||||
let mut vec = Vec::new(); |
||||
let n = unsafe{ read_to_end_uninitialized(&mut er, &mut vec).unwrap() }; |
||||
assert_all_eq(&vec, 1u8); |
||||
assert_eq!(vec.len(), n); |
||||
} |
||||
|
||||
#[test] |
||||
fn read_to_end_uninit_good() { |
||||
let mut er = repeat(1).take(100); |
||||
let mut vec = init_vec_data(); |
||||
let n = unsafe{ read_to_end_uninitialized(&mut er, &mut vec).unwrap() }; |
||||
validate(&vec, 100); |
||||
assert_eq!(vec.len(), n); |
||||
} |
||||
|
||||
#[bench] |
||||
#[cfg_attr(target_os = "emscripten", ignore)] |
||||
fn bench_uninitialized(b: &mut ::test::Bencher) { |
||||
b.iter(|| { |
||||
let mut lr = repeat(1).take(10000000); |
||||
let mut vec = Vec::with_capacity(1024); |
||||
unsafe { read_to_end_uninitialized(&mut lr, &mut vec) } |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
//! Platform-independent platform abstraction
|
||||
//!
|
||||
//! This is the platform-independent portion of the standard libraries
|
||||
//! platform abstraction layer, whereas `std::sys` is the
|
||||
//! platform-specific portion.
|
||||
//!
|
||||
//! The relationship between `std::sys_common`, `std::sys` and the
|
||||
//! rest of `std` is complex, with dependencies going in all
|
||||
//! directions: `std` depending on `sys_common`, `sys_common`
|
||||
//! depending on `sys`, and `sys` depending on `sys_common` and `std`.
|
||||
//! Ideally `sys_common` would be split into two and the dependencies
|
||||
//! between them all would form a dag, facilitating the extraction of
|
||||
//! `std::sys` from the standard library.
|
||||
|
||||
#![allow(missing_docs)] |
||||
|
||||
pub mod io; |
||||
|
||||
// common error constructors
|
||||
|
||||
/// A trait for viewing representations from std types
|
||||
#[doc(hidden)] |
||||
pub trait AsInner<Inner: ?Sized> { |
||||
fn as_inner(&self) -> &Inner; |
||||
} |
||||
|
||||
/// A trait for viewing representations from std types
|
||||
#[doc(hidden)] |
||||
pub trait AsInnerMut<Inner: ?Sized> { |
||||
fn as_inner_mut(&mut self) -> &mut Inner; |
||||
} |
||||
|
||||
/// A trait for extracting representations from std types
|
||||
#[doc(hidden)] |
||||
pub trait IntoInner<Inner> { |
||||
fn into_inner(self) -> Inner; |
||||
} |
||||
|
||||
/// A trait for creating std types from internal representations
|
||||
#[doc(hidden)] |
||||
pub trait FromInner<Inner> { |
||||
fn from_inner(inner: Inner) -> Self; |
||||
} |
||||
|
||||
macro_rules! rtabort { |
||||
($($t:tt)*) => (::sys_common::util::abort(format_args!($($t)*))) |
||||
} |
||||
|
||||
// Computes (value*numer)/denom without overflow, as long as both
|
||||
// (numer*denom) and the overall result fit into i64 (which is the case
|
||||
// for our time conversions).
|
||||
#[allow(dead_code)] // not used on all platforms
|
||||
pub fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { |
||||
let q = value / denom; |
||||
let r = value % denom; |
||||
// Decompose value as (value/denom*denom + value%denom),
|
||||
// substitute into (value*numer)/denom and simplify.
|
||||
// r < denom, so (denom*numer) is the upper bound of (r*numer)
|
||||
q * numer + r * numer / denom |
||||
} |
||||
|
||||
#[test] |
||||
fn test_muldiv() { |
||||
assert_eq!(mul_div_u64( 1_000_000_000_001, 1_000_000_000, 1_000_000), |
||||
1_000_000_000_001_000); |
||||
} |
@ -1,5 +1,8 @@
@@ -1,5 +1,8 @@
|
||||
[package] |
||||
name = "ctru-sys" |
||||
version = "0.2.0" |
||||
version = "0.3.0" |
||||
authors = ["Ronald Kinard <furyhunter600@gmail.com>"] |
||||
license = "https://en.wikipedia.org/wiki/Zlib_License" |
||||
|
||||
[dependencies] |
||||
ctr-libc = { path = "../ctr-libc", default-features = false } |
||||
|
@ -0,0 +1,258 @@
@@ -0,0 +1,258 @@
|
||||
// automatically generated by rust-bindgen
|
||||
|
||||
|
||||
#![allow(dead_code,
|
||||
non_camel_case_types, |
||||
non_upper_case_globals, |
||||
non_snake_case)] |
||||
|
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum SwkbdType { |
||||
SWKBD_TYPE_NORMAL = 0, |
||||
SWKBD_TYPE_QWERTY = 1, |
||||
SWKBD_TYPE_NUMPAD = 2, |
||||
SWKBD_TYPE_WESTERN = 3, |
||||
} |
||||
pub const SWKBD_NOTBLANK_NOTEMPTY: SwkbdValidInput = SwkbdValidInput::SWKBD_NOTEMPTY_NOTBLANK; |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum SwkbdValidInput { |
||||
SWKBD_ANYTHING = 0, |
||||
SWKBD_NOTEMPTY = 1, |
||||
SWKBD_NOTEMPTY_NOTBLANK = 2, |
||||
SWKBD_NOTBLANK = 3, |
||||
SWKBD_FIXEDLEN = 4, |
||||
} |
||||
pub const SWKBD_BUTTON_CONFIRM: SwkbdButton = SwkbdButton::SWKBD_BUTTON_RIGHT; |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum SwkbdButton { |
||||
SWKBD_BUTTON_LEFT = 0, |
||||
SWKBD_BUTTON_MIDDLE = 1, |
||||
SWKBD_BUTTON_RIGHT = 2, |
||||
SWKBD_BUTTON_NONE = 3, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum SwkbdPasswordMode { |
||||
SWKBD_PASSWORD_NONE = 0, |
||||
SWKBD_PASSWORD_HIDE = 1, |
||||
SWKBD_PASSWORD_HIDE_DELAY = 2, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum Enum_Unnamed1 { |
||||
SWKBD_FILTER_DIGITS = 1, |
||||
SWKBD_FILTER_AT = 2, |
||||
SWKBD_FILTER_PERCENT = 4, |
||||
SWKBD_FILTER_BACKSLASH = 8, |
||||
SWKBD_FILTER_PROFANITY = 16, |
||||
SWKBD_FILTER_CALLBACK = 32, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum Enum_Unnamed2 { |
||||
SWKBD_PARENTAL = 1, |
||||
SWKBD_DARKEN_TOP_SCREEN = 2, |
||||
SWKBD_PREDICTIVE_INPUT = 4, |
||||
SWKBD_MULTILINE = 8, |
||||
SWKBD_FIXED_WIDTH = 16, |
||||
SWKBD_ALLOW_HOME = 32, |
||||
SWKBD_ALLOW_RESET = 64, |
||||
SWKBD_ALLOW_POWER = 128, |
||||
SWKBD_DEFAULT_QWERTY = 512, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum SwkbdCallbackResult { |
||||
SWKBD_CALLBACK_OK = 0, |
||||
SWKBD_CALLBACK_CLOSE = 1, |
||||
SWKBD_CALLBACK_CONTINUE = 2, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(i32)] |
||||
#[derive(Debug)] |
||||
pub enum SwkbdResult { |
||||
SWKBD_NONE = -1, |
||||
SWKBD_INVALID_INPUT = -2, |
||||
SWKBD_OUTOFMEM = -3, |
||||
SWKBD_D0_CLICK = 0, |
||||
SWKBD_D1_CLICK0 = 1, |
||||
SWKBD_D1_CLICK1 = 2, |
||||
SWKBD_D2_CLICK0 = 3, |
||||
SWKBD_D2_CLICK1 = 4, |
||||
SWKBD_D2_CLICK2 = 5, |
||||
SWKBD_HOMEPRESSED = 10, |
||||
SWKBD_RESETPRESSED = 11, |
||||
SWKBD_POWERPRESSED = 12, |
||||
SWKBD_PARENTAL_OK = 20, |
||||
SWKBD_PARENTAL_FAIL = 21, |
||||
SWKBD_BANNED_INPUT = 30, |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy)] |
||||
pub struct SwkbdDictWord { |
||||
pub reading: [u16; 41usize], |
||||
pub word: [u16; 41usize], |
||||
pub language: u8, |
||||
pub all_languages: u8, |
||||
} |
||||
impl ::core::clone::Clone for SwkbdDictWord { |
||||
fn clone(&self) -> Self { |
||||
*self |
||||
} |
||||
} |
||||
impl ::core::default::Default for SwkbdDictWord { |
||||
fn default() -> Self { |
||||
unsafe { ::core::mem::zeroed() } |
||||
} |
||||
} |
||||
pub type SwkbdCallbackFn = |
||||
::core::option::Option<unsafe extern "C" fn(user: *mut ::libc::c_void, |
||||
ppMessage: *mut *const u8, |
||||
text: *const u8, |
||||
textlen: usize) |
||||
-> SwkbdCallbackResult>; |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct SwkbdStatusData { |
||||
pub data: [u32; 17usize], |
||||
} |
||||
impl ::core::default::Default for SwkbdStatusData { |
||||
fn default() -> Self { |
||||
unsafe { ::core::mem::zeroed() } |
||||
} |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy)] |
||||
pub struct SwkbdLearningData { |
||||
pub data: [u32; 10523usize], |
||||
} |
||||
impl ::core::clone::Clone for SwkbdLearningData { |
||||
fn clone(&self) -> Self { |
||||
*self |
||||
} |
||||
} |
||||
impl ::core::default::Default for SwkbdLearningData { |
||||
fn default() -> Self { |
||||
unsafe { ::core::mem::zeroed() } |
||||
} |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct SwkbdExtra { |
||||
pub initial_text: *const u8, |
||||
pub dict: *const SwkbdDictWord, |
||||
pub status_data: *mut SwkbdStatusData, |
||||
pub learning_data: *mut SwkbdLearningData, |
||||
pub callback: SwkbdCallbackFn, |
||||
pub callback_user: *mut ::libc::c_void, |
||||
} |
||||
impl ::core::default::Default for SwkbdExtra { |
||||
fn default() -> Self { |
||||
unsafe { ::core::mem::zeroed() } |
||||
} |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy)] |
||||
pub struct SwkbdState { |
||||
pub type_: i32, |
||||
pub num_buttons_m1: i32, |
||||
pub valid_input: i32, |
||||
pub password_mode: i32, |
||||
pub is_parental_screen: i32, |
||||
pub darken_top_screen: i32, |
||||
pub filter_flags: u32, |
||||
pub save_state_flags: u32, |
||||
pub max_text_len: u16, |
||||
pub dict_word_count: u16, |
||||
pub max_digits: u16, |
||||
pub button_text: [[u16; 17usize]; 3usize], |
||||
pub numpad_keys: [u16; 2usize], |
||||
pub hint_text: [u16; 65usize], |
||||
pub predictive_input: u8, |
||||
pub multiline: u8, |
||||
pub fixed_width: u8, |
||||
pub allow_home: u8, |
||||
pub allow_reset: u8, |
||||
pub allow_power: u8, |
||||
pub unknown: u8, |
||||
pub default_qwerty: u8, |
||||
pub button_submits_text: [u8; 4usize], |
||||
pub language: u16, |
||||
pub initial_text_offset: i32, |
||||
pub dict_offset: i32, |
||||
pub initial_status_offset: i32, |
||||
pub initial_learning_offset: i32, |
||||
pub shared_memory_size: usize, |
||||
pub version: u32, |
||||
pub result: SwkbdResult, |
||||
pub status_offset: i32, |
||||
pub learning_offset: i32, |
||||
pub text_offset: i32, |
||||
pub text_length: u16, |
||||
pub callback_result: i32, |
||||
pub callback_msg: [u16; 257usize], |
||||
pub skip_at_check: u8, |
||||
pub union: _bindgen_data_1_, |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
pub union _bindgen_data_1_ { |
||||
pub reserved: [u8; 171usize], |
||||
pub extra: SwkbdExtra, |
||||
} |
||||
impl ::core::clone::Clone for SwkbdState { |
||||
fn clone(&self) -> Self { |
||||
*self |
||||
} |
||||
} |
||||
impl ::core::default::Default for SwkbdState { |
||||
fn default() -> Self { |
||||
unsafe { ::core::mem::zeroed() } |
||||
} |
||||
} |
||||
extern "C" { |
||||
pub fn swkbdInit(swkbd: *mut SwkbdState, |
||||
type_: SwkbdType, |
||||
numButtons: i32, |
||||
maxTextLength: i32); |
||||
pub fn swkbdSetFeatures(swkbd: *mut SwkbdState, features: u32); |
||||
pub fn swkbdSetHintText(swkbd: *mut SwkbdState, text: *const u8); |
||||
pub fn swkbdSetButton(swkbd: *mut SwkbdState, |
||||
button: SwkbdButton, |
||||
text: *const u8, |
||||
submit: u8); |
||||
pub fn swkbdSetInitialText(swkbd: *mut SwkbdState, text: *const u8); |
||||
pub fn swkbdSetDictWord(word: *mut SwkbdDictWord, |
||||
reading: *const u8, |
||||
text: *const u8); |
||||
pub fn swkbdSetDictionary(swkbd: *mut SwkbdState, |
||||
dict: *const SwkbdDictWord, |
||||
wordCount: i32); |
||||
pub fn swkbdSetStatusData(swkbd: *mut SwkbdState, |
||||
data: *mut SwkbdStatusData, |
||||
in_: u8, |
||||
out: u8); |
||||
pub fn swkbdSetLearningData(swkbd: *mut SwkbdState, |
||||
data: *mut SwkbdLearningData, |
||||
in_: u8, |
||||
out: u8); |
||||
pub fn swkbdSetFilterCallback(swkbd: *mut SwkbdState, |
||||
callback: SwkbdCallbackFn, |
||||
user: *mut ::libc::c_void); |
||||
pub fn swkbdInputText(swkbd: *mut SwkbdState, |
||||
buf: *mut u8, |
||||
bufsize: usize) |
||||
-> SwkbdButton; |
||||
} |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
/* automatically generated by rust-bindgen */ |
||||
|
||||
#![allow(dead_code,
|
||||
non_camel_case_types, |
||||
non_upper_case_globals, |
||||
non_snake_case)] |
||||
|
||||
use ::types::*; |
||||
use super::ndsp::ndspWaveBuf; |
||||
|
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum Enum_Unnamed1 { |
||||
NDSP_ENCODING_PCM8 = 0, |
||||
NDSP_ENCODING_PCM16 = 1, |
||||
NDSP_ENCODING_ADPCM = 2, |
||||
} |
||||
pub const NDSP_FORMAT_PCM8: Enum_Unnamed2 = |
||||
Enum_Unnamed2::NDSP_FORMAT_MONO_PCM8; |
||||
pub const NDSP_FORMAT_PCM16: Enum_Unnamed2 = |
||||
Enum_Unnamed2::NDSP_FORMAT_MONO_PCM16; |
||||
pub const NDSP_FORMAT_ADPCM: Enum_Unnamed2 = |
||||
Enum_Unnamed2::NDSP_FORMAT_MONO_ADPCM; |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum Enum_Unnamed2 { |
||||
NDSP_FORMAT_MONO_PCM8 = 1, |
||||
NDSP_FORMAT_MONO_PCM16 = 5, |
||||
NDSP_FORMAT_MONO_ADPCM = 9, |
||||
NDSP_FORMAT_STEREO_PCM8 = 2, |
||||
NDSP_FORMAT_STEREO_PCM16 = 6, |
||||
NDSP_FRONT_BYPASS = 16, |
||||
NDSP_3D_SURROUND_PREPROCESSED = 64, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum ndspInterpType { |
||||
NDSP_INTERP_POLYPHASE = 0, |
||||
NDSP_INTERP_LINEAR = 1, |
||||
NDSP_INTERP_NONE = 2, |
||||
} |
||||
extern "C" { |
||||
pub fn ndspChnReset(id: ::libc::c_int); |
||||
pub fn ndspChnInitParams(id: ::libc::c_int); |
||||
pub fn ndspChnIsPlaying(id: ::libc::c_int) -> u8; |
||||
pub fn ndspChnGetSamplePos(id: ::libc::c_int) -> u32_; |
||||
pub fn ndspChnGetWaveBufSeq(id: ::libc::c_int) -> u16_; |
||||
pub fn ndspChnIsPaused(id: ::libc::c_int) -> u8; |
||||
pub fn ndspChnSetPaused(id: ::libc::c_int, paused: u8); |
||||
pub fn ndspChnSetFormat(id: ::libc::c_int, format: u16_); |
||||
pub fn ndspChnSetInterp(id: ::libc::c_int, type_: ndspInterpType); |
||||
pub fn ndspChnSetRate(id: ::libc::c_int, rate: f32); |
||||
pub fn ndspChnSetMix(id: ::libc::c_int, mix: *mut f32); |
||||
pub fn ndspChnSetAdpcmCoefs(id: ::libc::c_int, coefs: *mut u16_); |
||||
pub fn ndspChnWaveBufClear(id: ::libc::c_int); |
||||
pub fn ndspChnWaveBufAdd(id: ::libc::c_int, buf: *mut ndspWaveBuf); |
||||
pub fn ndspChnIirMonoSetEnable(id: ::libc::c_int, enable: u8); |
||||
pub fn ndspChnIirMonoSetParamsCustomFilter(id: ::libc::c_int, a0: f32, |
||||
a1: f32, b0: f32) -> u8; |
||||
pub fn ndspChnIirMonoSetParamsLowPassFilter(id: ::libc::c_int, f0: f32) |
||||
-> u8; |
||||
pub fn ndspChnIirMonoSetParamsHighPassFilter(id: ::libc::c_int, f0: f32) |
||||
-> u8; |
||||
pub fn ndspChnIirBiquadSetEnable(id: ::libc::c_int, enable: u8); |
||||
pub fn ndspChnIirBiquadSetParamsCustomFilter(id: ::libc::c_int, a0: f32, |
||||
a1: f32, a2: f32, b0: f32, |
||||
b1: f32, b2: f32) -> u8; |
||||
pub fn ndspChnIirBiquadSetParamsLowPassFilter(id: ::libc::c_int, f0: f32, |
||||
Q: f32) -> u8; |
||||
pub fn ndspChnIirBiquadSetParamsHighPassFilter(id: ::libc::c_int, f0: f32, |
||||
Q: f32) -> u8; |
||||
pub fn ndspChnIirBiquadSetParamsBandPassFilter(id: ::libc::c_int, f0: f32, |
||||
Q: f32) -> u8; |
||||
pub fn ndspChnIirBiquadSetParamsNotchFilter(id: ::libc::c_int, f0: f32, |
||||
Q: f32) -> u8; |
||||
pub fn ndspChnIirBiquadSetParamsPeakingEqualizer(id: ::libc::c_int, |
||||
f0: f32, Q: f32, |
||||
gain: f32) -> u8; |
||||
} |
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
pub mod channel; |
||||
pub mod ndsp; |
@ -0,0 +1,112 @@
@@ -0,0 +1,112 @@
|
||||
/* automatically generated by rust-bindgen */ |
||||
|
||||
#![allow(dead_code,
|
||||
non_camel_case_types, |
||||
non_upper_case_globals, |
||||
non_snake_case)] |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum ndspOutputMode { |
||||
NDSP_OUTPUT_MONO = 0, |
||||
NDSP_OUTPUT_STEREO = 1, |
||||
NDSP_OUTPUT_SURROUND = 2, |
||||
} |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum ndspClippingMode { NDSP_CLIP_NORMAL = 0, NDSP_CLIP_SOFT = 1, } |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum ndspSpeakerPos { |
||||
NDSP_SPKPOS_SQUARE = 0, |
||||
NDSP_SPKPOS_WIDE = 1, |
||||
NDSP_SPKPOS_NUM = 2, |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct ndspAdpcmData { |
||||
pub index: u16_, |
||||
pub history0: s16, |
||||
pub history1: s16, |
||||
} |
||||
impl ::core::default::Default for ndspAdpcmData { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
pub type ndspWaveBuf = tag_ndspWaveBuf; |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum Enum_Unnamed1 { |
||||
NDSP_WBUF_FREE = 0, |
||||
NDSP_WBUF_QUEUED = 1, |
||||
NDSP_WBUF_PLAYING = 2, |
||||
NDSP_WBUF_DONE = 3, |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct tag_ndspWaveBuf { |
||||
pub _bindgen_data_1_: [u64; 1usize], |
||||
pub nsamples: u32_, |
||||
pub adpcm_data: *mut ndspAdpcmData, |
||||
pub offset: u32_, |
||||
pub looping: u8, |
||||
pub status: u8_, |
||||
pub sequence_id: u16_, |
||||
pub next: *mut ndspWaveBuf, |
||||
} |
||||
impl tag_ndspWaveBuf { |
||||
pub unsafe fn data_pcm8(&mut self) -> *mut *mut s8 { |
||||
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_); |
||||
::core::mem::transmute(raw.offset(0)) |
||||
} |
||||
pub unsafe fn data_pcm16(&mut self) -> *mut *mut s16 { |
||||
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_); |
||||
::core::mem::transmute(raw.offset(0)) |
||||
} |
||||
pub unsafe fn data_adpcm(&mut self) -> *mut *mut u8_ { |
||||
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_); |
||||
::core::mem::transmute(raw.offset(0)) |
||||
} |
||||
pub unsafe fn data_vaddr(&mut self) -> *mut *const ::libc::c_void { |
||||
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_); |
||||
::core::mem::transmute(raw.offset(0)) |
||||
} |
||||
} |
||||
impl ::core::default::Default for tag_ndspWaveBuf { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
pub type ndspCallback = |
||||
::core::option::Option<unsafe extern "C" fn(data: *mut ::libc::c_void)>; |
||||
pub type ndspAuxCallback = |
||||
::core::option::Option<unsafe extern "C" fn(data: *mut ::libc::c_void, |
||||
nsamples: ::libc::c_int, |
||||
samples: |
||||
*mut *mut ::libc::c_void)>; |
||||
extern "C" { |
||||
pub fn ndspUseComponent(binary: *const ::libc::c_void, size: u32_, |
||||
progMask: u16_, dataMask: u16_); |
||||
pub fn ndspInit() -> Result; |
||||
pub fn ndspExit(); |
||||
pub fn ndspGetDroppedFrames() -> u32_; |
||||
pub fn ndspGetFrameCount() -> u32_; |
||||
pub fn ndspSetMasterVol(volume: f32); |
||||
pub fn ndspSetOutputMode(mode: ndspOutputMode); |
||||
pub fn ndspSetClippingMode(mode: ndspClippingMode); |
||||
pub fn ndspSetOutputCount(count: ::libc::c_int); |
||||
pub fn ndspSetCapture(capture: *mut ndspWaveBuf); |
||||
pub fn ndspSetCallback(callback: ndspCallback, data: *mut ::libc::c_void); |
||||
pub fn ndspSurroundSetDepth(depth: u16_); |
||||
pub fn ndspSurroundSetPos(pos: ndspSpeakerPos); |
||||
pub fn ndspSurroundSetRearRatio(ratio: u16_); |
||||
pub fn ndspAuxSetEnable(id: ::libc::c_int, enable: u8); |
||||
pub fn ndspAuxSetFrontBypass(id: ::libc::c_int, bypass: u8); |
||||
pub fn ndspAuxSetVolume(id: ::libc::c_int, volume: f32); |
||||
pub fn ndspAuxSetCallback(id: ::libc::c_int, callback: ndspAuxCallback, |
||||
data: *mut ::libc::c_void); |
||||
} |
||||
|
||||
use ::types::*; |
@ -1,53 +1,47 @@
@@ -1,53 +1,47 @@
|
||||
//TODO: Fix Bindgen's issues again.
|
||||
/* automatically generated by rust-bindgen */ |
||||
|
||||
use libc::c_void; |
||||
use types::*; |
||||
|
||||
#[inline] |
||||
pub fn SYSTEM_VERSION(major: i32, minor: i32, revision: i32) { |
||||
(((major)<<24)|((minor)<<16)|((revision)<<8)); |
||||
} |
||||
|
||||
#[derive(Clone, Copy)] |
||||
#[repr(C)] |
||||
pub enum Enum_Unnamed1 { |
||||
#![allow(dead_code,
|
||||
non_camel_case_types, |
||||
non_upper_case_globals, |
||||
non_snake_case)] |
||||
#[derive(Copy, Clone)] |
||||
#[repr(u32)] |
||||
#[derive(Debug)] |
||||
pub enum MemRegion { |
||||
MEMREGION_ALL = 0, |
||||
MEMREGION_APPLICATION = 1, |
||||
MEMREGION_SYSTEM = 2, |
||||
MEMREGION_BASE = 3, |
||||
} |
||||
pub type MemRegion = Enum_Unnamed1; |
||||
#[repr(C)] |
||||
#[derive(Copy)] |
||||
pub struct Struct_Unnamed2 { |
||||
pub build: u8, |
||||
pub minor: u8, |
||||
pub mainver: u8, |
||||
pub reserved_x3: u8, |
||||
pub region: u8, |
||||
pub reserved_x5: [u8; 3usize], |
||||
} |
||||
impl ::core::clone::Clone for Struct_Unnamed2 { |
||||
fn clone(&self) -> Self { *self } |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct OS_VersionBin { |
||||
pub build: u8_, |
||||
pub minor: u8_, |
||||
pub mainver: u8_, |
||||
pub reserved_x3: u8_, |
||||
pub region: ::libc::c_char, |
||||
pub reserved_x5: [u8_; 3usize], |
||||
} |
||||
impl ::core::default::Default for Struct_Unnamed2 { |
||||
impl ::core::default::Default for OS_VersionBin { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
pub type OS_VersionBin = Struct_Unnamed2; |
||||
extern "C" { |
||||
pub fn osConvertVirtToPhys(vaddr: *const c_void) -> u32; |
||||
pub fn osConvertOldLINEARMemToNew(vaddr: *const c_void) |
||||
-> *mut c_void; |
||||
pub fn osStrError(error: u32) -> *const u8; |
||||
pub fn osConvertVirtToPhys(vaddr: *const ::libc::c_void) -> u32_; |
||||
pub fn osConvertOldLINEARMemToNew(vaddr: *const ::libc::c_void) |
||||
-> *mut ::libc::c_void; |
||||
pub fn osStrError(error: u32_) -> *const ::libc::c_char; |
||||
pub fn osGetMemRegionUsed(region: MemRegion) -> s64; |
||||
pub fn osGetTime() -> u64; |
||||
pub fn osGetTime() -> u64_; |
||||
pub fn osSetSpeedupEnable(enable: u8); |
||||
pub fn osGetSystemVersionData(nver_versionbin: *mut OS_VersionBin, |
||||
cver_versionbin: *mut OS_VersionBin) |
||||
-> Result; |
||||
pub fn osGetSystemVersionDataString(nver_versionbin: *mut OS_VersionBin, |
||||
cver_versionbin: *mut OS_VersionBin, |
||||
sysverstr: |
||||
*mut u8, |
||||
sysverstr_maxsize: u32) -> Result; |
||||
sysverstr: *mut ::libc::c_char, |
||||
sysverstr_maxsize: u32_) -> Result; |
||||
} |
||||
|
||||
use ::types::*; |
||||
|
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
/* automatically generated by rust-bindgen */ |
||||
|
||||
#![allow(dead_code,
|
||||
non_camel_case_types, |
||||
non_upper_case_globals, |
||||
non_snake_case)] |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct romfs_header { |
||||
pub headerSize: u32_, |
||||
pub dirHashTableOff: u32_, |
||||
pub dirHashTableSize: u32_, |
||||
pub dirTableOff: u32_, |
||||
pub dirTableSize: u32_, |
||||
pub fileHashTableOff: u32_, |
||||
pub fileHashTableSize: u32_, |
||||
pub fileTableOff: u32_, |
||||
pub fileTableSize: u32_, |
||||
pub fileDataOff: u32_, |
||||
} |
||||
impl ::core::default::Default for romfs_header { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct romfs_dir { |
||||
pub parent: u32_, |
||||
pub sibling: u32_, |
||||
pub childDir: u32_, |
||||
pub childFile: u32_, |
||||
pub nextHash: u32_, |
||||
pub nameLen: u32_, |
||||
pub name: [u16_; 0usize], |
||||
} |
||||
impl ::core::default::Default for romfs_dir { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
#[derive(Debug)] |
||||
pub struct romfs_file { |
||||
pub parent: u32_, |
||||
pub sibling: u32_, |
||||
pub dataOff: u64_, |
||||
pub dataSize: u64_, |
||||
pub nextHash: u32_, |
||||
pub nameLen: u32_, |
||||
pub name: [u16_; 0usize], |
||||
} |
||||
impl ::core::default::Default for romfs_file { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
pub enum romfs_mount { } |
||||
extern "C" { |
||||
pub fn romfsMount(mount: *mut *mut romfs_mount) -> Result; |
||||
pub fn romfsMountFromFile(file: Handle, offset: u32_, |
||||
mount: *mut *mut romfs_mount) -> Result; |
||||
pub fn romfsBind(mount: *mut romfs_mount) -> Result; |
||||
pub fn romfsUnmount(mount: *mut romfs_mount) -> Result; |
||||
} |
||||
|
||||
use ::types::*; |
@ -1,7 +1,29 @@
@@ -1,7 +1,29 @@
|
||||
use Result; |
||||
/* automatically generated by rust-bindgen */ |
||||
|
||||
#![allow(dead_code,
|
||||
non_camel_case_types, |
||||
non_upper_case_globals, |
||||
non_snake_case)] |
||||
|
||||
use ::types::*; |
||||
use services::fs::FS_DirectoryEntry; |
||||
|
||||
#[repr(C)] |
||||
#[derive(Copy, Clone)] |
||||
pub struct sdmc_dir_t { |
||||
pub magic: u32_, |
||||
pub fd: Handle, |
||||
pub index: ::libc::ssize_t, |
||||
pub size: ::libc::size_t, |
||||
pub entry_data: [FS_DirectoryEntry; 32usize], |
||||
} |
||||
impl ::core::default::Default for sdmc_dir_t { |
||||
fn default() -> Self { unsafe { ::core::mem::zeroed() } } |
||||
} |
||||
extern "C" { |
||||
pub fn sdmcInit() -> Result; |
||||
pub fn sdmcWriteSafe(enable: u8); |
||||
pub fn sdmcExit() -> Result; |
||||
pub fn sdmc_getmtime(name: *const ::libc::c_char, mtime: *mut u64_) |
||||
-> Result; |
||||
} |
||||
|
@ -1,4 +1,3 @@
@@ -1,4 +1,3 @@
|
||||
pub mod libc; |
||||
pub mod lock; |
||||
pub mod socket; |
||||
pub mod inaddr; |
||||
pub mod socket; |
||||
|
@ -1,15 +0,0 @@
@@ -1,15 +0,0 @@
|
||||
[package] |
||||
name = "std" |
||||
version = "0.0.0" |
||||
|
||||
[lib] |
||||
crate-type = ["rlib"] |
||||
|
||||
[dependencies.alloc_system3ds] |
||||
git = "https://github.com/rust3ds/alloc_system3ds" |
||||
|
||||
[dependencies.ctru-sys] |
||||
path = "../ctru-sys" |
||||
|
||||
[dependencies.spin] |
||||
version = "0.4" |
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
pub use self::c_str::{CString, CStr}; |
||||
pub use self::os_str::{OsString, OsStr}; |
||||
|
||||
mod c_str; |
||||
mod os_str; |
@ -1,100 +0,0 @@
@@ -1,100 +0,0 @@
|
||||
#![feature(alloc)] |
||||
#![feature(allow_internal_unstable)] |
||||
#![feature(collections)] |
||||
#![feature(const_fn)] |
||||
#![feature(core_intrinsics)] |
||||
#![feature(char_escape_debug)] |
||||
#![feature(float_extras)] |
||||
#![feature(int_error_internals)] |
||||
#![feature(lang_items)] |
||||
#![feature(macro_reexport)] |
||||
#![feature(optin_builtin_traits)] |
||||
#![feature(prelude_import)] |
||||
#![feature(raw)] |
||||
#![feature(slice_concat_ext)] |
||||
#![feature(slice_patterns)] |
||||
#![feature(str_internals)] |
||||
#![feature(try_from)] |
||||
#![feature(unicode)] |
||||
#![feature(zero_one)] |
||||
#![allow(non_camel_case_types)] |
||||
#![no_std] |
||||
|
||||
#[prelude_import] |
||||
#[allow(unused)] |
||||
use prelude::v1::*;
|
||||
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
|
||||
unreachable, unimplemented, write, writeln)] |
||||
extern crate core as __core; |
||||
#[macro_use] |
||||
#[macro_reexport(vec, format)] |
||||
extern crate collections as core_collections; |
||||
extern crate alloc; |
||||
extern crate std_unicode; |
||||
|
||||
extern crate alloc_system; |
||||
|
||||
extern crate ctru_sys as libctru; |
||||
extern crate spin; |
||||
|
||||
pub use core::any; |
||||
pub use core::cell; |
||||
pub use core::clone; |
||||
pub use core::cmp; |
||||
pub use core::convert; |
||||
pub use core::default; |
||||
pub use core::hash; |
||||
pub use core::intrinsics; |
||||
pub use core::iter; |
||||
pub use core::marker; |
||||
pub use core::mem; |
||||
pub use core::ops; |
||||
pub use core::ptr; |
||||
pub use core::raw; |
||||
pub use core::result; |
||||
pub use core::option; |
||||
|
||||
pub use alloc::arc; |
||||
pub use alloc::boxed; |
||||
pub use alloc::rc; |
||||
|
||||
pub use core_collections::borrow; |
||||
pub use core_collections::fmt; |
||||
pub use core_collections::slice; |
||||
pub use core_collections::str; |
||||
pub use core_collections::string; |
||||
pub use core_collections::vec; |
||||
|
||||
pub use std_unicode::char; |
||||
|
||||
#[macro_use] |
||||
pub mod macros; |
||||
|
||||
pub mod prelude; |
||||
|
||||
pub use core::isize; |
||||
pub use core::i8; |
||||
pub use core::i16; |
||||
pub use core::i32; |
||||
pub use core::i64; |
||||
|
||||
pub use core::usize; |
||||
pub use core::u8; |
||||
pub use core::u16; |
||||
pub use core::u32; |
||||
pub use core::u64; |
||||
|
||||
#[path = "num/f32.rs"] pub mod f32; |
||||
#[path = "num/f64.rs"] pub mod f64; |
||||
|
||||
pub mod ascii; |
||||
pub mod error; |
||||
pub mod ffi; |
||||
pub mod io; |
||||
pub mod num; |
||||
pub mod path; |
||||
pub mod rt; |
||||
pub mod sync; |
||||
mod memchr; |
||||
mod panicking; |
||||
mod sys; |
@ -1,105 +0,0 @@
@@ -1,105 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
/// The entry point for panic of Rust threads.
|
||||
///
|
||||
/// This macro is used to inject panic into a Rust thread, causing the thread to
|
||||
/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
|
||||
/// and the single-argument form of the `panic!` macro will be the value which
|
||||
/// is transmitted.
|
||||
///
|
||||
/// The multi-argument form of this macro panics with a string and has the
|
||||
/// `format!` syntax for building a string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```should_panic
|
||||
/// # #![allow(unreachable_code)]
|
||||
/// panic!();
|
||||
/// panic!("this is a terrible mistake!");
|
||||
/// panic!(4); // panic with the value of 4 to be collected elsewhere
|
||||
/// panic!("this is a {} {message}", "fancy", message = "message");
|
||||
/// ```
|
||||
#[macro_export] |
||||
macro_rules! panic { |
||||
() => ({ |
||||
panic!("explicit panic") |
||||
}); |
||||
($msg:expr) => ({ |
||||
$crate::rt::begin_panic($msg, { |
||||
// static requires less code at runtime, more constant data
|
||||
static _FILE_LINE: (&'static str, u32) = (file!(), line!()); |
||||
&_FILE_LINE |
||||
}) |
||||
}); |
||||
($fmt:expr, $($arg:tt)+) => ({ |
||||
$crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), { |
||||
// The leading _'s are to avoid dead code warnings if this is
|
||||
// used inside a dead function. Just `#[allow(dead_code)]` is
|
||||
// insufficient, since the user may have
|
||||
// `#[forbid(dead_code)]` and which cannot be overridden.
|
||||
static _FILE_LINE: (&'static str, u32) = (file!(), line!()); |
||||
&_FILE_LINE |
||||
}) |
||||
}); |
||||
} |
||||
|
||||
/// Helper macro for unwrapping `Result` values while returning early with an
|
||||
/// error if the value of the expression is `Err`. Can only be used in
|
||||
/// functions that return `Result` because of the early return of `Err` that
|
||||
/// it provides.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::io;
|
||||
/// use std::fs::File;
|
||||
/// use std::io::prelude::*;
|
||||
///
|
||||
/// fn write_to_file_using_try() -> Result<(), io::Error> {
|
||||
/// let mut file = try!(File::create("my_best_friends.txt"));
|
||||
/// try!(file.write_all(b"This is a list of my best friends."));
|
||||
/// println!("I wrote to the file");
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// // This is equivalent to:
|
||||
/// fn write_to_file_using_match() -> Result<(), io::Error> {
|
||||
/// let mut file = try!(File::create("my_best_friends.txt"));
|
||||
/// match file.write_all(b"This is a list of my best friends.") {
|
||||
/// Ok(v) => v,
|
||||
/// Err(e) => return Err(e),
|
||||
/// }
|
||||
/// println!("I wrote to the file");
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export] |
||||
macro_rules! try { |
||||
($expr:expr) => (match $expr { |
||||
$crate::result::Result::Ok(val) => val, |
||||
$crate::result::Result::Err(err) => { |
||||
return $crate::result::Result::Err($crate::convert::From::from(err)) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
#[macro_export] |
||||
macro_rules! print { |
||||
($($arg:tt)*) => ( |
||||
$crate::io::_print(format_args!($($arg)*)); |
||||
); |
||||
} |
||||
|
||||
#[macro_export] |
||||
macro_rules! println { |
||||
() => (print!("\n")); |
||||
($fmt:expr) => (print!(concat!($fmt, "\n"))); |
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); |
||||
} |
@ -1,397 +0,0 @@
@@ -1,397 +0,0 @@
|
||||
// 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
|
||||
|
||||
|
||||
|
||||
/// A safe interface to `memchr`.
|
||||
///
|
||||
/// Returns the index corresponding to the first occurrence of `needle` in
|
||||
/// `haystack`, or `None` if one is not found.
|
||||
///
|
||||
/// memchr reduces to super-optimized machine code at around an order of
|
||||
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
|
||||
/// (See benchmarks.)
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This shows how to find the first position of a byte in a byte string.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use memchr::memchr;
|
||||
///
|
||||
/// let haystack = b"the quick brown fox";
|
||||
/// assert_eq!(memchr(b'k', haystack), Some(8));
|
||||
/// ```
|
||||
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
use libctru::libc; |
||||
|
||||
let p = unsafe { |
||||
libc::memchr(haystack.as_ptr() as *const libc::c_void, |
||||
needle as libc::c_int, |
||||
haystack.len() as libc::size_t) |
||||
}; |
||||
if p.is_null() { |
||||
None |
||||
} else { |
||||
Some(p as usize - (haystack.as_ptr() as usize)) |
||||
} |
||||
} |
||||
memchr_specific(needle, haystack) |
||||
} |
||||
|
||||
/// A safe interface to `memrchr`.
|
||||
///
|
||||
/// Returns the index corresponding to the last occurrence of `needle` in
|
||||
/// `haystack`, or `None` if one is not found.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This shows how to find the last position of a byte in a byte string.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use memchr::memrchr;
|
||||
///
|
||||
/// let haystack = b"the quick brown fox";
|
||||
/// assert_eq!(memrchr(b'o', haystack), Some(17));
|
||||
/// ```
|
||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> { |
||||
use libctru::libc; |
||||
|
||||
// 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() as libc::size_t) |
||||
}; |
||||
if p.is_null() { |
||||
None |
||||
} else { |
||||
Some(p as usize - (haystack.as_ptr() as usize)) |
||||
} |
||||
} |
||||
memrchr_specific(needle, haystack) |
||||
} |
||||
|
||||
#[allow(dead_code)] |
||||
mod fallback { |
||||
use core::cmp; |
||||
use core::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..])); |
||||
} |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
// test the implementations for the current plattform
|
||||
use super::{memchr, memrchr}; |
||||
|
||||
#[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() { |
||||
let mut data = [1u8; 64]; |
||||
let needle = 2; |
||||
let pos = 40; |
||||
data[pos] = needle; |
||||
for start in 0..16 { |
||||
assert_eq!(Some(pos - start), memchr(needle, &data[start..])); |
||||
} |
||||
} |
||||
} |
@ -1,49 +0,0 @@
@@ -1,49 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
//! The first version of the prelude of The Rust Standard Library.
|
||||
|
||||
// Reexported core operators
|
||||
#[doc(no_inline)] |
||||
pub use marker::{Copy, Send, Sized, Sync}; |
||||
#[doc(no_inline)] |
||||
pub use ops::{Drop, Fn, FnMut, FnOnce}; |
||||
|
||||
// Reexported functions
|
||||
#[doc(no_inline)] |
||||
pub use mem::drop; |
||||
|
||||
// Reexported types and traits
|
||||
#[doc(no_inline)] |
||||
pub use boxed::Box; |
||||
#[doc(no_inline)] |
||||
pub use borrow::ToOwned; |
||||
#[doc(no_inline)] |
||||
pub use clone::Clone; |
||||
#[doc(no_inline)] |
||||
pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; |
||||
#[doc(no_inline)] |
||||
pub use convert::{AsRef, AsMut, Into, From}; |
||||
#[doc(no_inline)] |
||||
pub use default::Default; |
||||
#[doc(no_inline)] |
||||
pub use iter::{Iterator, Extend, IntoIterator}; |
||||
#[doc(no_inline)] |
||||
pub use iter::{DoubleEndedIterator, ExactSizeIterator}; |
||||
#[doc(no_inline)] |
||||
pub use option::Option::{self, Some, None}; |
||||
#[doc(no_inline)] |
||||
pub use result::Result::{self, Ok, Err}; |
||||
#[doc(no_inline)] |
||||
pub use slice::SliceConcatExt; |
||||
#[doc(no_inline)] |
||||
pub use string::{String, ToString}; |
||||
#[doc(no_inline)] |
||||
pub use vec::Vec; |
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
mod mutex; |
||||
|
||||
pub use self::mutex::{Mutex, MutexGuard}; |
||||
|
||||
pub type LockResult<T> = Result<T, ()>; |
@ -1,92 +0,0 @@
@@ -1,92 +0,0 @@
|
||||
use cell::UnsafeCell; |
||||
use borrow::{Borrow, BorrowMut}; |
||||
use ops::{Deref, DerefMut}; |
||||
|
||||
use super::LockResult; |
||||
|
||||
use libctru::synchronization::*; |
||||
|
||||
/// A mutex based on libctru's LightLock primitive
|
||||
pub struct Mutex<T: ?Sized> { |
||||
mutex: Box<LightLock>, |
||||
data: UnsafeCell<T>, |
||||
} |
||||
|
||||
/// Mutex guard
|
||||
#[must_use] |
||||
pub struct MutexGuard<'a, T: ?Sized + 'a> { |
||||
inner: &'a Mutex<T>, |
||||
} |
||||
|
||||
// NOTE: This is used when implementing condvar, which hasn't been done yet
|
||||
#[allow(dead_code)] |
||||
pub fn guard_lock<'a, T: ?Sized + 'a>(guard: &'a MutexGuard<'a, T>) -> &'a LightLock { |
||||
&guard.inner.mutex |
||||
} |
||||
|
||||
impl<T> Mutex<T> { |
||||
pub fn new(t: T) -> Mutex<T> { |
||||
unsafe { |
||||
let mut mutex = Box::new(0); |
||||
LightLock_Init(mutex.borrow_mut()); |
||||
Mutex { |
||||
mutex: mutex, |
||||
data: UnsafeCell::new(t), |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn into_inner(self) -> T { |
||||
unsafe { self.data.into_inner() } |
||||
} |
||||
} |
||||
|
||||
impl<T: ?Sized> Mutex<T> { |
||||
pub fn lock(&self) -> MutexGuard<T> { |
||||
unsafe { |
||||
LightLock_Lock(self.mutex.borrow()); |
||||
MutexGuard { inner: self } |
||||
} |
||||
} |
||||
|
||||
pub fn try_lock(&self) -> LockResult<MutexGuard<T>> { |
||||
unsafe { |
||||
let locked = LightLock_TryLock(self.mutex.borrow()); |
||||
if locked == 0 { |
||||
Ok(MutexGuard { inner: self }) |
||||
} else { |
||||
Err(()) |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn get_mut(&mut self) -> &mut T { |
||||
unsafe { &mut *self.data.get() } |
||||
} |
||||
} |
||||
|
||||
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {} |
||||
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {} |
||||
|
||||
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> { |
||||
fn drop(&mut self) { |
||||
unsafe { LightLock_Unlock(self.inner.mutex.borrow()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> { |
||||
type Target = T; |
||||
|
||||
fn deref(&self) -> &T { |
||||
unsafe { &*self.inner.data.get() } |
||||
} |
||||
} |
||||
|
||||
impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> { |
||||
fn deref_mut(&mut self) -> &mut T { |
||||
unsafe { &mut *self.inner.data.get() } |
||||
} |
||||
} |
||||
|
||||
impl<'a, T: ?Sized> !Send for MutexGuard<'a, T> {} |
@ -1,25 +0,0 @@
@@ -1,25 +0,0 @@
|
||||
/// A trait for viewing representations from std types
|
||||
#[doc(hidden)] |
||||
pub trait AsInner<Inner: ?Sized> { |
||||
fn as_inner(&self) -> &Inner; |
||||
} |
||||
|
||||
/// A trait for viewing representations from std types
|
||||
#[doc(hidden)] |
||||
pub trait AsInnerMut<Inner: ?Sized> { |
||||
fn as_inner_mut(&mut self) -> &mut Inner; |
||||
} |
||||
|
||||
/// A trait for extracting representations from std types
|
||||
#[doc(hidden)] |
||||
pub trait IntoInner<Inner> { |
||||
fn into_inner(self) -> Inner; |
||||
} |
||||
|
||||
/// A trait for creating std types from internal representations
|
||||
#[doc(hidden)] |
||||
pub trait FromInner<Inner> { |
||||
fn from_inner(inner: Inner) -> Self; |
||||
} |
||||
|
||||
pub mod wtf8; |
Loading…
Reference in new issue