Browse Source

Split out libstd crate

pull/10/head
Fenrir 8 years ago
parent
commit
539fa2a425
  1. 14
      Cargo.toml
  2. 407
      ctru-sys/src/svc.rs
  3. 37
      ctru-sys/src/synchronization.rs
  4. 2
      ctru-sys/src/sys/libc.rs
  5. 23
      ctru-sys/src/sys/lock.rs
  6. 6
      src/console.rs
  7. 14
      src/gfx.rs
  8. 66
      src/lib.rs
  9. 2
      src/sdmc.rs
  10. 2
      src/services/apt.rs
  11. 11
      src/services/fs.rs
  12. 2
      src/services/gspgpu.rs
  13. 4
      src/services/hid.rs
  14. 2
      src/srv.rs
  15. 9
      src/system/mod.rs
  16. 9
      src/system/rt.rs
  17. 17
      std/Cargo.toml
  18. 5
      std/src/ascii.rs
  19. 17
      std/src/error.rs
  20. 24
      std/src/ffi/c_str.rs
  21. 0
      std/src/ffi/mod.rs
  22. 20
      std/src/ffi/os_str.rs
  23. 12
      std/src/io/buffered.rs
  24. 6
      std/src/io/cursor.rs
  25. 6
      std/src/io/error.rs
  26. 8
      std/src/io/impls.rs
  27. 14
      std/src/io/mod.rs
  28. 0
      std/src/io/prelude.rs
  29. 32
      std/src/io/print.rs
  30. 2
      std/src/io/util.rs
  31. 100
      std/src/lib.rs
  32. 394
      std/src/macros.rs
  33. 0
      std/src/memchr.rs
  34. 1826
      std/src/num/f32.rs
  35. 1712
      std/src/num/f64.rs
  36. 293
      std/src/num/mod.rs
  37. 25
      std/src/panicking.rs
  38. 20
      std/src/path.rs
  39. 1
      std/src/prelude/mod.rs
  40. 49
      std/src/prelude/v1.rs
  41. 30
      std/src/rt.rs
  42. 5
      std/src/sync/mod.rs
  43. 92
      std/src/sync/mutex.rs
  44. 0
      std/src/sys/mod.rs
  45. 18
      std/src/sys/wtf8.rs

14
Cargo.toml

@ -5,14 +5,14 @@ description = "A safe wrapper around smealum's ctrulib."
license = "https://en.wikipedia.org/wiki/Zlib_License" license = "https://en.wikipedia.org/wiki/Zlib_License"
links = "ctru" links = "ctru"
name = "ctru-rs" name = "ctru-rs"
version = "0.4.0" version = "0.5.0"
[dependencies.ctru-sys]
path = "ctru-sys"
[dependencies.alloc_system3ds]
git = "https://github.com/rust3ds/alloc_system3ds"
[lib] [lib]
crate-type = ["rlib"] crate-type = ["rlib"]
name = "ctru" name = "ctru"
[dependencies.ctru-sys]
path = "ctru-sys"
[dependencies.std]
path = "std"

407
ctru-sys/src/svc.rs

@ -1,13 +1,17 @@
//TODO: Implement static functions /* automatically generated by rust-bindgen */
use {Handle, Result}; #![allow(dead_code,
use libc::c_void; non_camel_case_types,
use ThreadFunc; non_upper_case_globals,
use types::*; non_snake_case)]
#[derive(Clone, Copy)] use ::{Handle, Result};
#[repr(C)] use ::ThreadFunc;
pub enum Enum_Unnamed1 {
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum MemOp {
MEMOP_FREE = 1, MEMOP_FREE = 1,
MEMOP_RESERVE = 2, MEMOP_RESERVE = 2,
MEMOP_ALLOC = 3, MEMOP_ALLOC = 3,
@ -22,10 +26,10 @@ pub enum Enum_Unnamed1 {
MEMOP_LINEAR_FLAG = 65536, MEMOP_LINEAR_FLAG = 65536,
MEMOP_ALLOC_LINEAR = 65539, MEMOP_ALLOC_LINEAR = 65539,
} }
pub type MemOp = Enum_Unnamed1; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed2 { pub enum MemState {
MEMSTATE_FREE = 0, MEMSTATE_FREE = 0,
MEMSTATE_RESERVED = 1, MEMSTATE_RESERVED = 1,
MEMSTATE_IO = 2, MEMSTATE_IO = 2,
@ -39,142 +43,128 @@ pub enum Enum_Unnamed2 {
MEMSTATE_ALIASCODE = 10, MEMSTATE_ALIASCODE = 10,
MEMSTATE_LOCKED = 11, MEMSTATE_LOCKED = 11,
} }
pub type MemState = Enum_Unnamed2; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed3 { pub enum MemPerm {
MEMPERM_READ = 1, MEMPERM_READ = 1,
MEMPERM_WRITE = 2, MEMPERM_WRITE = 2,
MEMPERM_EXECUTE = 4, MEMPERM_EXECUTE = 4,
MEMPERM_DONTCARE = 268435456, MEMPERM_DONTCARE = 268435456,
} }
pub type MemPerm = Enum_Unnamed3;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed4 { #[derive(Debug)]
pub struct MemInfo {
pub base_addr: u32, pub base_addr: u32,
pub size: u32, pub size: u32,
pub perm: u32, pub perm: u32,
pub state: u32, pub state: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed4 { impl ::core::default::Default for MemInfo {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed4 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type MemInfo = Struct_Unnamed4;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed5 { #[derive(Debug)]
pub struct PageInfo {
pub flags: u32, pub flags: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed5 { impl ::core::default::Default for PageInfo {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed5 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type PageInfo = Struct_Unnamed5; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed6 { pub enum ArbitrationType {
ARBITRATION_SIGNAL = 0, ARBITRATION_SIGNAL = 0,
ARBITRATION_WAIT_IF_LESS_THAN = 1, ARBITRATION_WAIT_IF_LESS_THAN = 1,
ARBITRATION_DECREMENT_AND_WAIT_IF_LESS_THAN = 2, ARBITRATION_DECREMENT_AND_WAIT_IF_LESS_THAN = 2,
ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT = 3, ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT = 3,
ARBITRATION_DECREMENT_AND_WAIT_IF_LESS_THAN_TIMEOUT = 4, ARBITRATION_DECREMENT_AND_WAIT_IF_LESS_THAN_TIMEOUT = 4,
} }
pub type ArbitrationType = Enum_Unnamed6; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed7 { THREADINFO_TYPE_UNKNOWN = 0, } pub enum ResetType { RESET_ONESHOT = 0, RESET_STICKY = 1, RESET_PULSE = 2, }
pub type ThreadInfoType = Enum_Unnamed7; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[derive(Debug)]
pub enum ThreadInfoType { THREADINFO_TYPE_UNKNOWN = 0, }
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ProcessEventReason { REASON_CREATE = 1, REASON_ATTACH = 2, }
#[repr(C)] #[repr(C)]
pub enum Enum_Unnamed8 { REASON_CREATE = 1, REASON_ATTACH = 2, } #[derive(Copy, Clone)]
pub type ProcessEventReason = Enum_Unnamed8; #[derive(Debug)]
#[repr(C)] pub struct ProcessEvent {
#[derive(Copy)]
pub struct Struct_Unnamed9 {
pub program_id: u64, pub program_id: u64,
pub process_name: [u8; 8usize], pub process_name: [u8; 8usize],
pub process_id: u32, pub process_id: u32,
pub reason: u32, pub reason: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed9 { impl ::core::default::Default for ProcessEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed9 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type ProcessEvent = Struct_Unnamed9; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed10 { pub enum ExitProcessEventReason {
EXITPROCESS_EVENT_NONE = 0, EXITPROCESS_EVENT_NONE = 0,
EXITPROCESS_EVENT_TERMINATE = 1, EXITPROCESS_EVENT_TERMINATE = 1,
EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2, EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2,
} }
pub type ExitProcessEventReason = Enum_Unnamed10;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed11 { #[derive(Debug)]
pub struct ExitProcessEvent {
pub reason: u32, pub reason: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed11 { impl ::core::default::Default for ExitProcessEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed11 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type ExitProcessEvent = Struct_Unnamed11;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed12 { #[derive(Debug)]
pub struct CreateThreadEvent {
pub creator_thread_id: u32, pub creator_thread_id: u32,
pub base_addr: u32, pub base_addr: u32,
pub entry_point: u32, pub entry_point: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed12 { impl ::core::default::Default for CreateThreadEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed12 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type CreateThreadEvent = Struct_Unnamed12; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed13 { pub enum ExitThreadEventReason {
EXITTHREAD_EVENT_NONE = 0, EXITTHREAD_EVENT_NONE = 0,
EXITTHREAD_EVENT_TERMINATE = 1, EXITTHREAD_EVENT_TERMINATE = 1,
EXITTHREAD_EVENT_UNHANDLED_EXC = 2, EXITTHREAD_EVENT_UNHANDLED_EXC = 2,
EXITTHREAD_EVENT_TERMINATE_PROCESS = 3, EXITTHREAD_EVENT_TERMINATE_PROCESS = 3,
} }
pub type ExitThreadEventReason = Enum_Unnamed13;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed14 { #[derive(Debug)]
pub struct ExitThreadEvent {
pub reason: u32, pub reason: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed14 { impl ::core::default::Default for ExitThreadEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed14 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type ExitThreadEvent = Struct_Unnamed14; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed15 { pub enum UserBreakType {
USERBREAK_PANIC = 0, USERBREAK_PANIC = 0,
USERBREAK_ASSERT = 1, USERBREAK_ASSERT = 1,
USERBREAK_USER = 2, USERBREAK_USER = 2,
} }
pub type UserBreakType = Enum_Unnamed15; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed16 { pub enum ExceptionEventType {
EXC_EVENT_UNDEFINED_INSTRUCTION = 0, EXC_EVENT_UNDEFINED_INSTRUCTION = 0,
EXC_EVENT_UNKNOWN1 = 1, EXC_EVENT_UNKNOWN1 = 1,
EXC_EVENT_UNKNOWN2 = 2, EXC_EVENT_UNKNOWN2 = 2,
@ -185,77 +175,63 @@ pub enum Enum_Unnamed16 {
EXC_EVENT_DEBUGGER_BREAK = 7, EXC_EVENT_DEBUGGER_BREAK = 7,
EXC_EVENT_UNDEFINED_SYSCALL = 8, EXC_EVENT_UNDEFINED_SYSCALL = 8,
} }
pub type ExceptionEventType = Enum_Unnamed16;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed17 { #[derive(Debug)]
pub _type: u32, pub struct ExceptionEvent {
pub type_: u32,
pub address: u32, pub address: u32,
pub argument: u32, pub argument: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed17 { impl ::core::default::Default for ExceptionEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed17 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type ExceptionEvent = Struct_Unnamed17;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed18 { #[derive(Debug)]
pub struct SchedulerInOutEvent {
pub clock_tick: u64, pub clock_tick: u64,
} }
impl ::core::clone::Clone for Struct_Unnamed18 { impl ::core::default::Default for SchedulerInOutEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed18 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type SchedulerInOutEvent = Struct_Unnamed18;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed19 { #[derive(Debug)]
pub struct SyscallInOutEvent {
pub clock_tick: u64, pub clock_tick: u64,
pub syscall: u32, pub syscall: u32,
_bindgen_padding_0_: [u8; 4usize],
} }
impl ::core::clone::Clone for Struct_Unnamed19 { impl ::core::default::Default for SyscallInOutEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed19 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type SyscallInOutEvent = Struct_Unnamed19;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed20 { #[derive(Debug)]
pub struct OutputStringEvent {
pub string_addr: u32, pub string_addr: u32,
pub string_size: u32, pub string_size: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed20 { impl ::core::default::Default for OutputStringEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed20 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type OutputStringEvent = Struct_Unnamed20;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed21 { #[derive(Debug)]
pub struct MapEvent {
pub mapped_addr: u32, pub mapped_addr: u32,
pub mapped_size: u32, pub mapped_size: u32,
pub memperm: u32, pub memperm: u32,
pub memstate: u32, pub memstate: u32,
} }
impl ::core::clone::Clone for Struct_Unnamed21 { impl ::core::default::Default for MapEvent {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct_Unnamed21 {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type MapEvent = Struct_Unnamed21; #[derive(Copy, Clone)]
#[derive(Clone, Copy)] #[repr(u32)]
#[repr(C)] #[derive(Debug)]
pub enum Enum_Unnamed22 { pub enum DebugEventType {
DBG_EVENT_PROCESS = 0, DBG_EVENT_PROCESS = 0,
DBG_EVENT_CREATE_THREAD = 1, DBG_EVENT_CREATE_THREAD = 1,
DBG_EVENT_EXIT_THREAD = 2, DBG_EVENT_EXIT_THREAD = 2,
@ -270,16 +246,16 @@ pub enum Enum_Unnamed22 {
DBG_EVENT_OUTPUT_STRING = 11, DBG_EVENT_OUTPUT_STRING = 11,
DBG_EVENT_MAP = 12, DBG_EVENT_MAP = 12,
} }
pub type DebugEventType = Enum_Unnamed22;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct_Unnamed23 { #[derive(Debug)]
pub _type: u32, pub struct DebugEventInfo {
pub type_: u32,
pub thread_id: u32, pub thread_id: u32,
pub unknown: [u32; 2usize], pub unknown: [u32; 2usize],
pub _bindgen_data_1_: [u64; 3usize], pub _bindgen_data_1_: [u64; 3usize],
} }
impl Struct_Unnamed23 { impl DebugEventInfo {
pub unsafe fn process(&mut self) -> *mut ProcessEvent { pub unsafe fn process(&mut self) -> *mut ProcessEvent {
let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_); let raw: *mut u8 = ::core::mem::transmute(&self._bindgen_data_1_);
::core::mem::transmute(raw.offset(0)) ::core::mem::transmute(raw.offset(0))
@ -317,18 +293,50 @@ impl Struct_Unnamed23 {
::core::mem::transmute(raw.offset(0)) ::core::mem::transmute(raw.offset(0))
} }
} }
impl ::core::clone::Clone for Struct_Unnamed23 { impl ::core::default::Default for DebugEventInfo {
fn clone(&self) -> Self { *self } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct CodeSetInfo {
pub name: [u8; 8usize],
pub unk1: u16,
pub unk2: u16,
pub unk3: u32,
pub text_addr: u32,
pub text_size: u32,
pub ro_addr: u32,
pub ro_size: u32,
pub rw_addr: u32,
pub rw_size: u32,
pub text_size_total: u32,
pub ro_size_total: u32,
pub rw_size_total: u32,
pub unk4: u32,
pub program_id: u64,
}
impl ::core::default::Default for CodeSetInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
impl ::core::default::Default for Struct_Unnamed23 { #[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct StartupInfo {
pub priority: ::libc::c_int,
pub stack_size: u32,
pub argc: ::libc::c_int,
pub argv: *mut u16,
pub envp: *mut u16,
}
impl ::core::default::Default for StartupInfo {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type DebugEventInfo = Struct_Unnamed23;
extern "C" { extern "C" {
pub fn svcControlMemory(addr_out: *mut u32, addr0: u32, addr1: u32, pub fn svcControlMemory(addr_out: *mut u32, addr0: u32, addr1: u32,
size: u32, op: MemOp, perm: MemPerm) -> Result; size: u32, op: MemOp, perm: MemPerm) -> Result;
pub fn svcControlProcessMemory(process: Handle, addr0: u32, addr1: u32, pub fn svcControlProcessMemory(process: Handle, addr0: u32, addr1: u32,
size: u32, _type: u32, perm: u32) size: u32, type_: u32, perm: u32)
-> Result; -> Result;
pub fn svcCreateMemoryBlock(memblock: *mut Handle, addr: u32, size: u32, pub fn svcCreateMemoryBlock(memblock: *mut Handle, addr: u32, size: u32,
my_perm: MemPerm, other_perm: MemPerm) my_perm: MemPerm, other_perm: MemPerm)
@ -341,102 +349,125 @@ extern "C" {
endAddr: u32) -> Result; endAddr: u32) -> Result;
pub fn svcUnmapMemoryBlock(memblock: Handle, addr: u32) -> Result; pub fn svcUnmapMemoryBlock(memblock: Handle, addr: u32) -> Result;
pub fn svcStartInterProcessDma(dma: *mut Handle, dstProcess: Handle, pub fn svcStartInterProcessDma(dma: *mut Handle, dstProcess: Handle,
dst: *mut c_void, dst: *mut ::libc::c_void,
srcProcess: Handle, srcProcess: Handle,
src: *const c_void, src: *const ::libc::c_void, size: u32,
size: u32, dmaConfig: *mut ::libc::c_void) -> Result;
dmaConfig: *mut c_void)
-> Result;
pub fn svcStopDma(dma: Handle) -> Result; pub fn svcStopDma(dma: Handle) -> Result;
pub fn svcGetDmaState(dmaState: *mut c_void, dma: Handle) pub fn svcGetDmaState(dmaState: *mut ::libc::c_void, dma: Handle)
-> Result; -> Result;
pub fn svcQueryMemory(info: *mut MemInfo, out: *mut PageInfo, addr: u32) pub fn svcQueryMemory(info: *mut MemInfo, out: *mut PageInfo, addr: u32)
-> Result; -> Result;
pub fn svcQueryProcessMemory(info: *mut MemInfo, out: *mut PageInfo, pub fn svcQueryProcessMemory(info: *mut MemInfo, out: *mut PageInfo,
process: Handle, addr: u32) -> Result; process: Handle, addr: u32) -> Result;
pub fn svcInvalidateProcessDataCache(process: Handle, pub fn svcInvalidateProcessDataCache(process: Handle,
addr: *mut c_void, addr: *mut ::libc::c_void,
size: u32) -> Result; size: u32) -> Result;
pub fn svcFlushProcessDataCache(process: Handle, pub fn svcFlushProcessDataCache(process: Handle,
addr: *const c_void, addr: *const ::libc::c_void, size: u32)
size: u32) -> Result;
pub fn svcReadProcessMemory(buffer: *mut c_void,
debug: Handle, addr: u32, size: u32)
-> Result; -> Result;
pub fn svcWriteProcessMemory(debug: Handle, pub fn svcReadProcessMemory(buffer: *mut ::libc::c_void, debug: Handle,
buffer: *const c_void, addr: u32, size: u32) -> Result;
pub fn svcWriteProcessMemory(debug: Handle, buffer: *const ::libc::c_void,
addr: u32, size: u32) -> Result; addr: u32, size: u32) -> Result;
pub fn svcOpenProcess(process: *mut Handle, processId: u32) -> Result; pub fn svcOpenProcess(process: *mut Handle, processId: u32) -> Result;
pub fn svcExitProcess(); pub fn svcExitProcess();
pub fn svcTerminateProcess(process: Handle) -> Result; pub fn svcTerminateProcess(process: Handle) -> Result;
pub fn svcGetProcessInfo(out: *mut s64, process: Handle, _type: u32) pub fn svcGetProcessInfo(out: *mut i64, process: Handle, type_: u32)
-> Result; -> Result;
pub fn svcGetProcessId(out: *mut u32, handle: Handle) -> Result; pub fn svcGetProcessId(out: *mut u32, handle: Handle) -> Result;
pub fn svcGetProcessList(processCount: *mut s32, processIds: *mut u32, pub fn svcGetProcessList(processCount: *mut i32, processIds: *mut u32,
processIdMaxCount: s32) -> Result; processIdMaxCount: i32) -> Result;
pub fn svcCreatePort(portServer: *mut Handle, portClient: *mut Handle, pub fn svcCreatePort(portServer: *mut Handle, portClient: *mut Handle,
name: *const u8, name: *const ::libc::c_char, maxSessions: i32)
maxSessions: s32) -> Result; -> Result;
pub fn svcConnectToPort(out: *mut Handle, pub fn svcConnectToPort(out: *mut Handle, portName: *const ::libc::c_char)
portName: *const u8) -> Result;
pub fn svcCreateCodeSet(out: *mut Handle, info: *const CodeSetInfo,
code_ptr: *mut ::libc::c_void,
ro_ptr: *mut ::libc::c_void,
data_ptr: *mut ::libc::c_void) -> Result;
pub fn svcCreateProcess(out: *mut Handle, codeset: Handle,
arm11kernelcaps: *const u32,
arm11kernelcaps_num: u32) -> Result;
pub fn svcSetProcessAffinityMask(process: Handle,
affinitymask: *const u8,
processorcount: i32) -> Result;
pub fn svcSetProcessIdealProcessor(process: Handle, processorid: i32)
-> Result; -> Result;
pub fn svcRun(process: Handle, info: *const StartupInfo) -> Result;
pub fn svcCreateThread(thread: *mut Handle, entrypoint: ThreadFunc, pub fn svcCreateThread(thread: *mut Handle, entrypoint: ThreadFunc,
arg: u32, stack_top: *mut u32, arg: u32, stack_top: *mut u32,
thread_priority: s32, processor_id: s32) -> Result; thread_priority: i32, processor_id: i32) -> Result;
pub fn svcOpenThread(thread: *mut Handle, process: Handle, threadId: u32) pub fn svcOpenThread(thread: *mut Handle, process: Handle, threadId: u32)
-> Result; -> Result;
pub fn svcExitThread(); pub fn svcExitThread();
pub fn svcSleepThread(ns: s64); pub fn svcSleepThread(ns: i64);
pub fn svcGetThreadPriority(out: *mut s32, handle: Handle) -> Result; pub fn svcGetThreadPriority(out: *mut i32, handle: Handle) -> Result;
pub fn svcSetThreadPriority(thread: Handle, prio: s32) -> Result; pub fn svcSetThreadPriority(thread: Handle, prio: i32) -> Result;
pub fn svcGetThreadAffinityMask(affinitymask: *mut u8, thread: Handle, pub fn svcGetThreadAffinityMask(affinitymask: *mut u8, thread: Handle,
processorcount: s32) -> Result; processorcount: i32) -> Result;
pub fn svcSetThreadAffinityMask(thread: Handle, affinitymask: *mut u8, pub fn svcSetThreadAffinityMask(thread: Handle, affinitymask: *const u8,
processorcount: s32) -> Result; processorcount: i32) -> Result;
pub fn svcGetThreadIdealProcessor(processorid: *mut s32, thread: Handle) pub fn svcGetThreadIdealProcessor(processorid: *mut i32, thread: Handle)
-> Result; -> Result;
pub fn svcSetThreadIdealProcessor(thread: Handle, processorid: s32) pub fn svcSetThreadIdealProcessor(thread: Handle, processorid: i32)
-> Result; -> Result;
pub fn svcGetProcessorID() -> s32; pub fn svcGetProcessorID() -> i32;
pub fn svcGetThreadId(out: *mut u32, handle: Handle) -> Result; pub fn svcGetThreadId(out: *mut u32, handle: Handle) -> Result;
pub fn svcGetResourceLimit(resourceLimit: *mut Handle, process: Handle)
-> Result;
pub fn svcGetResourceLimitLimitValues(values: *mut i64,
resourceLimit: Handle,
names: *mut u32, nameCount: i32)
-> Result;
pub fn svcGetResourceLimitCurrentValues(values: *mut i64,
resourceLimit: Handle,
names: *mut u32, nameCount: i32)
-> Result;
pub fn svcGetProcessIdOfThread(out: *mut u32, handle: Handle) -> Result; pub fn svcGetProcessIdOfThread(out: *mut u32, handle: Handle) -> Result;
pub fn svcGetThreadInfo(out: *mut s64, thread: Handle, pub fn svcGetThreadInfo(out: *mut i64, thread: Handle,
_type: ThreadInfoType) -> Result; type_: ThreadInfoType) -> Result;
pub fn svcCreateMutex(mutex: *mut Handle, initially_locked: u8) -> Result; pub fn svcCreateMutex(mutex: *mut Handle, initially_locked: u8) -> Result;
pub fn svcReleaseMutex(handle: Handle) -> Result; pub fn svcReleaseMutex(handle: Handle) -> Result;
pub fn svcCreateSemaphore(semaphore: *mut Handle, initial_count: s32, pub fn svcCreateSemaphore(semaphore: *mut Handle, initial_count: i32,
max_count: s32) -> Result; max_count: i32) -> Result;
pub fn svcReleaseSemaphore(count: *mut s32, semaphore: Handle, pub fn svcReleaseSemaphore(count: *mut i32, semaphore: Handle,
release_count: s32) -> Result; release_count: i32) -> Result;
pub fn svcCreateEvent(event: *mut Handle, reset_type: u8) -> Result; pub fn svcCreateEvent(event: *mut Handle, reset_type: ResetType)
-> Result;
pub fn svcSignalEvent(handle: Handle) -> Result; pub fn svcSignalEvent(handle: Handle) -> Result;
pub fn svcClearEvent(handle: Handle) -> Result; pub fn svcClearEvent(handle: Handle) -> Result;
pub fn svcWaitSynchronization(handle: Handle, nanoseconds: s64) -> Result; pub fn svcWaitSynchronization(handle: Handle, nanoseconds: i64) -> Result;
pub fn svcWaitSynchronizationN(out: *mut s32, handles: *mut Handle, pub fn svcWaitSynchronizationN(out: *mut i32, handles: *mut Handle,
handles_num: s32, wait_all: u8, handles_num: i32, wait_all: u8,
nanoseconds: s64) -> Result; nanoseconds: i64) -> Result;
pub fn svcCreateAddressArbiter(arbiter: *mut Handle) -> Result; pub fn svcCreateAddressArbiter(arbiter: *mut Handle) -> Result;
pub fn svcArbitrateAddress(arbiter: Handle, addr: u32, pub fn svcArbitrateAddress(arbiter: Handle, addr: u32,
_type: ArbitrationType, value: s32, type_: ArbitrationType, value: i32,
nanoseconds: s64) -> Result; nanoseconds: i64) -> Result;
pub fn svcSendSyncRequest(session: Handle) -> Result; pub fn svcSendSyncRequest(session: Handle) -> Result;
pub fn svcAcceptSession(session: *mut Handle, port: Handle) -> Result; pub fn svcAcceptSession(session: *mut Handle, port: Handle) -> Result;
pub fn svcReplyAndReceive(index: *mut s32, handles: *mut Handle, pub fn svcReplyAndReceive(index: *mut i32, handles: *mut Handle,
handleCount: s32, replyTarget: Handle) handleCount: i32, replyTarget: Handle)
-> Result;
pub fn svcBindInterrupt(interruptId: u32, event: Handle, priority: i32,
isManualClear: u8) -> Result;
pub fn svcUnbindInterrupt(interruptId: u32, event: Handle) -> Result;
pub fn svcCreateTimer(timer: *mut Handle, reset_type: ResetType)
-> Result; -> Result;
pub fn svcCreateTimer(timer: *mut Handle, reset_type: u8) -> Result; pub fn svcSetTimer(timer: Handle, initial: i64, interval: i64) -> Result;
pub fn svcSetTimer(timer: Handle, initial: s64, interval: s64) -> Result;
pub fn svcCancelTimer(timer: Handle) -> Result; pub fn svcCancelTimer(timer: Handle) -> Result;
pub fn svcClearTimer(timer: Handle) -> Result; pub fn svcClearTimer(timer: Handle) -> Result;
pub fn svcGetSystemTick() -> u64; pub fn svcGetSystemTick() -> u64;
pub fn svcCloseHandle(handle: Handle) -> Result; pub fn svcCloseHandle(handle: Handle) -> Result;
pub fn svcDuplicateHandle(out: *mut Handle, original: Handle) -> Result; pub fn svcDuplicateHandle(out: *mut Handle, original: Handle) -> Result;
pub fn svcGetSystemInfo(out: *mut s64, _type: u32, param: s32) -> Result; pub fn svcGetSystemInfo(out: *mut i64, type_: u32, param: i32) -> Result;
pub fn svcKernelSetState(_type: u32, param0: u32, param1: u32, pub fn svcKernelSetState(type_: u32, param0: u32, param1: u32,
param2: u32) -> Result; param2: u32) -> Result;
pub fn svcBreak(breakReason: UserBreakType); pub fn svcBreak(breakReason: UserBreakType);
pub fn svcOutputDebugString(str: *const u8, pub fn svcOutputDebugString(str: *const ::libc::c_char,
length: i32) -> Result; length: ::libc::c_int) -> Result;
pub fn svcDebugActiveProcess(debug: *mut Handle, processId: u32) pub fn svcDebugActiveProcess(debug: *mut Handle, processId: u32)
-> Result; -> Result;
pub fn svcBreakDebugProcess(debug: Handle) -> Result; pub fn svcBreakDebugProcess(debug: Handle) -> Result;
@ -445,6 +476,6 @@ extern "C" {
-> Result; -> Result;
pub fn svcContinueDebugEvent(debug: Handle, flags: u32) -> Result; pub fn svcContinueDebugEvent(debug: Handle, flags: u32) -> Result;
pub fn svcBackdoor(callback: pub fn svcBackdoor(callback:
::core::option::Option<extern "C" fn() -> s32>) ::core::option::Option<extern "C" fn() -> i32>)
-> Result; -> Result;
} }

37
ctru-sys/src/synchronization.rs

@ -1,19 +1,40 @@
//TODO: Implement stuff that bindgen doesn't catch /* automatically generated by rust-bindgen */
use Handle; #![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
use Handle;
use svc::ResetType;
use super::lock::*; use super::lock::*;
pub type LightLock = _LOCK_T; pub type LightLock = _LOCK_T;
pub type RecursiveLock = _LOCK_RECURSIVE_T; pub type RecursiveLock = _LOCK_RECURSIVE_T;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct LightEvent {
pub state: i32,
pub lock: LightLock,
}
impl ::core::default::Default for LightEvent {
fn default() -> Self { unsafe { ::core::mem::zeroed() } }
}
extern "C" { extern "C" {
pub fn __sync_get_arbiter() -> Handle; pub fn __sync_get_arbiter() -> Handle;
pub fn LightLock_Init(lock: *mut LightLock); pub fn LightLock_Init(lock: *mut LightLock);
pub fn LightLock_Lock(lock: *mut LightLock); pub fn LightLock_Lock(lock: *const LightLock);
pub fn LightLock_TryLock(lock: *mut LightLock) -> i32; pub fn LightLock_TryLock(lock: *const LightLock) -> ::libc::c_int;
pub fn LightLock_Unlock(lock: *mut LightLock); pub fn LightLock_Unlock(lock: *const LightLock);
pub fn RecursiveLock_Init(lock: *mut RecursiveLock); pub fn RecursiveLock_Init(lock: *mut RecursiveLock);
pub fn RecursiveLock_Lock(lock: *mut RecursiveLock); pub fn RecursiveLock_Lock(lock: *const RecursiveLock);
pub fn RecursiveLock_TryLock(lock: *mut RecursiveLock) -> i32; pub fn RecursiveLock_TryLock(lock: *const RecursiveLock) -> ::libc::c_int;
pub fn RecursiveLock_Unlock(lock: *mut RecursiveLock); pub fn RecursiveLock_Unlock(lock: *const RecursiveLock);
pub fn LightEvent_Init(event: *mut LightEvent, reset_type: ResetType);
pub fn LightEvent_Clear(event: *mut LightEvent);
pub fn LightEvent_Pulse(event: *mut LightEvent);
pub fn LightEvent_Signal(event: *mut LightEvent);
pub fn LightEvent_TryWait(event: *mut LightEvent) -> ::libc::c_int;
pub fn LightEvent_Wait(event: *mut LightEvent);
} }

2
ctru-sys/src/sys/libc.rs

@ -17,6 +17,8 @@ pub type c_long = i32;
pub type c_ulong = u32; pub type c_ulong = u32;
pub type c_longlong = i64; pub type c_longlong = i64;
pub type c_ulonglong = u64; pub type c_ulonglong = u64;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = usize; pub type size_t = usize;
pub type ssize_t = isize; pub type ssize_t = isize;

23
ctru-sys/src/sys/lock.rs

@ -1,20 +1,22 @@
//<sys/lock.h> from devkitArm, needed for synchronization.rs to compile /* automatically generated by rust-bindgen */
#![allow(dead_code,
non_camel_case_types,
non_upper_case_globals,
non_snake_case)]
pub type _LOCK_T = i32; pub type _LOCK_T = i32;
#[repr(C)] #[repr(C)]
#[derive(Copy)] #[derive(Copy, Clone)]
pub struct Struct___lock_t { #[derive(Debug)]
pub struct __lock_t {
pub lock: _LOCK_T, pub lock: _LOCK_T,
pub thread_tag: u32, pub thread_tag: u32,
pub counter: u32, pub counter: u32,
} }
impl ::core::clone::Clone for Struct___lock_t { impl ::core::default::Default for __lock_t {
fn clone(&self) -> Self { *self }
}
impl ::core::default::Default for Struct___lock_t {
fn default() -> Self { unsafe { ::core::mem::zeroed() } } fn default() -> Self { unsafe { ::core::mem::zeroed() } }
} }
pub type _LOCK_RECURSIVE_T = Struct___lock_t; pub type _LOCK_RECURSIVE_T = __lock_t;
extern "C" { extern "C" {
pub fn __libc_lock_init(lock: *mut _LOCK_T); pub fn __libc_lock_init(lock: *mut _LOCK_T);
pub fn __libc_lock_init_recursive(lock: *mut _LOCK_RECURSIVE_T); pub fn __libc_lock_init_recursive(lock: *mut _LOCK_RECURSIVE_T);
@ -24,8 +26,7 @@ extern "C" {
pub fn __libc_lock_acquire_recursive(lock: *mut _LOCK_RECURSIVE_T); pub fn __libc_lock_acquire_recursive(lock: *mut _LOCK_RECURSIVE_T);
pub fn __libc_lock_release(lock: *mut _LOCK_T); pub fn __libc_lock_release(lock: *mut _LOCK_T);
pub fn __libc_lock_release_recursive(lock: *mut _LOCK_RECURSIVE_T); pub fn __libc_lock_release_recursive(lock: *mut _LOCK_RECURSIVE_T);
pub fn __libc_lock_try_acquire(lock: *mut _LOCK_T) pub fn __libc_lock_try_acquire(lock: *mut _LOCK_T) -> ::libc::c_int;
-> i32;
pub fn __libc_lock_try_acquire_recursive(lock: *mut _LOCK_RECURSIVE_T) pub fn __libc_lock_try_acquire_recursive(lock: *mut _LOCK_RECURSIVE_T)
-> i32; -> ::libc::c_int;
} }

6
src/console.rs

@ -3,9 +3,9 @@ use libctru::libc;
use gfx::Screen; use gfx::Screen;
use core::fmt::{self, Write}; use std::fmt::{self, Write};
use core::default::Default; use std::default::Default;
use core::ptr; use std::ptr;
pub struct Console { pub struct Console {
context: PrintConsole, context: PrintConsole,

14
src/gfx.rs

@ -1,8 +1,8 @@
use libctru::gfx; use libctru::gfx;
use core::default::Default; use std::default::Default;
use core::marker::PhantomData; use std::marker::PhantomData;
use core::ops::Drop; use std::ops::Drop;
use services::gspgpu::FramebufferFormat; use services::gspgpu::FramebufferFormat;
@ -82,9 +82,9 @@ impl Gfx {
} }
pub fn get_framebuffer(&mut self, screen: Screen, side: Side) -> (&'static mut [u8], u16, u16) { pub fn get_framebuffer(&mut self, screen: Screen, side: Side) -> (&'static mut [u8], u16, u16) {
use core::convert::Into; use std::convert::Into;
unsafe { unsafe {
use core::slice::from_raw_parts_mut; use std::slice::from_raw_parts_mut;
let mut w: u16 = 0; let mut w: u16 = 0;
let mut h: u16 = 0; let mut h: u16 = 0;
@ -112,12 +112,12 @@ impl Gfx {
} }
pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat { pub fn get_framebuffer_format(&self, screen: Screen) -> FramebufferFormat {
use core::convert::Into; use std::convert::Into;
unsafe { gfx::gfxGetScreenFormat(screen.into()).into() } unsafe { gfx::gfxGetScreenFormat(screen.into()).into() }
} }
pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) { pub fn set_framebuffer_format(&mut self, screen: Screen, fmt: FramebufferFormat) {
use core::convert::Into; use std::convert::Into;
unsafe { gfx::gfxSetScreenFormat(screen.into(), fmt.into()) } unsafe { gfx::gfxSetScreenFormat(screen.into(), fmt.into()) }
} }

66
src/lib.rs

@ -1,79 +1,13 @@
#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(collections)]
#![feature(core_intrinsics)]
#![feature(char_escape_debug)]
#![feature(int_error_internals)]
#![feature(lang_items)]
#![feature(macro_reexport)]
#![feature(prelude_import)]
#![feature(slice_concat_ext)]
#![feature(slice_patterns)]
#![feature(str_internals)]
#![feature(try_from)]
#![feature(unicode)]
#![no_std]
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![crate_name = "ctru"] #![crate_name = "ctru"]
extern crate alloc;
extern crate alloc_system;
#[macro_reexport(format, vec)]
#[macro_use]
extern crate collections;
extern crate rustc_unicode;
extern crate ctru_sys as libctru; extern crate ctru_sys as libctru;
#[prelude_import]
#[allow(unused)]
use prelude::*;
pub mod std {
pub use core::{any, cell, clone, cmp, convert, default, hash, i16, i32, i64, i8, isize, iter,
marker, mem, ops, option, ptr, result, u16, u32, u64, u8, usize, intrinsics};
pub use rustc_unicode::char;
pub use alloc::{arc, rc};
pub use collections::{borrow, boxed, fmt, slice, str, string, vec};
pub use system::{error, io, memchr, ascii, ffi, path};
pub mod collections {
pub use collections::{binary_heap, btree_map, btree_set, linked_list, vec_deque,
BinaryHeap, LinkedList, VecDeque, String, Vec, BTreeMap, BTreeSet};
}
}
pub mod prelude {
pub use std;
pub use std::marker::{Copy, Send, Sized, Sync};
pub use std::ops::{Drop, Fn, FnMut, FnOnce};
pub use std::mem::drop;
pub use std::boxed::Box;
pub use std::borrow::ToOwned;
pub use std::clone::Clone;
pub use std::cmp::{PartialEq, PartialOrd, Eq, Ord};
pub use std::convert::{AsRef, AsMut, Into, From};
pub use std::default::Default;
pub use std::iter::{Iterator, Extend, IntoIterator};
pub use std::iter::{DoubleEndedIterator, ExactSizeIterator};
pub use std::option::Option::{self, Some, None};
pub use std::result::Result::{self, Ok, Err};
pub use std::slice::SliceConcatExt;
pub use std::string::{String, ToString};
pub use std::vec::Vec;
pub use std::fmt::Write;
}
pub use std::{fmt, boxed, vec};
pub mod console; pub mod console;
pub mod srv; pub mod srv;
pub mod gfx; pub mod gfx;
pub mod services; pub mod services;
pub mod sdmc; pub mod sdmc;
pub mod system;
pub use srv::Srv; pub use srv::Srv;
pub use gfx::Gfx; pub use gfx::Gfx;

2
src/sdmc.rs

@ -1,4 +1,4 @@
use core::marker::PhantomData; use std::marker::PhantomData;
use libctru::sdmc::*; use libctru::sdmc::*;

2
src/services/apt.rs

@ -1,4 +1,4 @@
use core::marker::PhantomData; use std::marker::PhantomData;
use libctru::services::apt; use libctru::services::apt;

11
src/services/fs.rs

@ -4,12 +4,11 @@
//! Only the SD card is currently supported. //! Only the SD card is currently supported.
use core::marker::PhantomData; use std::marker::PhantomData;
use core::ptr; use std::ptr;
use core::slice; use std::slice;
use core::mem; use std::mem;
use alloc::arc::Arc; use std::arc::Arc;
use collections::Vec;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::ffi::OsString; use std::ffi::OsString;

2
src/services/gspgpu.rs

@ -1,6 +1,6 @@
use libctru::services::gspgpu; use libctru::services::gspgpu;
use core::convert::From; use std::convert::From;
pub enum Event { pub enum Event {
Psc0, Psc0,

4
src/services/hid.rs

@ -1,5 +1,5 @@
use core::convert::Into; use std::convert::Into;
use core::marker::PhantomData; use std::marker::PhantomData;
use libctru::services::hid; use libctru::services::hid;

2
src/srv.rs

@ -1,6 +1,6 @@
use libctru::srv::*; use libctru::srv::*;
use core::marker::PhantomData; use std::marker::PhantomData;
pub struct Srv { pub struct Srv {
pd: PhantomData<i32>, pd: PhantomData<i32>,

9
src/system/mod.rs

@ -1,9 +0,0 @@
pub mod ascii;
pub mod error;
pub mod ffi;
pub mod io;
pub mod memchr;
pub mod panicking;
pub mod path;
pub mod rt;
mod sys;

9
src/system/rt.rs

@ -1,9 +0,0 @@
use std::mem;
//TODO: Handle argc/argv arguments
#[lang = "start"]
#[allow(unused_variables)]
fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
unsafe { mem::transmute::<_, fn()>(main)(); }
0
}

17
std/Cargo.toml

@ -0,0 +1,17 @@
[package]
name = "std"
version = "0.0.0"
authors = ["Ronald Kinard <furyhunter600@gmail.com>"]
license = "https://en.wikipedia.org/wiki/Zlib_License"
[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"

5
src/system/ascii.rs → std/src/ascii.rs

@ -10,9 +10,8 @@
//! Operations on ASCII strings and characters. //! Operations on ASCII strings and characters.
use core::mem; use mem;
use core::ops::Range; use ops::Range;
use collections::{String, Vec};
/// Extension methods for ASCII-subset only operations on string slices. /// Extension methods for ASCII-subset only operations on string slices.
/// ///

17
src/system/error.rs → std/src/error.rs

@ -49,15 +49,14 @@
// coherence challenge (e.g., specialization, neg impls, etc) we can // coherence challenge (e.g., specialization, neg impls, etc) we can
// reconsider what crate these items belong in. // reconsider what crate these items belong in.
use core::any::TypeId; use any::TypeId;
use core::cell; use cell;
use rustc_unicode::char; use char;
use core::fmt::{self, Debug, Display}; use fmt::{self, Debug, Display};
use core::mem::transmute; use mem::transmute;
use core::num; use num;
use core::str; use str;
use collections::string::{self, String}; use string;
use alloc::boxed::Box;
/// Base functionality for all errors in Rust. /// Base functionality for all errors in Rust.
pub trait Error: Debug + Display { pub trait Error: Debug + Display {

24
src/system/ffi/c_str.rs → std/src/ffi/c_str.rs

@ -8,19 +8,19 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::ascii; use ascii;
use std::borrow::{Cow, Borrow}; use borrow::{Cow, Borrow};
use std::cmp::Ordering; use cmp::Ordering;
use std::error::Error; use error::Error;
use std::fmt::{self, Write}; use fmt::{self, Write};
use std::io; use io;
use libctru::libc::{self, c_char}; use libctru::libc::{self, c_char};
use std::mem; use mem;
use system::memchr; use memchr;
use std::ops; use ops;
use std::ptr; use ptr;
use std::slice; use slice;
use std::str::{self, Utf8Error}; use str::{self, Utf8Error};
/// A type representing an owned C-compatible string /// A type representing an owned C-compatible string
/// ///

0
src/system/ffi/mod.rs → std/src/ffi/mod.rs

20
src/system/ffi/os_str.rs → std/src/ffi/os_str.rs

@ -8,16 +8,16 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::borrow::{Borrow, Cow}; use borrow::{Borrow, Cow};
use std::fmt::{self, Debug}; use fmt::{self, Debug};
use std::mem; use mem;
use std::ops; use ops;
use std::cmp; use cmp;
use std::hash::{Hash, Hasher}; use hash::{Hash, Hasher};
use system::sys::wtf8::{Wtf8, Wtf8Buf}; use sys::wtf8::{Wtf8, Wtf8Buf};
use system::sys::{AsInner, IntoInner, FromInner}; use sys::{AsInner, IntoInner, FromInner};
pub use system::sys::wtf8::EncodeWide; pub use sys::wtf8::EncodeWide;
/// A type that can represent owned, mutable platform-native strings, but is /// A type that can represent owned, mutable platform-native strings, but is
/// cheaply inter-convertible with Rust strings. /// cheaply inter-convertible with Rust strings.

12
src/system/io/buffered.rs → std/src/io/buffered.rs

@ -10,13 +10,13 @@
//! Buffering wrappers for I/O traits //! Buffering wrappers for I/O traits
use std::io::prelude::*; use io::prelude::*;
use std::cmp; use cmp;
use std::error; use error;
use std::fmt; use fmt;
use std::io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom}; use io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom};
use std::memchr; use memchr;
/// The `BufReader` struct adds buffering to any reader. /// The `BufReader` struct adds buffering to any reader.
/// ///

6
src/system/io/cursor.rs → std/src/io/cursor.rs

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::io::prelude::*; use io::prelude::*;
use std::cmp; use cmp;
use std::io::{self, SeekFrom, Error, ErrorKind}; use io::{self, SeekFrom, Error, ErrorKind};
/// A `Cursor` wraps another type and provides it with a /// A `Cursor` wraps another type and provides it with a
/// [`Seek`](trait.Seek.html) implementation. /// [`Seek`](trait.Seek.html) implementation.

6
src/system/io/error.rs → std/src/io/error.rs

@ -9,9 +9,9 @@
// except according to those terms. // except according to those terms.
use std::error; use error;
use std::fmt; use fmt;
use std::result; use result;
/// A specialized [`Result`](../result/enum.Result.html) type for I/O /// A specialized [`Result`](../result/enum.Result.html) type for I/O
/// operations. /// operations.

8
src/system/io/impls.rs → std/src/io/impls.rs

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::cmp; use cmp;
use std::io::{self, SeekFrom, Read, Write, Seek, BufRead, Error, ErrorKind}; use io::{self, SeekFrom, Read, Write, Seek, BufRead, Error, ErrorKind};
use std::fmt; use fmt;
use std::mem; use mem;
// ============================================================================= // =============================================================================
// Forwarding implementations // Forwarding implementations

14
src/system/io/mod.rs → std/src/io/mod.rs

@ -247,19 +247,20 @@
//! contract. The implementation of many of these functions are subject to change over //! contract. The implementation of many of these functions are subject to change over
//! time and may call fewer or more syscalls/library functions. //! time and may call fewer or more syscalls/library functions.
use std::cmp; use cmp;
use rustc_unicode::str as core_str; use rustc_unicode::str as core_str;
use std::error as std_error; use error as std_error;
use std::fmt; use fmt;
use std::result; use result;
use std::str; use str;
use std::memchr; use memchr;
pub use self::buffered::{BufReader, BufWriter, LineWriter}; pub use self::buffered::{BufReader, BufWriter, LineWriter};
pub use self::buffered::IntoInnerError; pub use self::buffered::IntoInnerError;
pub use self::cursor::Cursor; pub use self::cursor::Cursor;
pub use self::error::{Result, Error, ErrorKind}; pub use self::error::{Result, Error, ErrorKind};
pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat}; pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
pub use self::print::{STDOUT, _print};
//pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr}; //pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
//pub use self::stdio::{StdoutLock, StderrLock, StdinLock}; //pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
@ -272,6 +273,7 @@ mod cursor;
mod error; mod error;
mod impls; mod impls;
mod util; mod util;
mod print;
//mod lazy; //mod lazy;
//mod stdio; //mod stdio;

0
src/system/io/prelude.rs → std/src/io/prelude.rs

32
std/src/io/print.rs

@ -0,0 +1,32 @@
use fmt;
use io::{self, Write};
// NOTE: We're just gonna use the spin mutex until we figure out how to properly
// implement mutexes with ctrulib functions
use spin::Mutex;
use libctru::libc;
pub static STDOUT: Mutex<StdoutRaw> = Mutex::new(StdoutRaw(()));
pub struct StdoutRaw(());
impl Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
unsafe {
// devkitPro's version of write(2) fails if zero bytes are written,
// so let's just exit if the buffer size is zero
if buf.is_empty() {
return Ok(buf.len())
}
libc::write(libc::STDOUT_FILENO, buf.as_ptr() as *const _, buf.len());
Ok(buf.len())
}
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
STDOUT.lock().write_fmt(args).unwrap();
}

2
src/system/io/util.rs → std/src/io/util.rs

@ -10,7 +10,7 @@
#![allow(missing_copy_implementations)] #![allow(missing_copy_implementations)]
use std::io::{self, Read, Write, ErrorKind, BufRead}; use io::{self, Read, Write, ErrorKind, BufRead};
/// Copies the entire contents of a reader into a writer. /// Copies the entire contents of a reader into a writer.
/// ///

100
std/src/lib.rs

@ -0,0 +1,100 @@
#![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 rustc_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 rustc_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;

394
std/src/macros.rs

@ -0,0 +1,394 @@
// 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]
#[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
})
});
}
/// Ensure that a boolean expression is `true` at runtime.
///
/// This will invoke the `panic!` macro if the provided expression cannot be
/// evaluated to `true` at runtime.
///
/// This macro has a second version, where a custom panic message can be provided.
///
/// # Examples
///
/// ```
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// assert!(true);
///
/// fn some_computation() -> bool { true } // a very simple function
///
/// assert!(some_computation());
///
/// // assert with a custom message
/// let x = true;
/// assert!(x, "x wasn't true!");
///
/// let a = 3; let b = 27;
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
macro_rules! assert {
($cond:expr) => (
if !$cond {
panic!(concat!("assertion failed: ", stringify!($cond)))
}
);
($cond:expr, $($arg:tt)+) => (
if !$cond {
panic!($($arg)+)
}
);
}
/// Asserts that two expressions are equal to each other.
///
/// On panic, this macro will print the values of the expressions with their
/// debug representations.
///
/// # Examples
///
/// ```
/// let a = 3;
/// let b = 1 + 2;
/// assert_eq!(a, b);
/// ```
#[macro_export]
macro_rules! assert_eq {
($left:expr , $right:expr) => ({
match (&$left, &$right) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
panic!("assertion failed: `(left == right)` \
(left: `{:?}`, right: `{:?}`)", left_val, right_val)
}
}
}
})
}
/// Ensure that a boolean expression is `true` at runtime.
///
/// This will invoke the `panic!` macro if the provided expression cannot be
/// evaluated to `true` at runtime.
///
/// Like `assert!`, this macro also has a second version, where a custom panic
/// message can be provided.
///
/// Unlike `assert!`, `debug_assert!` statements are only enabled in non
/// optimized builds by default. An optimized build will omit all
/// `debug_assert!` statements unless `-C debug-assertions` is passed to the
/// compiler. This makes `debug_assert!` useful for checks that are too
/// expensive to be present in a release build but may be helpful during
/// development.
///
/// # Examples
///
/// ```
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// debug_assert!(true);
///
/// fn some_expensive_computation() -> bool { true } // a very simple function
/// debug_assert!(some_expensive_computation());
///
/// // assert with a custom message
/// let x = true;
/// debug_assert!(x, "x wasn't true!");
///
/// let a = 3; let b = 27;
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
macro_rules! debug_assert {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
}
/// Asserts that two expressions are equal to each other.
///
/// On panic, this macro will print the values of the expressions with their
/// debug representations.
///
/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
/// optimized builds by default. An optimized build will omit all
/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
/// compiler. This makes `debug_assert_eq!` useful for checks that are too
/// expensive to be present in a release build but may be helpful during
/// development.
///
/// # Examples
///
/// ```
/// let a = 3;
/// let b = 1 + 2;
/// debug_assert_eq!(a, b);
/// ```
#[macro_export]
macro_rules! debug_assert_eq {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
}
/// 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))
}
})
}
/// Use the `format!` syntax to write data into a buffer.
///
/// This macro is typically used with a buffer of `&mut `[`Write`][write].
///
/// See [`std::fmt`][fmt] for more information on format syntax.
///
/// [fmt]: ../std/fmt/index.html
/// [write]: ../std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::Write;
///
/// let mut w = Vec::new();
/// write!(&mut w, "test").unwrap();
/// write!(&mut w, "formatted {}", "arguments").unwrap();
///
/// assert_eq!(w, b"testformatted arguments");
/// ```
#[macro_export]
macro_rules! write {
($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
}
/// Use the `format!` syntax to write data into a buffer, appending a newline.
///
/// This macro is typically used with a buffer of `&mut `[`Write`][write].
///
/// See [`std::fmt`][fmt] for more information on format syntax.
///
/// [fmt]: ../std/fmt/index.html
/// [write]: ../std/io/trait.Write.html
///
/// # Examples
///
/// ```
/// use std::io::Write;
///
/// let mut w = Vec::new();
/// writeln!(&mut w, "test").unwrap();
/// writeln!(&mut w, "formatted {}", "arguments").unwrap();
///
/// assert_eq!(&w[..], "test\nformatted arguments\n".as_bytes());
/// ```
#[macro_export]
macro_rules! writeln {
($dst:expr, $fmt:expr) => (
write!($dst, concat!($fmt, "\n"))
);
($dst:expr, $fmt:expr, $($arg:tt)*) => (
write!($dst, concat!($fmt, "\n"), $($arg)*)
);
}
/// A utility macro for indicating unreachable code.
///
/// This is useful any time that the compiler can't determine that some code is unreachable. For
/// example:
///
/// * Match arms with guard conditions.
/// * Loops that dynamically terminate.
/// * Iterators that dynamically terminate.
///
/// # Panics
///
/// This will always panic.
///
/// # Examples
///
/// Match arms:
///
/// ```
/// # #[allow(dead_code)]
/// fn foo(x: Option<i32>) {
/// match x {
/// Some(n) if n >= 0 => println!("Some(Non-negative)"),
/// Some(n) if n < 0 => println!("Some(Negative)"),
/// Some(_) => unreachable!(), // compile error if commented out
/// None => println!("None")
/// }
/// }
/// ```
///
/// Iterators:
///
/// ```
/// # #[allow(dead_code)]
/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
/// for i in 0.. {
/// if 3*i < i { panic!("u32 overflow"); }
/// if x < 3*i { return i-1; }
/// }
/// unreachable!();
/// }
/// ```
#[macro_export]
macro_rules! unreachable {
() => ({
panic!("internal error: entered unreachable code")
});
($msg:expr) => ({
unreachable!("{}", $msg)
});
($fmt:expr, $($arg:tt)*) => ({
panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
});
}
/// A standardized placeholder for marking unfinished code. It panics with the
/// message `"not yet implemented"` when executed.
///
/// This can be useful if you are prototyping and are just looking to have your
/// code typecheck, or if you're implementing a trait that requires multiple
/// methods, and you're only planning on using one of them.
///
/// # Examples
///
/// Here's an example of some in-progress code. We have a trait `Foo`:
///
/// ```
/// trait Foo {
/// fn bar(&self);
/// fn baz(&self);
/// }
/// ```
///
/// We want to implement `Foo` on one of our types, but we also want to work on
/// just `bar()` first. In order for our code to compile, we need to implement
/// `baz()`, so we can use `unimplemented!`:
///
/// ```
/// # trait Foo {
/// # fn bar(&self);
/// # fn baz(&self);
/// # }
/// struct MyStruct;
///
/// impl Foo for MyStruct {
/// fn bar(&self) {
/// // implementation goes here
/// }
///
/// fn baz(&self) {
/// // let's not worry about implementing baz() for now
/// unimplemented!();
/// }
/// }
///
/// fn main() {
/// let s = MyStruct;
/// s.bar();
///
/// // we aren't even using baz() yet, so this is fine.
/// }
/// ```
#[macro_export]
macro_rules! unimplemented {
() => (panic!("not yet implemented"))
}
#[macro_export]
#[allow_internal_unstable]
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)*));
}

0
src/system/memchr.rs → std/src/memchr.rs

1826
std/src/num/f32.rs

File diff suppressed because it is too large Load Diff

1712
std/src/num/f64.rs

File diff suppressed because it is too large Load Diff

293
std/src/num/mod.rs

@ -0,0 +1,293 @@
// Copyright 2012-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.
//! Additional functionality for numerics.
//!
//! This module provides some extra types that are useful when doing numerical
//! work. See the individual documentation for each piece for more information.
#![allow(missing_docs)]
#[allow(deprecated)]
pub use core::num::{Zero, One};
pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError};
pub use core::num::Wrapping;
#[cfg(test)]
use fmt;
#[cfg(test)]
use ops::{Add, Sub, Mul, Div, Rem};
/// Helper function for testing numeric operations
#[cfg(test)]
pub fn test_num<T>(ten: T, two: T) where
T: PartialEq
+ Add<Output=T> + Sub<Output=T>
+ Mul<Output=T> + Div<Output=T>
+ Rem<Output=T> + fmt::Debug
+ Copy
{
assert_eq!(ten.add(two), ten + two);
assert_eq!(ten.sub(two), ten - two);
assert_eq!(ten.mul(two), ten * two);
assert_eq!(ten.div(two), ten / two);
assert_eq!(ten.rem(two), ten % two);
}
#[cfg(test)]
mod tests {
use u8;
use u16;
use u32;
use u64;
use usize;
use ops::Mul;
#[test]
fn test_saturating_add_uint() {
use usize::MAX;
assert_eq!(3_usize.saturating_add(5_usize), 8_usize);
assert_eq!(3_usize.saturating_add(MAX - 1), MAX);
assert_eq!(MAX.saturating_add(MAX), MAX);
assert_eq!((MAX - 2).saturating_add(1), MAX - 1);
}
#[test]
fn test_saturating_sub_uint() {
use usize::MAX;
assert_eq!(5_usize.saturating_sub(3_usize), 2_usize);
assert_eq!(3_usize.saturating_sub(5_usize), 0_usize);
assert_eq!(0_usize.saturating_sub(1_usize), 0_usize);
assert_eq!((MAX - 1).saturating_sub(MAX), 0);
}
#[test]
fn test_saturating_add_int() {
use isize::{MIN, MAX};
assert_eq!(3i32.saturating_add(5), 8);
assert_eq!(3isize.saturating_add(MAX - 1), MAX);
assert_eq!(MAX.saturating_add(MAX), MAX);
assert_eq!((MAX - 2).saturating_add(1), MAX - 1);
assert_eq!(3i32.saturating_add(-5), -2);
assert_eq!(MIN.saturating_add(-1), MIN);
assert_eq!((-2isize).saturating_add(-MAX), MIN);
}
#[test]
fn test_saturating_sub_int() {
use isize::{MIN, MAX};
assert_eq!(3i32.saturating_sub(5), -2);
assert_eq!(MIN.saturating_sub(1), MIN);
assert_eq!((-2isize).saturating_sub(MAX), MIN);
assert_eq!(3i32.saturating_sub(-5), 8);
assert_eq!(3isize.saturating_sub(-(MAX - 1)), MAX);
assert_eq!(MAX.saturating_sub(-MAX), MAX);
assert_eq!((MAX - 2).saturating_sub(-1), MAX - 1);
}
#[test]
fn test_checked_add() {
let five_less = usize::MAX - 5;
assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5));
assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4));
assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3));
assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2));
assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1));
assert_eq!(five_less.checked_add(5), Some(usize::MAX));
assert_eq!(five_less.checked_add(6), None);
assert_eq!(five_less.checked_add(7), None);
}
#[test]
fn test_checked_sub() {
assert_eq!(5_usize.checked_sub(0), Some(5));
assert_eq!(5_usize.checked_sub(1), Some(4));
assert_eq!(5_usize.checked_sub(2), Some(3));
assert_eq!(5_usize.checked_sub(3), Some(2));
assert_eq!(5_usize.checked_sub(4), Some(1));
assert_eq!(5_usize.checked_sub(5), Some(0));
assert_eq!(5_usize.checked_sub(6), None);
assert_eq!(5_usize.checked_sub(7), None);
}
#[test]
fn test_checked_mul() {
let third = usize::MAX / 3;
assert_eq!(third.checked_mul(0), Some(0));
assert_eq!(third.checked_mul(1), Some(third));
assert_eq!(third.checked_mul(2), Some(third * 2));
assert_eq!(third.checked_mul(3), Some(third * 3));
assert_eq!(third.checked_mul(4), None);
}
macro_rules! test_is_power_of_two {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![test]
assert_eq!((0 as $T).is_power_of_two(), false);
assert_eq!((1 as $T).is_power_of_two(), true);
assert_eq!((2 as $T).is_power_of_two(), true);
assert_eq!((3 as $T).is_power_of_two(), false);
assert_eq!((4 as $T).is_power_of_two(), true);
assert_eq!((5 as $T).is_power_of_two(), false);
assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true);
}
)
}
test_is_power_of_two!{ test_is_power_of_two_u8, u8 }
test_is_power_of_two!{ test_is_power_of_two_u16, u16 }
test_is_power_of_two!{ test_is_power_of_two_u32, u32 }
test_is_power_of_two!{ test_is_power_of_two_u64, u64 }
test_is_power_of_two!{ test_is_power_of_two_uint, usize }
macro_rules! test_next_power_of_two {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![test]
assert_eq!((0 as $T).next_power_of_two(), 1);
let mut next_power = 1;
for i in 1 as $T..40 {
assert_eq!(i.next_power_of_two(), next_power);
if i == next_power { next_power *= 2 }
}
}
)
}
test_next_power_of_two! { test_next_power_of_two_u8, u8 }
test_next_power_of_two! { test_next_power_of_two_u16, u16 }
test_next_power_of_two! { test_next_power_of_two_u32, u32 }
test_next_power_of_two! { test_next_power_of_two_u64, u64 }
test_next_power_of_two! { test_next_power_of_two_uint, usize }
macro_rules! test_checked_next_power_of_two {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![test]
assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
assert!(($T::MAX / 2).checked_next_power_of_two().is_some());
assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
assert_eq!($T::MAX.checked_next_power_of_two(), None);
let mut next_power = 1;
for i in 1 as $T..40 {
assert_eq!(i.checked_next_power_of_two(), Some(next_power));
if i == next_power { next_power *= 2 }
}
}
)
}
test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
#[test]
fn test_pow() {
fn naive_pow<T: Mul<Output = T> + Copy>(one: T, base: T, exp: usize) -> T {
(0..exp).fold(one, |acc, _| acc * base)
}
macro_rules! assert_pow {
(($num:expr, $exp:expr) => $expected:expr) => {{
let result = $num.pow($exp);
assert_eq!(result, $expected);
assert_eq!(result, naive_pow(1, $num, $exp));
}}
}
assert_pow!((3u32, 0 ) => 1);
assert_pow!((5u32, 1 ) => 5);
assert_pow!((-4i32, 2 ) => 16);
assert_pow!((8u32, 3 ) => 512);
assert_pow!((2u64, 50) => 1125899906842624);
}
#[test]
fn test_uint_to_str_overflow() {
let mut u8_val: u8 = 255;
assert_eq!(u8_val.to_string(), "255");
u8_val = u8_val.wrapping_add(1);
assert_eq!(u8_val.to_string(), "0");
let mut u16_val: u16 = 65_535;
assert_eq!(u16_val.to_string(), "65535");
u16_val = u16_val.wrapping_add(1);
assert_eq!(u16_val.to_string(), "0");
let mut u32_val: u32 = 4_294_967_295;
assert_eq!(u32_val.to_string(), "4294967295");
u32_val = u32_val.wrapping_add(1);
assert_eq!(u32_val.to_string(), "0");
let mut u64_val: u64 = 18_446_744_073_709_551_615;
assert_eq!(u64_val.to_string(), "18446744073709551615");
u64_val = u64_val.wrapping_add(1);
assert_eq!(u64_val.to_string(), "0");
}
fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
::str::FromStr::from_str(t).ok()
}
#[test]
fn test_uint_from_str_overflow() {
let mut u8_val: u8 = 255;
assert_eq!(from_str::<u8>("255"), Some(u8_val));
assert_eq!(from_str::<u8>("256"), None);
u8_val = u8_val.wrapping_add(1);
assert_eq!(from_str::<u8>("0"), Some(u8_val));
assert_eq!(from_str::<u8>("-1"), None);
let mut u16_val: u16 = 65_535;
assert_eq!(from_str::<u16>("65535"), Some(u16_val));
assert_eq!(from_str::<u16>("65536"), None);
u16_val = u16_val.wrapping_add(1);
assert_eq!(from_str::<u16>("0"), Some(u16_val));
assert_eq!(from_str::<u16>("-1"), None);
let mut u32_val: u32 = 4_294_967_295;
assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
assert_eq!(from_str::<u32>("4294967296"), None);
u32_val = u32_val.wrapping_add(1);
assert_eq!(from_str::<u32>("0"), Some(u32_val));
assert_eq!(from_str::<u32>("-1"), None);
let mut u64_val: u64 = 18_446_744_073_709_551_615;
assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
assert_eq!(from_str::<u64>("18446744073709551616"), None);
u64_val = u64_val.wrapping_add(1);
assert_eq!(from_str::<u64>("0"), Some(u64_val));
assert_eq!(from_str::<u64>("-1"), None);
}
}
#[cfg(test)]
mod bench {
extern crate test;
use self::test::Bencher;
#[bench]
fn bench_pow_function(b: &mut Bencher) {
let v = (0..1024).collect::<Vec<u32>>();
b.iter(|| {
v.iter().fold(0u32, |old, new| old.pow(*new as u32));
});
}
}

25
src/system/panicking.rs → std/src/panicking.rs

@ -11,11 +11,8 @@
//! Implementation of various bits and pieces of the `panic!` macro and //! Implementation of various bits and pieces of the `panic!` macro and
//! associated runtime pieces. //! associated runtime pieces.
use core::fmt::{self, Display, Write}; use fmt::{self, Display};
use core::any::Any; use any::Any;
use collections::String;
use collections::boxed::Box;
///The compiler wants this to be here. Otherwise it won't be happy. And we like happy compilers. ///The compiler wants this to be here. Otherwise it won't be happy. And we like happy compilers.
#[lang = "eh_personality"] #[lang = "eh_personality"]
@ -36,6 +33,8 @@ extern fn panic_fmt(msg: fmt::Arguments, file: &'static str, line: u32) -> ! {
#[inline(never)] #[inline(never)]
#[cold] #[cold]
pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line: &(&'static str, u32)) -> ! { pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
use fmt::Write;
let mut s = String::new(); let mut s = String::new();
let _ = s.write_fmt(*msg); let _ = s.write_fmt(*msg);
begin_panic(s, file_line); begin_panic(s, file_line);
@ -45,21 +44,13 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line: &(&'static str, u32)) ->
#[inline(never)] #[inline(never)]
#[cold] #[cold]
pub fn begin_panic<M: Any + Send + Display>(msg: M, file_line: &(&'static str, u32)) -> ! { pub fn begin_panic<M: Any + Send + Display>(msg: M, file_line: &(&'static str, u32)) -> ! {
use gfx::Screen;
use console::Console;
let msg = Box::new(msg); let msg = Box::new(msg);
let (file, line) = *file_line; let (file, line) = *file_line;
let mut error_top = Console::init(Screen::Top); println!("--------------------------------------------------");
let mut error_bottom = Console::init(Screen::Bottom); println!("PANIC in {} at line {}:", file, line);
println!(" {}", msg);
write!(error_top, "--------------------------------------------------").unwrap(); println!("\x1b[29;00H--------------------------------------------------");
writeln!(error_top, "PANIC in {} at line {}:", file, line).unwrap();
writeln!(error_top, " {}", msg).unwrap();
write!(error_top, "\x1b[29;00H--------------------------------------------------").unwrap();
write!(error_bottom, "").unwrap();
loop {} loop {}
} }

20
src/system/path.rs → std/src/path.rs

@ -97,19 +97,19 @@
//! normalization is possible to build on top of the components APIs, //! normalization is possible to build on top of the components APIs,
//! and will be included in this library in the near future. //! and will be included in this library in the near future.
use std::ascii::*; use ascii::*;
use std::borrow::{Borrow, ToOwned, Cow}; use borrow::{Borrow, ToOwned, Cow};
use std::cmp; use cmp;
//use error::Error; //use error::Error;
use std::fmt; use fmt;
//use fs; //use fs;
use std::hash::{Hash, Hasher}; use hash::{Hash, Hasher};
//use io; //use io;
use std::mem; use mem;
use std::ops::{self, Deref}; use ops::{self, Deref};
use std::iter; use iter;
use std::ffi::{OsStr, OsString}; use ffi::{OsStr, OsString};
use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix}; use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
@ -132,7 +132,7 @@ use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
mod platform { mod platform {
use super::Prefix; use super::Prefix;
use std::ffi::OsStr; use ffi::OsStr;
#[inline] #[inline]
pub fn is_sep_byte(b: u8) -> bool { pub fn is_sep_byte(b: u8) -> bool {

1
std/src/prelude/mod.rs

@ -0,0 +1 @@
pub mod v1;

49
std/src/prelude/v1.rs

@ -0,0 +1,49 @@
// 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;

30
std/src/rt.rs

@ -0,0 +1,30 @@
// 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.
//! Runtime services
//!
//! The `rt` module provides a narrow set of runtime services,
//! including the global heap (exported in `heap`) and unwinding and
//! backtrace support. The APIs in this module are highly unstable,
//! and should be considered as private implementation details for the
//! time being.
use mem;
// Reexport some of our utilities which are expected by other crates.
pub use panicking::{begin_panic, begin_panic_fmt};
//TODO: Handle argc/argv arguments
#[lang = "start"]
#[allow(unused_variables)]
fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
unsafe { mem::transmute::<_, fn()>(main)(); }
0
}

5
std/src/sync/mod.rs

@ -0,0 +1,5 @@
mod mutex;
pub use self::mutex::{Mutex, MutexGuard};
pub type LockResult<T> = Result<T, ()>;

92
std/src/sync/mutex.rs

@ -0,0 +1,92 @@
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> {}

0
src/system/sys/mod.rs → std/src/sys/mod.rs

18
src/system/sys/wtf8.rs → std/src/sys/wtf8.rs

@ -27,16 +27,16 @@
use core::str::next_code_point; use core::str::next_code_point;
use std::ascii::*; use ascii::*;
use std::borrow::Cow; use borrow::Cow;
use rustc_unicode::char; use rustc_unicode::char;
use std::fmt; use fmt;
use std::hash::{Hash, Hasher}; use hash::{Hash, Hasher};
use std::iter::FromIterator; use iter::FromIterator;
use std::mem; use mem;
use std::ops; use ops;
use std::slice; use slice;
use std::str; use str;
use super::AsInner; use super::AsInner;
const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD"; const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
Loading…
Cancel
Save