save_metrics: config.save_metrics.clone(),
test_shard: config.test_shard.clone(),
nocapture: false,
+ color: test::AutoColor,
}
}
use std::os;
use std::str;
use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
let prog = if cfg!(windows) {prog.slice_to(prog.len() - 4)} else {prog};
use core::prelude::*;
use core::cmp;
+use core::default::Default;
use core::fmt;
use core::iter::{Enumerate, Repeat, Map, Zip};
use core::ops;
bitv: BigBitv
}
+impl Default for BitvSet {
+ #[inline]
+ fn default() -> BitvSet { BitvSet::new() }
+}
+
impl BitvSet {
/// Creates a new bit vector set with initially no contents
pub fn new() -> BitvSet {
use core::prelude::*;
use alloc::owned::Box;
+use core::default::Default;
use core::fmt;
use core::iter;
use core::mem;
}
}
+impl<T> Default for DList<T> {
+ #[inline]
+ fn default() -> DList<T> { DList::new() }
+}
+
impl<T> DList<T> {
/// Create an empty DList
#[inline]
use core::prelude::*;
+use core::default::Default;
use core::mem::{zeroed, replace, swap};
use core::ptr;
fn clear(&mut self) { self.data.truncate(0) }
}
+impl<T: Ord> Default for PriorityQueue<T> {
+ #[inline]
+ fn default() -> PriorityQueue<T> { PriorityQueue::new() }
+}
+
impl<T: Ord> PriorityQueue<T> {
/// An iterator visiting all values in underlying vector, in
/// arbitrary order.
use core::prelude::*;
use core::cmp;
+use core::default::Default;
use core::fmt;
use core::iter::RandomAccessIterator;
}
}
+impl<T> Default for RingBuf<T> {
+ #[inline]
+ fn default() -> RingBuf<T> { RingBuf::new() }
+}
+
impl<T> RingBuf<T> {
/// Create an empty RingBuf
pub fn new() -> RingBuf<T> {
use core::prelude::*;
+use core::default::Default;
use core::fmt;
use core::iter::{Enumerate, FilterMap};
use core::mem::replace;
}
}
+impl<V> Default for SmallIntMap<V> {
+ #[inline]
+ fn default() -> SmallIntMap<V> { SmallIntMap::new() }
+}
+
impl<V> SmallIntMap<V> {
/// Create an empty SmallIntMap
pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
use core::prelude::*;
use alloc::owned::Box;
+use core::default::Default;
use core::fmt;
use core::fmt::Show;
use core::iter::Peekable;
}
}
+impl<K: Ord, V> Default for TreeMap<K,V> {
+ #[inline]
+ fn default() -> TreeMap<K, V> { TreeMap::new() }
+}
+
impl<K: Ord, V> TreeMap<K, V> {
/// Create an empty TreeMap
pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
}
+impl<T: Ord> Default for TreeSet<T> {
+ #[inline]
+ fn default() -> TreeSet<T> { TreeSet::new() }
+}
+
impl<T: Ord> TreeSet<T> {
/// Create an empty TreeSet
#[inline]
use core::prelude::*;
use alloc::owned::Box;
+use core::default::Default;
use core::mem::zeroed;
use core::mem;
use core::uint;
}
}
+impl<T> Default for TrieMap<T> {
+ #[inline]
+ fn default() -> TrieMap<T> { TrieMap::new() }
+}
+
impl<T> TrieMap<T> {
/// Create an empty TrieMap
#[inline]
}
}
+impl Default for TrieSet {
+ #[inline]
+ fn default() -> TrieSet { TrieSet::new() }
+}
+
impl TrieSet {
/// Create an empty TrieSet
#[inline]
pub mod compat {
use std::intrinsics::{atomic_store_relaxed, transmute};
use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
- use std::os::win32::as_utf16_p;
extern "system" {
fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
// This way, calling a function in this compatibility layer (after it's loaded) shouldn't
// be any slower than a regular DLL call.
unsafe fn store_func<T: Copy>(ptr: *mut T, module: &str, symbol: &str, fallback: T) {
- as_utf16_p(module, |module| {
- symbol.with_c_str(|symbol| {
- let handle = GetModuleHandleW(module);
- let func: Option<T> = transmute(GetProcAddress(handle, symbol));
- atomic_store_relaxed(ptr, func.unwrap_or(fallback))
- })
+ let module = module.to_utf16().append_one(0);
+ symbol.with_c_str(|symbol| {
+ let handle = GetModuleHandleW(module.as_ptr());
+ let func: Option<T> = transmute(GetProcAddress(handle, symbol));
+ atomic_store_relaxed(ptr, func.unwrap_or(fallback))
})
}
use libc;
use std::c_str::CString;
use std::mem;
-use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
+use std::os::win32::fill_utf16_buf_and_decode;
use std::ptr;
use std::rt::rtio;
-use std::rt::rtio::IoResult;
+use std::rt::rtio::{IoResult, IoError};
use std::str;
use std::vec;
}
}
+pub fn to_utf16(s: &CString) -> IoResult<Vec<u16>> {
+ match s.as_str() {
+ Some(s) => Ok(s.to_utf16().append_one(0)),
+ None => Err(IoError {
+ code: libc::ERROR_INVALID_NAME as uint,
+ extra: 0,
+ detail: Some("valid unicode input required".to_str()),
+ })
+ }
+}
+
pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
-> IoResult<FileDesc> {
// Flags passed to open_osfhandle
// Compat with unix, this allows opening directories (see libuv)
dwFlagsAndAttributes |= libc::FILE_FLAG_BACKUP_SEMANTICS;
- let handle = as_utf16_p(path.as_str().unwrap(), |buf| unsafe {
- libc::CreateFileW(buf,
+ let path = try!(to_utf16(path));
+ let handle = unsafe {
+ libc::CreateFileW(path.as_ptr(),
dwDesiredAccess,
dwShareMode,
ptr::mut_null(),
dwCreationDisposition,
dwFlagsAndAttributes,
ptr::mut_null())
- });
+ };
if handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
Err(super::last_error())
} else {
}
pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> {
+ let p = try!(to_utf16(p));
super::mkerr_winbool(unsafe {
// FIXME: turn mode into something useful? #2623
- as_utf16_p(p.as_str().unwrap(), |buf| {
- libc::CreateDirectoryW(buf, ptr::mut_null())
- })
+ libc::CreateDirectoryW(p.as_ptr(), ptr::mut_null())
})
}
let star = Path::new(unsafe {
CString::new(p.with_ref(|p| p), false)
}).join("*");
- as_utf16_p(star.as_str().unwrap(), |path_ptr| unsafe {
+ let path = try!(to_utf16(&star.to_c_str()));
+
+ unsafe {
let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint);
- let find_handle = libc::FindFirstFileW(path_ptr, wfd_ptr as libc::HANDLE);
+ let find_handle = libc::FindFirstFileW(path.as_ptr(), wfd_ptr as libc::HANDLE);
if find_handle as libc::c_int != libc::INVALID_HANDLE_VALUE {
let mut paths = vec!();
let mut more_files = 1 as libc::c_int;
} else {
Err(super::last_error())
}
- })
+ }
}
pub fn unlink(p: &CString) -> IoResult<()> {
+ let p = try!(to_utf16(p));
super::mkerr_winbool(unsafe {
- as_utf16_p(p.as_str().unwrap(), |buf| {
- libc::DeleteFileW(buf)
- })
+ libc::DeleteFileW(p.as_ptr())
})
}
pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
+ let old = try!(to_utf16(old));
+ let new = try!(to_utf16(new));
super::mkerr_winbool(unsafe {
- as_utf16_p(old.as_str().unwrap(), |old| {
- as_utf16_p(new.as_str().unwrap(), |new| {
- libc::MoveFileExW(old, new, libc::MOVEFILE_REPLACE_EXISTING)
- })
- })
+ libc::MoveFileExW(old.as_ptr(), new.as_ptr(),
+ libc::MOVEFILE_REPLACE_EXISTING)
})
}
pub fn chmod(p: &CString, mode: uint) -> IoResult<()> {
- super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
- libc::wchmod(p, mode as libc::c_int)
- }))
+ let p = try!(to_utf16(p));
+ super::mkerr_libc(unsafe {
+ libc::wchmod(p.as_ptr(), mode as libc::c_int)
+ })
}
pub fn rmdir(p: &CString) -> IoResult<()> {
- super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
- libc::wrmdir(p)
- }))
+ let p = try!(to_utf16(p));
+ super::mkerr_libc(unsafe { libc::wrmdir(p.as_ptr()) })
}
pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
pub fn readlink(p: &CString) -> IoResult<CString> {
// FIXME: I have a feeling that this reads intermediate symlinks as well.
use io::c::compat::kernel32::GetFinalPathNameByHandleW;
+ let p = try!(to_utf16(p));
let handle = unsafe {
- as_utf16_p(p.as_str().unwrap(), |p| {
- libc::CreateFileW(p,
- libc::GENERIC_READ,
- libc::FILE_SHARE_READ,
- ptr::mut_null(),
- libc::OPEN_EXISTING,
- libc::FILE_ATTRIBUTE_NORMAL,
- ptr::mut_null())
- })
+ libc::CreateFileW(p.as_ptr(),
+ libc::GENERIC_READ,
+ libc::FILE_SHARE_READ,
+ ptr::mut_null(),
+ libc::OPEN_EXISTING,
+ libc::FILE_ATTRIBUTE_NORMAL,
+ ptr::mut_null())
};
if handle as int == libc::INVALID_HANDLE_VALUE as int {
return Err(super::last_error())
pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
use io::c::compat::kernel32::CreateSymbolicLinkW;
- super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
- as_utf16_p(dst.as_str().unwrap(), |dst| {
- unsafe { CreateSymbolicLinkW(dst, src, 0) }
- }) as libc::BOOL
- }))
+ let src = try!(to_utf16(src));
+ let dst = try!(to_utf16(dst));
+ super::mkerr_winbool(unsafe {
+ CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), 0) as libc::BOOL
+ })
}
pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
- super::mkerr_winbool(as_utf16_p(src.as_str().unwrap(), |src| {
- as_utf16_p(dst.as_str().unwrap(), |dst| {
- unsafe { libc::CreateHardLinkW(dst, src, ptr::mut_null()) }
- })
- }))
+ let src = try!(to_utf16(src));
+ let dst = try!(to_utf16(dst));
+ super::mkerr_winbool(unsafe {
+ libc::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::mut_null())
+ })
}
fn mkstat(stat: &libc::stat) -> rtio::FileStat {
pub fn stat(p: &CString) -> IoResult<rtio::FileStat> {
let mut stat: libc::stat = unsafe { mem::zeroed() };
- as_utf16_p(p.as_str().unwrap(), |up| {
- match unsafe { libc::wstat(up, &mut stat) } {
- 0 => Ok(mkstat(&stat)),
- _ => Err(super::last_error()),
- }
- })
+ let p = try!(to_utf16(p));
+ match unsafe { libc::wstat(p.as_ptr(), &mut stat) } {
+ 0 => Ok(mkstat(&stat)),
+ _ => Err(super::last_error()),
+ }
}
pub fn lstat(_p: &CString) -> IoResult<rtio::FileStat> {
actime: (atime / 1000) as libc::time64_t,
modtime: (mtime / 1000) as libc::time64_t,
};
- super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
- libc::wutime(p, &buf)
- }))
+ let p = try!(to_utf16(p));
+ super::mkerr_libc(unsafe {
+ libc::wutime(p.as_ptr(), &buf)
+ })
}
IoError {
code: ERROR as uint,
extra: 0,
- detail: None,
+ detail: Some("not yet supported by the `native` runtime, maybe try `green`.".to_string()),
}
}
use libc;
use std::c_str::CString;
use std::mem;
-use std::os::win32::as_utf16_p;
use std::os;
use std::ptr;
use std::rt::rtio;
use super::c;
use super::util;
+use super::file::to_utf16;
struct Event(libc::HANDLE);
}
pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
- as_utf16_p(addr.as_str().unwrap(), |p| {
- let start = ::io::timer::now();
- loop {
- match UnixStream::try_connect(p) {
- Some(handle) => {
- let inner = Inner::new(handle);
- let mut mode = libc::PIPE_TYPE_BYTE |
- libc::PIPE_READMODE_BYTE |
- libc::PIPE_WAIT;
- let ret = unsafe {
- libc::SetNamedPipeHandleState(inner.handle,
- &mut mode,
- ptr::mut_null(),
- ptr::mut_null())
- };
- return if ret == 0 {
- Err(super::last_error())
- } else {
- Ok(UnixStream {
- inner: Arc::new(inner),
- read: None,
- write: None,
- read_deadline: 0,
- write_deadline: 0,
- })
- }
+ let addr = try!(to_utf16(addr));
+ let start = ::io::timer::now();
+ loop {
+ match UnixStream::try_connect(addr.as_ptr()) {
+ Some(handle) => {
+ let inner = Inner::new(handle);
+ let mut mode = libc::PIPE_TYPE_BYTE |
+ libc::PIPE_READMODE_BYTE |
+ libc::PIPE_WAIT;
+ let ret = unsafe {
+ libc::SetNamedPipeHandleState(inner.handle,
+ &mut mode,
+ ptr::mut_null(),
+ ptr::mut_null())
+ };
+ return if ret == 0 {
+ Err(super::last_error())
+ } else {
+ Ok(UnixStream {
+ inner: Arc::new(inner),
+ read: None,
+ write: None,
+ read_deadline: 0,
+ write_deadline: 0,
+ })
}
- None => {}
}
+ None => {}
+ }
- // On windows, if you fail to connect, you may need to call the
- // `WaitNamedPipe` function, and this is indicated with an error
- // code of ERROR_PIPE_BUSY.
- let code = unsafe { libc::GetLastError() };
- if code as int != libc::ERROR_PIPE_BUSY as int {
- return Err(super::last_error())
- }
+ // On windows, if you fail to connect, you may need to call the
+ // `WaitNamedPipe` function, and this is indicated with an error
+ // code of ERROR_PIPE_BUSY.
+ let code = unsafe { libc::GetLastError() };
+ if code as int != libc::ERROR_PIPE_BUSY as int {
+ return Err(super::last_error())
+ }
- match timeout {
- Some(timeout) => {
- let now = ::io::timer::now();
- let timed_out = (now - start) >= timeout || unsafe {
- let ms = (timeout - (now - start)) as libc::DWORD;
- libc::WaitNamedPipeW(p, ms) == 0
- };
- if timed_out {
- return Err(util::timeout("connect timed out"))
- }
+ match timeout {
+ Some(timeout) => {
+ let now = ::io::timer::now();
+ let timed_out = (now - start) >= timeout || unsafe {
+ let ms = (timeout - (now - start)) as libc::DWORD;
+ libc::WaitNamedPipeW(addr.as_ptr(), ms) == 0
+ };
+ if timed_out {
+ return Err(util::timeout("connect timed out"))
}
+ }
- // An example I found on microsoft's website used 20
- // seconds, libuv uses 30 seconds, hence we make the
- // obvious choice of waiting for 25 seconds.
- None => {
- if unsafe { libc::WaitNamedPipeW(p, 25000) } == 0 {
- return Err(super::last_error())
- }
+ // An example I found on microsoft's website used 20
+ // seconds, libuv uses 30 seconds, hence we make the
+ // obvious choice of waiting for 25 seconds.
+ None => {
+ if unsafe { libc::WaitNamedPipeW(addr.as_ptr(), 25000) } == 0 {
+ return Err(super::last_error())
}
}
}
- })
+ }
}
fn handle(&self) -> libc::HANDLE { self.inner.handle }
// Although we technically don't need the pipe until much later, we
// create the initial handle up front to test the validity of the name
// and such.
- as_utf16_p(addr.as_str().unwrap(), |p| {
- let ret = unsafe { pipe(p, true) };
- if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
- Err(super::last_error())
- } else {
- Ok(UnixListener { handle: ret, name: addr.clone() })
- }
- })
+ let addr_v = try!(to_utf16(addr));
+ let ret = unsafe { pipe(addr_v.as_ptr(), true) };
+ if ret == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
+ Err(super::last_error())
+ } else {
+ Ok(UnixListener { handle: ret, name: addr.clone() })
+ }
}
pub fn native_listen(self) -> IoResult<UnixAcceptor> {
// using the original server pipe.
let handle = self.listener.handle;
+ let name = try!(to_utf16(&self.listener.name));
+
// Once we've got a "server handle", we need to wait for a client to
// connect. The ConnectNamedPipe function will block this thread until
// someone on the other end connects. This function can "fail" if a
// Now that we've got a connected client to our handle, we need to
// create a second server pipe. If this fails, we disconnect the
// connected client and return an error (see comments above).
- let new_handle = as_utf16_p(self.listener.name.as_str().unwrap(), |p| {
- unsafe { pipe(p, false) }
- });
+ let new_handle = unsafe { pipe(name.as_ptr(), false) };
if new_handle == libc::INVALID_HANDLE_VALUE as libc::HANDLE {
let ret = Err(super::last_error());
// If our disconnection fails, then there's not really a whole lot
lpSecurityDescriptor: ptr::mut_null(),
bInheritHandle: 1,
};
- *slot = os::win32::as_utf16_p("NUL", |filename| {
- libc::CreateFileW(filename,
- access,
- libc::FILE_SHARE_READ |
- libc::FILE_SHARE_WRITE,
- &mut sa,
- libc::OPEN_EXISTING,
- 0,
- ptr::mut_null())
- });
+ let filename = "NUL".to_utf16().append_one(0);
+ *slot = libc::CreateFileW(filename.as_ptr(),
+ access,
+ libc::FILE_SHARE_READ |
+ libc::FILE_SHARE_WRITE,
+ &mut sa,
+ libc::OPEN_EXISTING,
+ 0,
+ ptr::mut_null());
if *slot == INVALID_HANDLE_VALUE as libc::HANDLE {
return Err(super::last_error())
}
with_envp(cfg.env, |envp| {
with_dirp(cfg.cwd, |dirp| {
- os::win32::as_mut_utf16_p(cmd_str.as_slice(), |cmdp| {
- let created = CreateProcessW(ptr::null(),
- cmdp,
- ptr::mut_null(),
- ptr::mut_null(),
- TRUE,
- flags, envp, dirp,
- &mut si, &mut pi);
- if created == FALSE {
- create_err = Some(super::last_error());
- }
- })
+ let mut cmd_str = cmd_str.to_utf16().append_one(0);
+ let created = CreateProcessW(ptr::null(),
+ cmd_str.as_mut_ptr(),
+ ptr::mut_null(),
+ ptr::mut_null(),
+ TRUE,
+ flags, envp, dirp,
+ &mut si, &mut pi);
+ if created == FALSE {
+ create_err = Some(super::last_error());
+ }
})
});
Some(dir) => {
let dir_str = dir.as_str()
.expect("expected workingdirectory to be utf-8 encoded");
- os::win32::as_utf16_p(dir_str, cb)
+ let dir_str = dir_str.to_utf16().append_one(0);
+ cb(dir_str.as_ptr())
},
None => cb(ptr::null())
}
let cdata = cstore.get_crate_data(cnum);
decoder::get_reachable_extern_fns(&*cdata)
}
+
+pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
+ let cdata = cstore.get_crate_data(did.krate);
+ decoder::is_typedef(&*cdata, did.node)
+}
});
return ret;
}
+
+pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
+ let item_doc = lookup_item(id, cdata.data());
+ match item_family(item_doc) {
+ Type => true,
+ _ => false,
+ }
+}
use std::cell::RefCell;
use std::os;
use std::io::fs;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
use std::collections::HashSet;
use myfs = util::fs;
use std::mem;
use std::os;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
use syntax::ast;
use syntax::attr;
use syntax::visit;
fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
let t = ty::lookup_item_type(tcx, did);
match ty::get(t.ty).sty {
- ty::ty_enum(edid, _) => {
+ ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
return clean::EnumItem(clean::Enum {
generics: t.generics.clean(),
variants_stripped: false,
mod imp {
use libc;
use std::mem;
- use std::os::win32::as_utf16_p;
use std::os;
use std::ptr;
impl Lock {
pub fn new(p: &Path) -> Lock {
- let handle = as_utf16_p(p.as_str().unwrap(), |p| unsafe {
- libc::CreateFileW(p,
+ let p_16 = p.as_str().unwrap().to_utf16().append_one(0);
+ let handle = unsafe {
+ libc::CreateFileW(p_16.as_ptr(),
libc::FILE_GENERIC_READ |
libc::FILE_GENERIC_WRITE,
libc::FILE_SHARE_READ |
libc::CREATE_ALWAYS,
libc::FILE_ATTRIBUTE_NORMAL,
ptr::mut_null())
- });
+ };
if handle as uint == libc::INVALID_HANDLE_VALUE as uint {
fail!("create file error: {}", os::last_os_error());
}
use clean;
-use dl = std::unstable::dynamic_lib;
+use dl = std::dynamic_lib;
use serialize::json;
use std::string::String;
use std::os;
use std::str;
use std::string::String;
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
use std::collections::{HashSet, HashMap};
use testing;
--- /dev/null
+// Copyright 2013-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.
+
+/*!
+
+Dynamic library facilities.
+
+A simple wrapper over the platform's dynamic library facilities
+
+*/
+
+#![experimental]
+#![allow(missing_doc)]
+
+use clone::Clone;
+use c_str::ToCStr;
+use iter::Iterator;
+use mem;
+use ops::*;
+use option::*;
+use os;
+use path::{Path,GenericPath};
+use result::*;
+use slice::{Vector,ImmutableVector};
+use str;
+use string::String;
+use vec::Vec;
+
+pub struct DynamicLibrary { handle: *u8}
+
+impl Drop for DynamicLibrary {
+ fn drop(&mut self) {
+ match dl::check_for_errors_in(|| {
+ unsafe {
+ dl::close(self.handle)
+ }
+ }) {
+ Ok(()) => {},
+ Err(str) => fail!("{}", str)
+ }
+ }
+}
+
+impl DynamicLibrary {
+ // FIXME (#12938): Until DST lands, we cannot decompose &str into
+ // & and str, so we cannot usefully take ToCStr arguments by
+ // reference (without forcing an additional & around &str). So we
+ // are instead temporarily adding an instance for &Path, so that
+ // we can take ToCStr as owned. When DST lands, the &Path instance
+ // should be removed, and arguments bound by ToCStr should be
+ // passed by reference. (Here: in the `open` method.)
+
+ /// Lazily open a dynamic library. When passed None it gives a
+ /// handle to the calling process
+ pub fn open<T: ToCStr>(filename: Option<T>)
+ -> Result<DynamicLibrary, String> {
+ unsafe {
+ let mut filename = filename;
+ let maybe_library = dl::check_for_errors_in(|| {
+ match filename.take() {
+ Some(name) => dl::open_external(name),
+ None => dl::open_internal()
+ }
+ });
+
+ // The dynamic library must not be constructed if there is
+ // an error opening the library so the destructor does not
+ // run.
+ match maybe_library {
+ Err(err) => Err(err),
+ Ok(handle) => Ok(DynamicLibrary { handle: handle })
+ }
+ }
+ }
+
+ /// Prepends a path to this process's search path for dynamic libraries
+ pub fn prepend_search_path(path: &Path) {
+ let mut search_path = DynamicLibrary::search_path();
+ search_path.insert(0, path.clone());
+ let newval = DynamicLibrary::create_path(search_path.as_slice());
+ os::setenv(DynamicLibrary::envvar(),
+ str::from_utf8(newval.as_slice()).unwrap());
+ }
+
+ /// From a slice of paths, create a new vector which is suitable to be an
+ /// environment variable for this platforms dylib search path.
+ pub fn create_path(path: &[Path]) -> Vec<u8> {
+ let mut newvar = Vec::new();
+ for (i, path) in path.iter().enumerate() {
+ if i > 0 { newvar.push(DynamicLibrary::separator()); }
+ newvar.push_all(path.as_vec());
+ }
+ return newvar;
+ }
+
+ /// Returns the environment variable for this process's dynamic library
+ /// search path
+ pub fn envvar() -> &'static str {
+ if cfg!(windows) {
+ "PATH"
+ } else if cfg!(target_os = "macos") {
+ "DYLD_LIBRARY_PATH"
+ } else {
+ "LD_LIBRARY_PATH"
+ }
+ }
+
+ fn separator() -> u8 {
+ if cfg!(windows) {';' as u8} else {':' as u8}
+ }
+
+ /// Returns the current search path for dynamic libraries being used by this
+ /// process
+ pub fn search_path() -> Vec<Path> {
+ let mut ret = Vec::new();
+ match os::getenv_as_bytes(DynamicLibrary::envvar()) {
+ Some(env) => {
+ for portion in
+ env.as_slice()
+ .split(|a| *a == DynamicLibrary::separator()) {
+ ret.push(Path::new(portion));
+ }
+ }
+ None => {}
+ }
+ return ret;
+ }
+
+ /// Access the value at the symbol of the dynamic library
+ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, String> {
+ // This function should have a lifetime constraint of 'a on
+ // T but that feature is still unimplemented
+
+ let maybe_symbol_value = dl::check_for_errors_in(|| {
+ symbol.with_c_str(|raw_string| {
+ dl::symbol(self.handle, raw_string)
+ })
+ });
+
+ // The value must not be constructed if there is an error so
+ // the destructor does not run.
+ match maybe_symbol_value {
+ Err(err) => Err(err),
+ Ok(symbol_value) => Ok(mem::transmute(symbol_value))
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use prelude::*;
+ use libc;
+
+ #[test]
+ #[ignore(cfg(windows))] // FIXME #8818
+ #[ignore(cfg(target_os="android"))] // FIXME(#10379)
+ fn test_loading_cosine() {
+ // The math library does not need to be loaded since it is already
+ // statically linked in
+ let none: Option<Path> = None; // appease the typechecker
+ let libm = match DynamicLibrary::open(none) {
+ Err(error) => fail!("Could not load self as module: {}", error),
+ Ok(libm) => libm
+ };
+
+ let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
+ match libm.symbol("cos") {
+ Err(error) => fail!("Could not load function cos: {}", error),
+ Ok(cosine) => cosine
+ }
+ };
+
+ let argument = 0.0;
+ let expected_result = 1.0;
+ let result = cosine(argument);
+ if result != expected_result {
+ fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
+ expected_result, result)
+ }
+ }
+
+ #[test]
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "macos")]
+ #[cfg(target_os = "freebsd")]
+ fn test_errors_do_not_crash() {
+ // Open /dev/null as a library to get an error, and make sure
+ // that only causes an error, and not a crash.
+ let path = Path::new("/dev/null");
+ match DynamicLibrary::open(Some(&path)) {
+ Err(_) => {}
+ Ok(_) => fail!("Successfully opened the empty library.")
+ }
+ }
+}
+
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+pub mod dl {
+ use prelude::*;
+
+ use c_str::{CString, ToCStr};
+ use libc;
+ use ptr;
+ use result::*;
+ use str::StrAllocating;
+ use string::String;
+
+ pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
+ filename.with_c_str(|raw_name| {
+ dlopen(raw_name, Lazy as libc::c_int) as *u8
+ })
+ }
+
+ pub unsafe fn open_internal() -> *u8 {
+ dlopen(ptr::null(), Lazy as libc::c_int) as *u8
+ }
+
+ pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+ use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+ static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
+ unsafe {
+ // dlerror isn't thread safe, so we need to lock around this entire
+ // sequence
+ let _guard = lock.lock();
+ let _old_error = dlerror();
+
+ let result = f();
+
+ let last_error = dlerror();
+ let ret = if ptr::null() == last_error {
+ Ok(result)
+ } else {
+ Err(CString::new(last_error, false).as_str()
+ .unwrap()
+ .to_string())
+ };
+
+ ret
+ }
+ }
+
+ pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
+ dlsym(handle as *libc::c_void, symbol) as *u8
+ }
+ pub unsafe fn close(handle: *u8) {
+ dlclose(handle as *libc::c_void); ()
+ }
+
+ pub enum RTLD {
+ Lazy = 1,
+ Now = 2,
+ Global = 256,
+ Local = 0,
+ }
+
+ #[link_name = "dl"]
+ extern {
+ fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
+ fn dlerror() -> *libc::c_char;
+ fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
+ fn dlclose(handle: *libc::c_void) -> libc::c_int;
+ }
+}
+
+#[cfg(target_os = "win32")]
+pub mod dl {
+ use c_str::ToCStr;
+ use libc;
+ use os;
+ use ptr;
+ use result::{Ok, Err, Result};
+ use str::StrAllocating;
+ use str;
+ use string::String;
+
+ pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
+ // Windows expects Unicode data
+ let filename_cstr = filename.to_c_str();
+ let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
+ let filename_str = filename_str.to_utf16().append_one(0);
+ LoadLibraryW(filename_str.as_ptr() as *libc::c_void) as *u8
+ }
+
+ pub unsafe fn open_internal() -> *u8 {
+ let handle = ptr::null();
+ GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
+ handle as *u8
+ }
+
+ pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
+ unsafe {
+ SetLastError(0);
+
+ let result = f();
+
+ let error = os::errno();
+ if 0 == error {
+ Ok(result)
+ } else {
+ Err(format!("Error code {}", error))
+ }
+ }
+ }
+
+ pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
+ GetProcAddress(handle as *libc::c_void, symbol) as *u8
+ }
+ pub unsafe fn close(handle: *u8) {
+ FreeLibrary(handle as *libc::c_void); ()
+ }
+
+ #[allow(non_snake_case_functions)]
+ extern "system" {
+ fn SetLastError(error: libc::size_t);
+ fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void;
+ fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
+ handle: **libc::c_void) -> *libc::c_void;
+ fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
+ fn FreeLibrary(handle: *libc::c_void);
+ }
+}
* Make a simple TCP client connection and request
- ```rust,should_fail
+ ```rust
# #![allow(unused_must_use)]
use std::io::net::tcp::TcpStream;
+ # // connection doesn't fail if a server is running on 8080
+ # // locally, we still want to be type checking this code, so lets
+ # // just stop it running (#11576)
+ # if false {
let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap();
socket.write(bytes!("GET / HTTP/1.0\n\n"));
let response = socket.read_to_end();
+ # }
```
* Make a simple TCP server
/* Runtime and platform support */
pub mod c_vec;
+pub mod dynamic_lib;
pub mod os;
pub mod io;
pub mod path;
pub mod fmt;
-// Private APIs
-#[unstable]
-pub mod unstable;
-
// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
// but name resolution doesn't work without it being pub.
#[unstable]
// The test runner requires std::slice::Vector, so re-export std::slice just for it.
#[cfg(test)] pub use slice;
}
+
+#[deprecated]
+#[allow(missing_doc)]
+#[doc(hiden)]
+pub mod unstable {
+ #[deprecated = "use std::dynamic_lib"]
+ pub use dynamic_lib;
+}
use os::TMPBUF_SZ;
use slice::{MutableVector, ImmutableVector};
use string::String;
- use str::{StrSlice, StrAllocating};
+ use str::StrSlice;
use str;
use vec::Vec;
return res;
}
}
-
- pub fn as_utf16_p<T>(s: &str, f: |*u16| -> T) -> T {
- as_mut_utf16_p(s, |t| { f(t as *u16) })
- }
-
- pub fn as_mut_utf16_p<T>(s: &str, f: |*mut u16| -> T) -> T {
- let mut t = s.to_utf16();
- // Null terminate before passing on.
- t.push(0u16);
- f(t.as_mut_ptr())
- }
}
/*
pub fn getenv(n: &str) -> Option<String> {
unsafe {
with_env_lock(|| {
- use os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
- as_utf16_p(n, |u| {
- fill_utf16_buf_and_decode(|buf, sz| {
- libc::GetEnvironmentVariableW(u, buf, sz)
- })
+ use os::win32::{fill_utf16_buf_and_decode};
+ let n = n.to_utf16().append_one(0);
+ fill_utf16_buf_and_decode(|buf, sz| {
+ libc::GetEnvironmentVariableW(n.as_ptr(), buf, sz)
})
})
}
/// Sets the environment variable `n` to the value `v` for the currently running
/// process
pub fn setenv(n: &str, v: &str) {
+ let n = n.to_utf16().append_one(0);
+ let v = v.to_utf16().append_one(0);
unsafe {
with_env_lock(|| {
- use os::win32::as_utf16_p;
- as_utf16_p(n, |nbuf| {
- as_utf16_p(v, |vbuf| {
- libc::SetEnvironmentVariableW(nbuf, vbuf);
- })
- })
+ libc::SetEnvironmentVariableW(n.as_ptr(), v.as_ptr());
})
}
}
}
#[cfg(windows)]
fn _unsetenv(n: &str) {
+ let n = n.to_utf16().append_one(0);
unsafe {
with_env_lock(|| {
- use os::win32::as_utf16_p;
- as_utf16_p(n, |nbuf| {
- libc::SetEnvironmentVariableW(nbuf, ptr::null());
- })
+ libc::SetEnvironmentVariableW(n.as_ptr(), ptr::null());
})
}
}
#[cfg(windows)]
fn chdir(p: &Path) -> bool {
+ let p = match p.as_str() {
+ Some(s) => s.to_utf16().append_one(0),
+ None => return false,
+ };
unsafe {
- use os::win32::as_utf16_p;
- return as_utf16_p(p.as_str().unwrap(), |buf| {
- libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
- });
+ libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL)
}
}
use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
use slice::ImmutableVector;
use str::StrSlice;
- use unstable::dynamic_lib::DynamicLibrary;
+ use dynamic_lib::DynamicLibrary;
#[allow(non_snake_case_functions)]
extern "system" {
+++ /dev/null
-// Copyright 2013-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.
-
-/*!
-
-Dynamic library facilities.
-
-A simple wrapper over the platform's dynamic library facilities
-
-*/
-
-use clone::Clone;
-use c_str::ToCStr;
-use iter::Iterator;
-use mem;
-use ops::*;
-use option::*;
-use os;
-use path::{Path,GenericPath};
-use result::*;
-use slice::{Vector,ImmutableVector};
-use str;
-use string::String;
-use vec::Vec;
-
-pub struct DynamicLibrary { handle: *u8}
-
-impl Drop for DynamicLibrary {
- fn drop(&mut self) {
- match dl::check_for_errors_in(|| {
- unsafe {
- dl::close(self.handle)
- }
- }) {
- Ok(()) => {},
- Err(str) => fail!("{}", str)
- }
- }
-}
-
-impl DynamicLibrary {
- // FIXME (#12938): Until DST lands, we cannot decompose &str into
- // & and str, so we cannot usefully take ToCStr arguments by
- // reference (without forcing an additional & around &str). So we
- // are instead temporarily adding an instance for &Path, so that
- // we can take ToCStr as owned. When DST lands, the &Path instance
- // should be removed, and arguments bound by ToCStr should be
- // passed by reference. (Here: in the `open` method.)
-
- /// Lazily open a dynamic library. When passed None it gives a
- /// handle to the calling process
- pub fn open<T: ToCStr>(filename: Option<T>)
- -> Result<DynamicLibrary, String> {
- unsafe {
- let mut filename = filename;
- let maybe_library = dl::check_for_errors_in(|| {
- match filename.take() {
- Some(name) => dl::open_external(name),
- None => dl::open_internal()
- }
- });
-
- // The dynamic library must not be constructed if there is
- // an error opening the library so the destructor does not
- // run.
- match maybe_library {
- Err(err) => Err(err),
- Ok(handle) => Ok(DynamicLibrary { handle: handle })
- }
- }
- }
-
- /// Prepends a path to this process's search path for dynamic libraries
- pub fn prepend_search_path(path: &Path) {
- let mut search_path = DynamicLibrary::search_path();
- search_path.insert(0, path.clone());
- let newval = DynamicLibrary::create_path(search_path.as_slice());
- os::setenv(DynamicLibrary::envvar(),
- str::from_utf8(newval.as_slice()).unwrap());
- }
-
- /// From a slice of paths, create a new vector which is suitable to be an
- /// environment variable for this platforms dylib search path.
- pub fn create_path(path: &[Path]) -> Vec<u8> {
- let mut newvar = Vec::new();
- for (i, path) in path.iter().enumerate() {
- if i > 0 { newvar.push(DynamicLibrary::separator()); }
- newvar.push_all(path.as_vec());
- }
- return newvar;
- }
-
- /// Returns the environment variable for this process's dynamic library
- /// search path
- pub fn envvar() -> &'static str {
- if cfg!(windows) {
- "PATH"
- } else if cfg!(target_os = "macos") {
- "DYLD_LIBRARY_PATH"
- } else {
- "LD_LIBRARY_PATH"
- }
- }
-
- fn separator() -> u8 {
- if cfg!(windows) {';' as u8} else {':' as u8}
- }
-
- /// Returns the current search path for dynamic libraries being used by this
- /// process
- pub fn search_path() -> Vec<Path> {
- let mut ret = Vec::new();
- match os::getenv_as_bytes(DynamicLibrary::envvar()) {
- Some(env) => {
- for portion in
- env.as_slice()
- .split(|a| *a == DynamicLibrary::separator()) {
- ret.push(Path::new(portion));
- }
- }
- None => {}
- }
- return ret;
- }
-
- /// Access the value at the symbol of the dynamic library
- pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, String> {
- // This function should have a lifetime constraint of 'a on
- // T but that feature is still unimplemented
-
- let maybe_symbol_value = dl::check_for_errors_in(|| {
- symbol.with_c_str(|raw_string| {
- dl::symbol(self.handle, raw_string)
- })
- });
-
- // The value must not be constructed if there is an error so
- // the destructor does not run.
- match maybe_symbol_value {
- Err(err) => Err(err),
- Ok(symbol_value) => Ok(mem::transmute(symbol_value))
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use prelude::*;
- use libc;
-
- #[test]
- #[ignore(cfg(windows))] // FIXME #8818
- #[ignore(cfg(target_os="android"))] // FIXME(#10379)
- fn test_loading_cosine() {
- // The math library does not need to be loaded since it is already
- // statically linked in
- let none: Option<Path> = None; // appease the typechecker
- let libm = match DynamicLibrary::open(none) {
- Err(error) => fail!("Could not load self as module: {}", error),
- Ok(libm) => libm
- };
-
- let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
- match libm.symbol("cos") {
- Err(error) => fail!("Could not load function cos: {}", error),
- Ok(cosine) => cosine
- }
- };
-
- let argument = 0.0;
- let expected_result = 1.0;
- let result = cosine(argument);
- if result != expected_result {
- fail!("cos({:?}) != {:?} but equaled {:?} instead", argument,
- expected_result, result)
- }
- }
-
- #[test]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn test_errors_do_not_crash() {
- // Open /dev/null as a library to get an error, and make sure
- // that only causes an error, and not a crash.
- let path = Path::new("/dev/null");
- match DynamicLibrary::open(Some(&path)) {
- Err(_) => {}
- Ok(_) => fail!("Successfully opened the empty library.")
- }
- }
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-pub mod dl {
- use prelude::*;
-
- use c_str::{CString, ToCStr};
- use libc;
- use ptr;
- use result::*;
- use str::StrAllocating;
- use string::String;
-
- pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
- filename.with_c_str(|raw_name| {
- dlopen(raw_name, Lazy as libc::c_int) as *u8
- })
- }
-
- pub unsafe fn open_internal() -> *u8 {
- dlopen(ptr::null(), Lazy as libc::c_int) as *u8
- }
-
- pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
- use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
- static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
- unsafe {
- // dlerror isn't thread safe, so we need to lock around this entire
- // sequence
- let _guard = lock.lock();
- let _old_error = dlerror();
-
- let result = f();
-
- let last_error = dlerror();
- let ret = if ptr::null() == last_error {
- Ok(result)
- } else {
- Err(CString::new(last_error, false).as_str()
- .unwrap()
- .to_string())
- };
-
- ret
- }
- }
-
- pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
- dlsym(handle as *libc::c_void, symbol) as *u8
- }
- pub unsafe fn close(handle: *u8) {
- dlclose(handle as *libc::c_void); ()
- }
-
- pub enum RTLD {
- Lazy = 1,
- Now = 2,
- Global = 256,
- Local = 0,
- }
-
- #[link_name = "dl"]
- extern {
- fn dlopen(filename: *libc::c_char, flag: libc::c_int) -> *libc::c_void;
- fn dlerror() -> *libc::c_char;
- fn dlsym(handle: *libc::c_void, symbol: *libc::c_char) -> *libc::c_void;
- fn dlclose(handle: *libc::c_void) -> libc::c_int;
- }
-}
-
-#[cfg(target_os = "win32")]
-pub mod dl {
- use libc;
- use os;
- use ptr;
- use result::{Ok, Err, Result};
- use string::String;
- use str;
- use c_str::ToCStr;
-
- pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
- // Windows expects Unicode data
- let filename_cstr = filename.to_c_str();
- let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
- os::win32::as_utf16_p(filename_str, |raw_name| {
- LoadLibraryW(raw_name as *libc::c_void) as *u8
- })
- }
-
- pub unsafe fn open_internal() -> *u8 {
- let handle = ptr::null();
- GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
- handle as *u8
- }
-
- pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
- unsafe {
- SetLastError(0);
-
- let result = f();
-
- let error = os::errno();
- if 0 == error {
- Ok(result)
- } else {
- Err(format!("Error code {}", error))
- }
- }
- }
-
- pub unsafe fn symbol(handle: *u8, symbol: *libc::c_char) -> *u8 {
- GetProcAddress(handle as *libc::c_void, symbol) as *u8
- }
- pub unsafe fn close(handle: *u8) {
- FreeLibrary(handle as *libc::c_void); ()
- }
-
- #[allow(non_snake_case_functions)]
- extern "system" {
- fn SetLastError(error: libc::size_t);
- fn LoadLibraryW(name: *libc::c_void) -> *libc::c_void;
- fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
- handle: **libc::c_void) -> *libc::c_void;
- fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
- fn FreeLibrary(handle: *libc::c_void);
- }
-}
+++ /dev/null
-// Copyright 2012-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.
-
-#![doc(hidden)]
-
-pub mod dynamic_lib;
tests)
}
+pub enum ColorConfig {
+ AutoColor,
+ AlwaysColor,
+ NeverColor,
+}
+
pub struct TestOpts {
pub filter: Option<Regex>,
pub run_ignored: bool,
pub test_shard: Option<(uint,uint)>,
pub logfile: Option<Path>,
pub nocapture: bool,
+ pub color: ColorConfig,
}
impl TestOpts {
test_shard: None,
logfile: None,
nocapture: false,
+ color: AutoColor,
}
}
}
getopts::optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite",
"A.B"),
getopts::optflag("", "nocapture", "don't capture stdout/stderr of each \
- task, allow printing directly"))
+ task, allow printing directly"),
+ getopts::optopt("", "color", "Configure coloring of output:
+ auto = colorize if stdout is a tty and tests are run on serially (default);
+ always = always colorize output;
+ never = never colorize output;", "auto|always|never"))
}
fn usage(binary: &str) {
nocapture = os::getenv("RUST_TEST_NOCAPTURE").is_some();
}
+ let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
+ Some("auto") | None => AutoColor,
+ Some("always") => AlwaysColor,
+ Some("never") => NeverColor,
+
+ Some(v) => return Some(Err(format!("argument for --color must be \
+ auto, always, or never (was {})",
+ v))),
+ };
+
let test_opts = TestOpts {
filter: filter,
run_ignored: run_ignored,
test_shard: test_shard,
logfile: logfile,
nocapture: nocapture,
+ color: color,
};
Some(Ok(test_opts))
Ok(ConsoleTestState {
out: out,
log_out: log_out,
- use_color: use_color(),
+ use_color: use_color(opts),
total: 0u,
passed: 0u,
failed: 0u,
assert!(apos < bpos);
}
-fn use_color() -> bool {
- get_concurrency() == 1 && io::stdout().get_ref().isatty()
+fn use_color(opts: &TestOpts) -> bool {
+ match opts.color {
+ AutoColor => get_concurrency() == 1 && io::stdout().get_ref().isatty(),
+ AlwaysColor => true,
+ NeverColor => false,
+ }
}
#[deriving(Clone)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
#[no_mangle]
pub fn foo() { bar(); }
--- /dev/null
+// 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.
+
+
+// Used to cause ICE
+
+static VEC: [u32, ..256] = vec!(); //~ ERROR mismatched types
+
+fn main() {}
+
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::unstable::dynamic_lib::DynamicLibrary;
+use std::dynamic_lib::DynamicLibrary;
use std::os;
pub fn main() {
// aux-build:linkage-visibility.rs
// ignore-android: FIXME(#10379)
-// ignore-win32: std::unstable::dynamic_lib does not work on win32 well
+// ignore-win32: std::dynamic_lib does not work on win32 well
extern crate foo = "linkage-visibility";