<commit_before>
use std::fs;
use std::path::{Path, PathBuf};
use std::io;
use std::char::from_u32;
use std::io::Write;
use std::process::{Command, Stdio, ExitStatus};
use std::ffi::{OsStr, OsString};
use hyper::{self, Client};
use openssl::crypto::hash::Hasher;

use rand::random;

pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result<bool> {
	if !is_directory(path.as_ref()) {
		callback(path.as_ref());
		fs::create_dir_all(path.as_ref()).map(|()| true)
	} else {
		Ok(false)
	}
}

pub fn is_directory<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_dir) == Some(true)
}

pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_file) == Some(true)
}

pub fn path_exists<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).is_ok()
}

pub fn random_string(length: usize) -> String {
	let chars = b"abcdefghijklmnopqrstuvwxyz0123456789_";
	(0..length).map(|_| from_u32(chars[random::<usize>() % chars.len()] as u32).unwrap()).collect()
}

pub fn if_not_empty<S: PartialEq<str>>(s: S) -> Option<S> {
	if s == *"" {
		None
	} else {
		Some(s)
	}
}

pub fn write_file(path: &Path, contents: &str) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.write(true)
		.truncate(true)
		.create(true)
		.open(path));

	try!(io::Write::write_all(&mut file, contents.as_bytes()));

	try!(file.sync_data());

	Ok(())
}

pub fn read_file(path: &Path) -> io::Result<String> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let mut contents = String::new();

	try!(io::Read::read_to_string(&mut file, &mut contents));

	Ok(contents)
}

pub fn filter_file<F: FnMut(&str) -> bool>(src: &Path, dest: &Path, mut filter: F) -> io::Result<usize> {
	let src_file = try!(fs::File::open(src));
	let dest_file = try!(fs::File::create(dest));

	let mut reader = io::BufReader::new(src_file);
	let mut writer = io::BufWriter::new(dest_file);
	let mut removed = 0;

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if filter(&line) {
			try!(writeln!(&mut writer, "{}", &line));
		} else {
			removed += 1;
		}
	}

	try!(writer.flush());

	Ok(removed)
}

pub fn match_file<T, F: FnMut(&str) -> Option<T>>(src: &Path, mut f: F) -> io::Result<Option<T>> {
	let src_file = try!(fs::File::open(src));

	let mut reader = io::BufReader::new(src_file);

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if let Some(r) = f(&line) {
			return Ok(Some(r));
		}
	}

	Ok(None)
}

pub fn append_file(dest: &Path, line: &str) -> io::Result<()> {
	let mut dest_file = try!(fs::OpenOptions::new()
		.write(true)
		.append(true)
		.create(true)
		.open(dest)
		);

	try!(writeln!(&mut dest_file, "{}", line));

	try!(dest_file.sync_data());

	Ok(())
}

pub fn tee_file<W: io::Write>(path: &Path, mut w: &mut W) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	loop {
		let bytes_read = try!(io::Read::read(&mut file, &mut buffer));

		if bytes_read != 0 {
			try!(io::Write::write_all(w, &mut buffer[0..bytes_read]));
		} else {
			return Ok(());
		}
	}
}

pub enum DownloadError {
	Status(hyper::status::StatusCode),
	Network(hyper::Error),
	File(io::Error),
}
pub type DownloadResult<T> = Result<T, DownloadError>;

pub fn download_file<P: AsRef<Path>>(url: hyper::Url, path: P, mut hasher: Option<&mut Hasher>) -> DownloadResult<()> {
	let client = Client::new();

	let mut res = try!(client.get(url).send().map_err(DownloadError::Network));
	if res.status != hyper::Ok { return Err(DownloadError::Status(res.status)); }

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	let mut file = try!(fs::File::create(path).map_err(DownloadError::File));

	loop {
		let bytes_read = try!(io::Read::read(&mut res, &mut buffer)
			.map_err(hyper::Error::Io)
			.map_err(DownloadError::Network)
			);

		if bytes_read != 0 {
			if let Some(ref mut h) = hasher {
				try!(io::Write::write_all(*h, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
			}
			try!(io::Write::write_all(&mut file, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
		} else {
			try!(file.sync_data().map_err(DownloadError::File));
			return Ok(());
		}
	}
}

pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_dir(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = fs::remove_dir_all(src);
	symlink_dir_inner(src, dest)
}

pub fn symlink_file(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_file(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = fs::remove_file(src);
	symlink_file_inner(src, dest)
}

pub fn hardlink(src: &Path, dest: &Path) -> io::Result<()> {
	let _ = fs::remove_file(dest);
	fs::hard_link(src, dest)
}

pub enum CommandError {
	Io(io::Error),
	Status(ExitStatus),
}

pub type CommandResult<T> = Result<T, CommandError>;

pub fn cmd_status(cmd: &mut Command) -> CommandResult<()> {
	cmd.status().map_err(CommandError::Io).and_then(|s| {
		if s.success() {
			Ok(())
		} else {
			Err(CommandError::Status(s))
		}
	})
}

pub fn copy_dir(src: &Path, dest: &Path) -> CommandResult<()> {
	#[cfg(windows)]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("robocopy").arg(src).arg(dest).arg("/E"))
	}
	#[cfg(not(windows))]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("cp").arg("-R").arg(src).arg(dest))
	}

	let _ = fs::remove_dir_all(dest);
	copy_dir_inner(src, dest)
}

pub fn prefix_arg<S: AsRef<OsStr>>(name: &str, s: S) -> OsString {
	let mut arg = OsString::from(name);
	arg.push(s);
	arg
}

pub fn open_browser(path: &Path) -> io::Result<bool> {
	#[cfg(not(windows))]
	fn has_cmd(cmd: &&str) -> bool {
		cmd_status(Command::new("which")
			.arg(cmd)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())).is_ok()
	}
	#[cfg(not(windows))]
	fn inner(path: &Path) -> io::Result<bool> {
		let commands = ["xdg-open", "open", "firefox", "chromium"];
		if let Some(cmd) = commands.iter().map(|s| *s).filter(has_cmd).next() {
			Command::new(cmd)
				.arg(path)
				.stdin(Stdio::null())
				.stdout(Stdio::null())
				.stderr(Stdio::null())
				.spawn()
				.map(|_| true)
		} else {
			Ok(false)
		}
	}
	#[cfg(windows)]
	fn inner(path: &Path) -> io::Result<bool> {
		Command::new("cmd")
			.arg("/C")
			.arg("start")
			.arg(path)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())
			.spawn()
			.map(|_| true)
	}
	inner(path)
}
pub fn home_dir() -> Option<PathBuf> {
	#[cfg(not(windows))]
	fn inner() -> Option<PathBuf> {
		::std::env::home_dir()
	}
	#[cfg(windows)]
	fn inner() -> Option<PathBuf> {
		windows::get_special_folder(&windows::FOLDERID_Profile).ok()
	}

	inner()
}

#[cfg(windows)]
pub mod windows {
	use winapi::*;
	use std::io;
	use std::path::PathBuf;
	use std::ptr;
	use std::slice;
	use std::ffi::OsString;
	use std::os::windows::ffi::OsStringExt;
	use shell32;
	use ole32;

	#[allow(non_upper_case_globals)]
	pub const FOLDERID_LocalAppData: GUID = GUID {
		Data1: 0xF1B32785,
		Data2: 0x6FBA,
		Data3: 0x4FCF,
		Data4: [0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91],
	};
	#[allow(non_upper_case_globals)]
	pub const FOLDERID_Profile: GUID = GUID {
		Data1: 0x5E6C858F,
		Data2: 0x0E22,
		Data3: 0x4760,
		Data4: [0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73],
	};

	pub fn get_special_folder(id: &shtypes::KNOWNFOLDERID) -> io::Result<PathBuf> {

		let mut path = ptr::null_mut();
		let result;

		unsafe {
			let code = shell32::SHGetKnownFolderPath(id, 0, ptr::null_mut(), &mut path);
			if code == 0 {
				let mut length = 0usize;
				while *path.offset(length as isize) != 0 {
					length += 1;
				}
				let slice = slice::from_raw_parts(path, length);
				result = Ok(OsString::from_wide(slice).into());
			} else {
				result = Err(io::Error::from_raw_os_error(code));
			}
			ole32::CoTaskMemFree(path as *mut _);
		}
		result
	}
}
<commit_msg>Switch order<commit_after>
use std::fs;
use std::path::{Path, PathBuf};
use std::io;
use std::char::from_u32;
use std::io::Write;
use std::process::{Command, Stdio, ExitStatus};
use std::ffi::{OsStr, OsString};
use hyper::{self, Client};
use openssl::crypto::hash::Hasher;

use rand::random;

pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result<bool> {
	if !is_directory(path.as_ref()) {
		callback(path.as_ref());
		fs::create_dir_all(path.as_ref()).map(|()| true)
	} else {
		Ok(false)
	}
}

pub fn is_directory<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_dir) == Some(true)
}

pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).ok().as_ref().map(fs::Metadata::is_file) == Some(true)
}

pub fn path_exists<P: AsRef<Path>>(path: P) -> bool {
	fs::metadata(path).is_ok()
}

pub fn random_string(length: usize) -> String {
	let chars = b"abcdefghijklmnopqrstuvwxyz0123456789_";
	(0..length).map(|_| from_u32(chars[random::<usize>() % chars.len()] as u32).unwrap()).collect()
}

pub fn if_not_empty<S: PartialEq<str>>(s: S) -> Option<S> {
	if s == *"" {
		None
	} else {
		Some(s)
	}
}

pub fn write_file(path: &Path, contents: &str) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.write(true)
		.truncate(true)
		.create(true)
		.open(path));

	try!(io::Write::write_all(&mut file, contents.as_bytes()));

	try!(file.sync_data());

	Ok(())
}

pub fn read_file(path: &Path) -> io::Result<String> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let mut contents = String::new();

	try!(io::Read::read_to_string(&mut file, &mut contents));

	Ok(contents)
}

pub fn filter_file<F: FnMut(&str) -> bool>(src: &Path, dest: &Path, mut filter: F) -> io::Result<usize> {
	let src_file = try!(fs::File::open(src));
	let dest_file = try!(fs::File::create(dest));

	let mut reader = io::BufReader::new(src_file);
	let mut writer = io::BufWriter::new(dest_file);
	let mut removed = 0;

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if filter(&line) {
			try!(writeln!(&mut writer, "{}", &line));
		} else {
			removed += 1;
		}
	}

	try!(writer.flush());

	Ok(removed)
}

pub fn match_file<T, F: FnMut(&str) -> Option<T>>(src: &Path, mut f: F) -> io::Result<Option<T>> {
	let src_file = try!(fs::File::open(src));

	let mut reader = io::BufReader::new(src_file);

	for result in io::BufRead::lines(&mut reader) {
		let line = try!(result);
		if let Some(r) = f(&line) {
			return Ok(Some(r));
		}
	}

	Ok(None)
}

pub fn append_file(dest: &Path, line: &str) -> io::Result<()> {
	let mut dest_file = try!(fs::OpenOptions::new()
		.write(true)
		.append(true)
		.create(true)
		.open(dest)
		);

	try!(writeln!(&mut dest_file, "{}", line));

	try!(dest_file.sync_data());

	Ok(())
}

pub fn tee_file<W: io::Write>(path: &Path, mut w: &mut W) -> io::Result<()> {
	let mut file = try!(fs::OpenOptions::new()
		.read(true)
		.open(path));

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	loop {
		let bytes_read = try!(io::Read::read(&mut file, &mut buffer));

		if bytes_read != 0 {
			try!(io::Write::write_all(w, &mut buffer[0..bytes_read]));
		} else {
			return Ok(());
		}
	}
}

pub enum DownloadError {
	Status(hyper::status::StatusCode),
	Network(hyper::Error),
	File(io::Error),
}
pub type DownloadResult<T> = Result<T, DownloadError>;

pub fn download_file<P: AsRef<Path>>(url: hyper::Url, path: P, mut hasher: Option<&mut Hasher>) -> DownloadResult<()> {
	let client = Client::new();

	let mut res = try!(client.get(url).send().map_err(DownloadError::Network));
	if res.status != hyper::Ok { return Err(DownloadError::Status(res.status)); }

	let buffer_size = 0x10000;
	let mut buffer = vec![0u8; buffer_size];

	let mut file = try!(fs::File::create(path).map_err(DownloadError::File));

	loop {
		let bytes_read = try!(io::Read::read(&mut res, &mut buffer)
			.map_err(hyper::Error::Io)
			.map_err(DownloadError::Network)
			);

		if bytes_read != 0 {
			if let Some(ref mut h) = hasher {
				try!(io::Write::write_all(*h, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
			}
			try!(io::Write::write_all(&mut file, &mut buffer[0..bytes_read]).map_err(DownloadError::File));
		} else {
			try!(file.sync_data().map_err(DownloadError::File));
			return Ok(());
		}
	}
}

pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_dir(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_dir_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = fs::remove_dir_all(dest);
	symlink_dir_inner(src, dest)
}

pub fn symlink_file(src: &Path, dest: &Path) -> io::Result<()> {
	#[cfg(windows)]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::windows::fs::symlink_file(src, dest)
	}
	#[cfg(not(windows))]
	fn symlink_file_inner(src: &Path, dest: &Path) -> io::Result<()> {
		::std::os::unix::fs::symlink(src, dest)
	}

	let _ = fs::remove_file(dest);
	symlink_file_inner(src, dest)
}

pub fn hardlink(src: &Path, dest: &Path) -> io::Result<()> {
	let _ = fs::remove_file(dest);
	fs::hard_link(src, dest)
}

pub enum CommandError {
	Io(io::Error),
	Status(ExitStatus),
}

pub type CommandResult<T> = Result<T, CommandError>;

pub fn cmd_status(cmd: &mut Command) -> CommandResult<()> {
	cmd.status().map_err(CommandError::Io).and_then(|s| {
		if s.success() {
			Ok(())
		} else {
			Err(CommandError::Status(s))
		}
	})
}

pub fn copy_dir(src: &Path, dest: &Path) -> CommandResult<()> {
	#[cfg(windows)]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("robocopy").arg(src).arg(dest).arg("/E"))
	}
	#[cfg(not(windows))]
	fn copy_dir_inner(src: &Path, dest: &Path) -> CommandResult<()> {
		cmd_status(Command::new("cp").arg("-R").arg(src).arg(dest))
	}

	let _ = fs::remove_dir_all(dest);
	copy_dir_inner(src, dest)
}

pub fn prefix_arg<S: AsRef<OsStr>>(name: &str, s: S) -> OsString {
	let mut arg = OsString::from(name);
	arg.push(s);
	arg
}

pub fn open_browser(path: &Path) -> io::Result<bool> {
	#[cfg(not(windows))]
	fn has_cmd(cmd: &&str) -> bool {
		cmd_status(Command::new("which")
			.arg(cmd)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())).is_ok()
	}
	#[cfg(not(windows))]
	fn inner(path: &Path) -> io::Result<bool> {
		let commands = ["xdg-open", "open", "firefox", "chromium"];
		if let Some(cmd) = commands.iter().map(|s| *s).filter(has_cmd).next() {
			Command::new(cmd)
				.arg(path)
				.stdin(Stdio::null())
				.stdout(Stdio::null())
				.stderr(Stdio::null())
				.spawn()
				.map(|_| true)
		} else {
			Ok(false)
		}
	}
	#[cfg(windows)]
	fn inner(path: &Path) -> io::Result<bool> {
		Command::new("cmd")
			.arg("/C")
			.arg("start")
			.arg(path)
			.stdin(Stdio::null())
			.stdout(Stdio::null())
			.stderr(Stdio::null())
			.spawn()
			.map(|_| true)
	}
	inner(path)
}
pub fn home_dir() -> Option<PathBuf> {
	#[cfg(not(windows))]
	fn inner() -> Option<PathBuf> {
		::std::env::home_dir()
	}
	#[cfg(windows)]
	fn inner() -> Option<PathBuf> {
		windows::get_special_folder(&windows::FOLDERID_Profile).ok()
	}

	inner()
}

#[cfg(windows)]
pub mod windows {
	use winapi::*;
	use std::io;
	use std::path::PathBuf;
	use std::ptr;
	use std::slice;
	use std::ffi::OsString;
	use std::os::windows::ffi::OsStringExt;
	use shell32;
	use ole32;

	#[allow(non_upper_case_globals)]
	pub const FOLDERID_LocalAppData: GUID = GUID {
		Data1: 0xF1B32785,
		Data2: 0x6FBA,
		Data3: 0x4FCF,
		Data4: [0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91],
	};
	#[allow(non_upper_case_globals)]
	pub const FOLDERID_Profile: GUID = GUID {
		Data1: 0x5E6C858F,
		Data2: 0x0E22,
		Data3: 0x4760,
		Data4: [0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73],
	};

	pub fn get_special_folder(id: &shtypes::KNOWNFOLDERID) -> io::Result<PathBuf> {

		let mut path = ptr::null_mut();
		let result;

		unsafe {
			let code = shell32::SHGetKnownFolderPath(id, 0, ptr::null_mut(), &mut path);
			if code == 0 {
				let mut length = 0usize;
				while *path.offset(length as isize) != 0 {
					length += 1;
				}
				let slice = slice::from_raw_parts(path, length);
				result = Ok(OsString::from_wide(slice).into());
			} else {
				result = Err(io::Error::from_raw_os_error(code));
			}
			ole32::CoTaskMemFree(path as *mut _);
		}
		result
	}
}
<|endoftext|>


<commit_before><commit_msg>Add test for a mixture of arguments<commit_after>extern crate clap;

use clap::{App, Arg};

#[test]
fn mixed_positional_and_options() {
    App::new("mixed_positional_and_options")
        .arg(Arg::with_name("feed")
             .short("f")
             .long("feed")
             .takes_value(true)
             .multiple(true))
        .arg(Arg::with_name("config")
             .required(true)
             .index(1))
        .get_matches_from(vec!["", "--feed", "1", "config.toml"]);
}
<|endoftext|>


<commit_before><commit_msg>Added new constructor for gate parameters struct.<commit_after><|endoftext|>


<commit_before><commit_msg>Return bool instead of CargoResult for filter<commit_after><|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2015 Rustcc developers

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

//! Basic single threaded Coroutine
//!
//! ```rust
//! use coroutine::{spawn, sched};
//!
//! let coro = spawn(|| {
//!     println!("Before yield");
//!
//!     // Yield back to its parent who resume this coroutine
//!     sched();
//!
//!     println!("I am back!");
//! });
//!
//! // Starts the Coroutine
//! coro.resume().ok().expect("Failed to resume");
//!
//! println!("Back to main");
//!
//! // Resume it
//! coro.resume().ok().expect("Failed to resume");
//!
//! println!("Coroutine finished");
//! ```
//!

/* Here is the coroutine(with scheduler) workflow:
 *
 *                               --------------------------------
 * --------------------------    |                              |
 * |                        |    v                              |
 * |                  ----------------                          |  III.Coroutine::yield_now()
 * |             ---> |   Scheduler  |  <-----                  |
 * |    parent   |    ----------------       |   parent         |
 * |             |           ^ parent        |                  |
 * |   --------------  --------------  --------------           |
 * |   |Coroutine(1)|  |Coroutine(2)|  |Coroutine(3)|  ----------
 * |   --------------  --------------  --------------
 * |         ^            |     ^
 * |         |            |     |  II.do_some_works
 * -----------            -------
 *   I.Handle.resume()
 *
 *
 *  First, all coroutines have a link to a parent coroutine, which was set when the coroutine resumed.
 *  In the scheduler/coroutine model, every worker coroutine has a parent pointer pointing to
 *  the scheduler coroutine(which is a raw thread).
 *  Scheduler resumes a proper coroutine and set the parent pointer, like procedure I does.
 *  When a coroutine is awaken, it does some work like procedure II does.
 *  When a coroutine yield(io, finished, paniced or sched), it resumes its parent's context,
 *  like procedure III does.
 *  Now the scheduler is awake again and it simply decides whether to put the coroutine to queue again or not,
 *  according to the coroutine's return status.
 *  And last, the scheduler continues the scheduling loop and selects a proper coroutine to wake up.
 */

use std::default::Default;
use thunk::Thunk;
use std::mem::transmute;
use std::rt::unwind::try;
use std::cell::UnsafeCell;
use std::ops::Deref;
use std::sync::Arc;
use std::fmt::{self, Debug};

use spin::Mutex;

use context::Context;
use stack::Stack;
use environment::Environment;
use {Options, Result, Error, State};

/// Handle of a Coroutine
#[derive(Clone)]
pub struct Handle(Arc<UnsafeCell<Coroutine>>);

impl Debug for Handle {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            self.get_inner().name().fmt(f)
        }
    }
}

unsafe impl Send for Handle {}
unsafe impl Sync for Handle {}

impl Handle {
    fn new(c: Coroutine) -> Handle {
        Handle(Arc::new(UnsafeCell::new(c)))
    }

    unsafe fn get_inner_mut(&self) -> &mut Coroutine {
        &mut *self.0.get()
    }

    unsafe fn get_inner(&self) -> &Coroutine {
        &*self.0.get()
    }

    /// Resume the Coroutine
    pub fn resume(&self) -> Result {
        {
            let mut self_state = self.state_lock().lock();

            match *self_state {
                State::Finished => return Err(Error::Finished),
                State::Panicked => return Err(Error::Panicked),
                State::Normal => return Err(Error::Waiting),
                State::Running => return Ok(State::Running),
                _ => {}
            }

            *self_state = State::Running;
        }

        let env = Environment::current();

        let from_coro_hdl = Coroutine::current();
        {
            let (from_coro, to_coro) = unsafe {
                (from_coro_hdl.get_inner_mut(), self.get_inner_mut())
            };

            // Save state
            from_coro_hdl.set_state(State::Normal);

            env.coroutine_stack.push(unsafe { transmute(self) });
            Context::swap(&mut from_coro.saved_context, &to_coro.saved_context);

            from_coro_hdl.set_state(State::Running);
            self.set_state(env.switch_state);
        }

        match env.running_state.take() {
            Some(err) => Err(Error::Panicking(err)),
            None => Ok(env.switch_state),
        }
    }

    /// Join this Coroutine.
    ///
    /// If the Coroutine panicked, this method will return an `Err` with panic message.
    ///
    /// ```ignore
    /// // Wait until the Coroutine exits
    /// Coroutine::spawn(|| {
    ///     println!("Before yield");
    ///     sched();
    ///     println!("Exiting");
    /// }).join().unwrap();
    /// ```
    #[inline]
    pub fn join(&self) -> Result {
        loop {
            match self.resume() {
                Ok(State::Finished) => break,
                Ok(..) => {},
                Err(Error::Finished) => break,
                Err(err) => return Err(err),
            }
        }
        Ok(State::Finished)
    }

    /// Get the state of the Coroutine
    #[inline]
    pub fn state(&self) -> State {
        *self.state_lock().lock()
    }

    /// Set the state of the Coroutine
    #[inline]
    fn set_state(&self, state: State) {
        *self.state_lock().lock() = state;
    }

    #[inline]
    fn state_lock(&self) -> &Mutex<State> {
        unsafe {
            self.get_inner().state()
        }
    }
}

impl Deref for Handle {
    type Target = Coroutine;

    #[inline]
    fn deref(&self) -> &Coroutine {
        unsafe { self.get_inner() }
    }
}

/// A coroutine is nothing more than a (register context, stack) pair.
// #[derive(Debug)]
pub struct Coroutine {
    /// The segment of stack on which the task is currently running or
    /// if the task is blocked, on which the task will resume
    /// execution.
    current_stack_segment: Option<Stack>,

    /// Always valid if the task is alive and not running.
    saved_context: Context,

    /// State
    state: Mutex<State>,

    /// Name
    name: Option<String>,
}

unsafe impl Send for Coroutine {}

/// Destroy coroutine and try to reuse std::stack segment.
impl Drop for Coroutine {
    fn drop(&mut self) {
        match self.current_stack_segment.take() {
            Some(stack) => {
                let env = Environment::current();
                env.stack_pool.give_stack(stack);
            },
            None => {}
        }
    }
}

/// Initialization function for make context
extern "C" fn coroutine_initialize(_: usize, f: *mut ()) -> ! {
    let func: Box<Thunk> = unsafe { transmute(f) };

    let ret = unsafe { try(move|| func.invoke(())) };

    let env = Environment::current();

    let cur: &mut Coroutine = unsafe {
        let last = & **env.coroutine_stack.last().expect("Impossible happened! No current coroutine!");
        last.get_inner_mut()
    };

    let state = match ret {
        Ok(..) => {
            env.running_state = None;

            State::Finished
        }
        Err(err) => {
            {
                use std::io::stderr;
                use std::io::Write;
                let msg = match err.downcast_ref::<&'static str>() {
                    Some(s) => *s,
                    None => match err.downcast_ref::<String>() {
                        Some(s) => &s[..],
                        None => "Box<Any>",
                    }
                };

                let name = cur.name().unwrap_or("<unnamed>");

                let _ = writeln!(&mut stderr(), "Coroutine '{}' panicked at '{}'", name, msg);
            }

            env.running_state = Some(err);

            State::Panicked
        }
    };

    loop {
        Coroutine::yield_now(state);
    }
}

impl Coroutine {

    #[doc(hidden)]
    pub unsafe fn empty(name: Option<String>, state: State) -> Handle {
        Handle::new(Coroutine {
            current_stack_segment: None,
            saved_context: Context::empty(),
            state: Mutex::new(state),
            name: name,
        })
    }

    #[doc(hidden)]
    pub fn new(name: Option<String>, stack: Stack, ctx: Context, state: State) -> Handle {
        Handle::new(Coroutine {
            current_stack_segment: Some(stack),
            saved_context: ctx,
            state: Mutex::new(state),
            name: name,
        })
    }

    /// Spawn a Coroutine with options
    pub fn spawn_opts<F>(f: F, opts: Options) -> Handle
        where F: FnOnce() + Send + 'static
    {

        let env = Environment::current();
        let mut stack = env.stack_pool.take_stack(opts.stack_size);

        let ctx = Context::new(coroutine_initialize, 0, f, &mut stack);

        Coroutine::new(opts.name, stack, ctx, State::Suspended)
    }

    /// Spawn a Coroutine with default options
    pub fn spawn<F>(f: F) -> Handle
        where F: FnOnce() + Send + 'static
    {
        Coroutine::spawn_opts(f, Default::default())
    }

    /// Yield the current running Coroutine to its parent
    #[inline]
    pub fn yield_now(state: State) {
        // Cannot yield with Running state
        assert!(state != State::Running);

        let env = Environment::current();
        if env.coroutine_stack.len() == 1 {
            // Environment root
            return;
        }

        unsafe {
            match (env.coroutine_stack.pop(), env.coroutine_stack.last()) {
                (Some(from_coro), Some(to_coro)) => {
                    env.switch_state = state;
                    Context::swap(&mut (& *from_coro).get_inner_mut().saved_context, &(& **to_coro).saved_context);
                },
                _ => unreachable!()
            }
        }
    }

    /// Yield the current running Coroutine with `Suspended` state
    #[inline]
    pub fn sched() {
        Coroutine::yield_now(State::Suspended)
    }

    /// Yield the current running Coroutine with `Blocked` state
    #[inline]
    pub fn block() {
        Coroutine::yield_now(State::Blocked)
    }

    /// Get a Handle to the current running Coroutine.
    ///
    /// It is unsafe because it is an undefined behavior if you resume a Coroutine
    /// in more than one native thread.
    #[inline]
    pub fn current() -> &'static Handle {
        Environment::current().coroutine_stack.last().map(|hdl| unsafe { (& **hdl) })
            .expect("Impossible happened! No current coroutine!")
    }

    #[inline(always)]
    fn state(&self) -> &Mutex<State> {
        &self.state
    }

    /// Get the name of the Coroutine
    #[inline(always)]
    pub fn name(&self) -> Option<&str> {
        self.name.as_ref().map(|s| &**s)
    }

    /// Determines whether the current Coroutine is unwinding because of panic.
    #[inline(always)]
    pub fn panicking(&self) -> bool {
        *self.state().lock() == State::Panicked
    }

    /// Determines whether the Coroutine is finished
    #[inline(always)]
    pub fn finished(&self) -> bool {
        *self.state().lock() == State::Finished
    }
}
<commit_msg>remove an "ignore" from coroutine_clonable's doc string, while their still remains one in Builder's, which causes test failure and needs to be fixed later.<commit_after>// The MIT License (MIT)

// Copyright (c) 2015 Rustcc developers

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

//! Basic single threaded Coroutine
//!
//! ```rust
//! use coroutine::{spawn, sched};
//!
//! let coro = spawn(|| {
//!     println!("Before yield");
//!
//!     // Yield back to its parent who resume this coroutine
//!     sched();
//!
//!     println!("I am back!");
//! });
//!
//! // Starts the Coroutine
//! coro.resume().ok().expect("Failed to resume");
//!
//! println!("Back to main");
//!
//! // Resume it
//! coro.resume().ok().expect("Failed to resume");
//!
//! println!("Coroutine finished");
//! ```
//!

/* Here is the coroutine(with scheduler) workflow:
 *
 *                               --------------------------------
 * --------------------------    |                              |
 * |                        |    v                              |
 * |                  ----------------                          |  III.Coroutine::yield_now()
 * |             ---> |   Scheduler  |  <-----                  |
 * |    parent   |    ----------------       |   parent         |
 * |             |           ^ parent        |                  |
 * |   --------------  --------------  --------------           |
 * |   |Coroutine(1)|  |Coroutine(2)|  |Coroutine(3)|  ----------
 * |   --------------  --------------  --------------
 * |         ^            |     ^
 * |         |            |     |  II.do_some_works
 * -----------            -------
 *   I.Handle.resume()
 *
 *
 *  First, all coroutines have a link to a parent coroutine, which was set when the coroutine resumed.
 *  In the scheduler/coroutine model, every worker coroutine has a parent pointer pointing to
 *  the scheduler coroutine(which is a raw thread).
 *  Scheduler resumes a proper coroutine and set the parent pointer, like procedure I does.
 *  When a coroutine is awaken, it does some work like procedure II does.
 *  When a coroutine yield(io, finished, paniced or sched), it resumes its parent's context,
 *  like procedure III does.
 *  Now the scheduler is awake again and it simply decides whether to put the coroutine to queue again or not,
 *  according to the coroutine's return status.
 *  And last, the scheduler continues the scheduling loop and selects a proper coroutine to wake up.
 */

use std::default::Default;
use thunk::Thunk;
use std::mem::transmute;
use std::rt::unwind::try;
use std::cell::UnsafeCell;
use std::ops::Deref;
use std::sync::Arc;
use std::fmt::{self, Debug};

use spin::Mutex;

use context::Context;
use stack::Stack;
use environment::Environment;
use {Options, Result, Error, State};

/// Handle of a Coroutine
#[derive(Clone)]
pub struct Handle(Arc<UnsafeCell<Coroutine>>);

impl Debug for Handle {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            self.get_inner().name().fmt(f)
        }
    }
}

unsafe impl Send for Handle {}
unsafe impl Sync for Handle {}

impl Handle {
    fn new(c: Coroutine) -> Handle {
        Handle(Arc::new(UnsafeCell::new(c)))
    }

    unsafe fn get_inner_mut(&self) -> &mut Coroutine {
        &mut *self.0.get()
    }

    unsafe fn get_inner(&self) -> &Coroutine {
        &*self.0.get()
    }

    /// Resume the Coroutine
    pub fn resume(&self) -> Result {
        {
            let mut self_state = self.state_lock().lock();

            match *self_state {
                State::Finished => return Err(Error::Finished),
                State::Panicked => return Err(Error::Panicked),
                State::Normal => return Err(Error::Waiting),
                State::Running => return Ok(State::Running),
                _ => {}
            }

            *self_state = State::Running;
        }

        let env = Environment::current();

        let from_coro_hdl = Coroutine::current();
        {
            let (from_coro, to_coro) = unsafe {
                (from_coro_hdl.get_inner_mut(), self.get_inner_mut())
            };

            // Save state
            from_coro_hdl.set_state(State::Normal);

            env.coroutine_stack.push(unsafe { transmute(self) });
            Context::swap(&mut from_coro.saved_context, &to_coro.saved_context);

            from_coro_hdl.set_state(State::Running);
            self.set_state(env.switch_state);
        }

        match env.running_state.take() {
            Some(err) => Err(Error::Panicking(err)),
            None => Ok(env.switch_state),
        }
    }

    /// Join this Coroutine.
    ///
    /// If the Coroutine panicked, this method will return an `Err` with panic message.
    ///
    /// ```
    /// use coroutine::Coroutine;
    /// use coroutine::sched;
    /// // Wait until the Coroutine exits
    /// Coroutine::spawn(|| {
    ///     println!("Before yield");
    ///     sched();
    ///     println!("Exiting");
    /// }).join().unwrap();
    /// ```
    #[inline]
    pub fn join(&self) -> Result {
        loop {
            match self.resume() {
                Ok(State::Finished) => break,
                Ok(..) => {},
                Err(Error::Finished) => break,
                Err(err) => return Err(err),
            }
        }
        Ok(State::Finished)
    }

    /// Get the state of the Coroutine
    #[inline]
    pub fn state(&self) -> State {
        *self.state_lock().lock()
    }

    /// Set the state of the Coroutine
    #[inline]
    fn set_state(&self, state: State) {
        *self.state_lock().lock() = state;
    }

    #[inline]
    fn state_lock(&self) -> &Mutex<State> {
        unsafe {
            self.get_inner().state()
        }
    }
}

impl Deref for Handle {
    type Target = Coroutine;

    #[inline]
    fn deref(&self) -> &Coroutine {
        unsafe { self.get_inner() }
    }
}

/// A coroutine is nothing more than a (register context, stack) pair.
// #[derive(Debug)]
pub struct Coroutine {
    /// The segment of stack on which the task is currently running or
    /// if the task is blocked, on which the task will resume
    /// execution.
    current_stack_segment: Option<Stack>,

    /// Always valid if the task is alive and not running.
    saved_context: Context,

    /// State
    state: Mutex<State>,

    /// Name
    name: Option<String>,
}

unsafe impl Send for Coroutine {}

/// Destroy coroutine and try to reuse std::stack segment.
impl Drop for Coroutine {
    fn drop(&mut self) {
        match self.current_stack_segment.take() {
            Some(stack) => {
                let env = Environment::current();
                env.stack_pool.give_stack(stack);
            },
            None => {}
        }
    }
}

/// Initialization function for make context
extern "C" fn coroutine_initialize(_: usize, f: *mut ()) -> ! {
    let func: Box<Thunk> = unsafe { transmute(f) };

    let ret = unsafe { try(move|| func.invoke(())) };

    let env = Environment::current();

    let cur: &mut Coroutine = unsafe {
        let last = & **env.coroutine_stack.last().expect("Impossible happened! No current coroutine!");
        last.get_inner_mut()
    };

    let state = match ret {
        Ok(..) => {
            env.running_state = None;

            State::Finished
        }
        Err(err) => {
            {
                use std::io::stderr;
                use std::io::Write;
                let msg = match err.downcast_ref::<&'static str>() {
                    Some(s) => *s,
                    None => match err.downcast_ref::<String>() {
                        Some(s) => &s[..],
                        None => "Box<Any>",
                    }
                };

                let name = cur.name().unwrap_or("<unnamed>");

                let _ = writeln!(&mut stderr(), "Coroutine '{}' panicked at '{}'", name, msg);
            }

            env.running_state = Some(err);

            State::Panicked
        }
    };

    loop {
        Coroutine::yield_now(state);
    }
}

impl Coroutine {

    #[doc(hidden)]
    pub unsafe fn empty(name: Option<String>, state: State) -> Handle {
        Handle::new(Coroutine {
            current_stack_segment: None,
            saved_context: Context::empty(),
            state: Mutex::new(state),
            name: name,
        })
    }

    #[doc(hidden)]
    pub fn new(name: Option<String>, stack: Stack, ctx: Context, state: State) -> Handle {
        Handle::new(Coroutine {
            current_stack_segment: Some(stack),
            saved_context: ctx,
            state: Mutex::new(state),
            name: name,
        })
    }

    /// Spawn a Coroutine with options
    pub fn spawn_opts<F>(f: F, opts: Options) -> Handle
        where F: FnOnce() + Send + 'static
    {

        let env = Environment::current();
        let mut stack = env.stack_pool.take_stack(opts.stack_size);

        let ctx = Context::new(coroutine_initialize, 0, f, &mut stack);

        Coroutine::new(opts.name, stack, ctx, State::Suspended)
    }

    /// Spawn a Coroutine with default options
    pub fn spawn<F>(f: F) -> Handle
        where F: FnOnce() + Send + 'static
    {
        Coroutine::spawn_opts(f, Default::default())
    }

    /// Yield the current running Coroutine to its parent
    #[inline]
    pub fn yield_now(state: State) {
        // Cannot yield with Running state
        assert!(state != State::Running);

        let env = Environment::current();
        if env.coroutine_stack.len() == 1 {
            // Environment root
            return;
        }

        unsafe {
            match (env.coroutine_stack.pop(), env.coroutine_stack.last()) {
                (Some(from_coro), Some(to_coro)) => {
                    env.switch_state = state;
                    Context::swap(&mut (& *from_coro).get_inner_mut().saved_context, &(& **to_coro).saved_context);
                },
                _ => unreachable!()
            }
        }
    }

    /// Yield the current running Coroutine with `Suspended` state
    #[inline]
    pub fn sched() {
        Coroutine::yield_now(State::Suspended)
    }

    /// Yield the current running Coroutine with `Blocked` state
    #[inline]
    pub fn block() {
        Coroutine::yield_now(State::Blocked)
    }

    /// Get a Handle to the current running Coroutine.
    ///
    /// It is unsafe because it is an undefined behavior if you resume a Coroutine
    /// in more than one native thread.
    #[inline]
    pub fn current() -> &'static Handle {
        Environment::current().coroutine_stack.last().map(|hdl| unsafe { (& **hdl) })
            .expect("Impossible happened! No current coroutine!")
    }

    #[inline(always)]
    fn state(&self) -> &Mutex<State> {
        &self.state
    }

    /// Get the name of the Coroutine
    #[inline(always)]
    pub fn name(&self) -> Option<&str> {
        self.name.as_ref().map(|s| &**s)
    }

    /// Determines whether the current Coroutine is unwinding because of panic.
    #[inline(always)]
    pub fn panicking(&self) -> bool {
        *self.state().lock() == State::Panicked
    }

    /// Determines whether the Coroutine is finished
    #[inline(always)]
    pub fn finished(&self) -> bool {
        *self.state().lock() == State::Finished
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix copy/paste error.<commit_after><|endoftext|>


<commit_before><commit_msg>Faster sorting on presorted inputs<commit_after><|endoftext|>


<commit_before><commit_msg>fix(doctests): mark doctests with `rust` to workaround a rustdoc bug<commit_after><|endoftext|>


<commit_before><commit_msg>cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>Add crate-level documentation.<commit_after><|endoftext|>


<commit_before><commit_msg>Count to 5.000.000 in 10 threads in `process()`<commit_after>use std::thread;

fn process() {
    let handles: Vec<_> = (0..10).map(|_| {
        thread::spawn(|| {
            let mut x = 0;
            for _ in (0..5_000_000) {
                x += 1
            }
        x
        })
    }).collect();

    for h in handles {
        println!("Thread finished with count={}",
        h.join().map_err(|_| "Could not join a thread!").unwrap());
    }
    println!("done!");
}
<|endoftext|>


<commit_before><commit_msg>Simplify annotation<commit_after><|endoftext|>


<commit_before><commit_msg>Clarify how InvalidInput differs from InvalidEvent.<commit_after><|endoftext|>


<commit_before><commit_msg>rust-rub work<commit_after><|endoftext|>


<commit_before><commit_msg>mpm: remove unused pkginfo<commit_after><|endoftext|>


<commit_before>use core::mem;

use redox::*;

use super::{XdrOps, XdrError, XdrResult};

pub struct MemOps {
    pos: usize,
    buffer: Vec<u8>,
}

impl XdrOps for MemOps {
    fn get_long(&mut self) -> XdrResult<usize> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &usize = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(*d)
        }
    }

    fn put_long(&mut self, l: usize) -> XdrResult<()> {
        Ok(())
    }

    fn get_i32(&mut self) -> XdrResult<i32> {
        Ok(0)
    }

    fn put_i32(&mut self, i: i32) -> XdrResult<()> {
        Ok(())
    }

    fn get_bytes(&mut self, bytes: &mut [u8]) -> XdrResult<()> {
        Ok(())
    }

    fn put_bytes(&mut self, bytes: &[u8]) -> XdrResult<()> {
        Ok(())
    }

    fn get_pos(&self) -> usize {
        self.pos
    }

    fn set_pos(&mut self, offset: usize) -> XdrResult<()> {
        Ok(())
    }

    fn destroy(&mut self) {
    }
}
<commit_msg>Whoops.. forgot big endian<commit_after>use core::mem;

use redox::*;

use super::{XdrOps, XdrError, XdrResult};

pub struct MemOps {
    pos: usize,
    buffer: Vec<u8>,
}

impl XdrOps for MemOps {
    fn get_long(&mut self) -> XdrResult<usize> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &usize = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(usize::from_be(*d))
        }
    }

    fn put_long(&mut self, l: usize) -> XdrResult<()> {
        Ok(())
    }

    fn get_i32(&mut self) -> XdrResult<i32> {
        Ok(0)
    }

    fn put_i32(&mut self, i: i32) -> XdrResult<()> {
        Ok(())
    }

    fn get_bytes(&mut self, bytes: &mut [u8]) -> XdrResult<()> {
        Ok(())
    }

    fn put_bytes(&mut self, bytes: &[u8]) -> XdrResult<()> {
        Ok(())
    }

    fn get_pos(&self) -> usize {
        self.pos
    }

    fn set_pos(&mut self, offset: usize) -> XdrResult<()> {
        Ok(())
    }

    fn destroy(&mut self) {
    }
}
<|endoftext|>


<commit_before><commit_msg>Integration test for translucence<commit_after>#![cfg(test)]

extern crate ferrous_threads;

use ferrous_threads::thread_pool::ThreadPool;

use std::sync::atomic::{Ordering, AtomicBool};
use std::sync::{Arc};
use std::process::{Stdio, Command};
use std::net::UdpSocket;

const ADDR: &'static str = "localhost:60000";

#[test]
fn main_metrics_test() {
    let mut pool = ThreadPool::new(2, 2);
    let test_thread = pool.thread().unwrap_or_else(|e| panic!("{}", e));
    let timer_thread = pool.thread().unwrap_or_else(|e| panic!("{}", e));
    let reg_interval = 10;

    let done = Arc::new(AtomicBool::new(false));
    let test_done = done.clone();
    let timer_done = done.clone();

    let passed = Arc::new(AtomicBool::new(false));
    let test_passed = passed.clone();

    let test_addr = ADDR.clone();

    test_thread.start(Box::new(move || {
        let mut buf = [0; 65536];
        let socket = UdpSocket::bind(test_addr)
            .unwrap_or_else(|e| panic!("{}", e));

        let res = socket.recv_from(&mut buf);
        assert!(res.is_ok());

        test_done.store(true, Ordering::SeqCst);
        test_passed.store(true, Ordering::SeqCst);
    })).unwrap_or_else(|e| panic!("{}", e));

    let child = Command::new("cargo")
        .arg("run")
        .arg(ADDR)
        .stderr(Stdio::null()) // Ignore cargo "unknown error" output
        .spawn().unwrap_or_else(|e| panic!("{}", e));

    timer_thread.start(Box::new(move || {
        ::std::thread::sleep_ms(reg_interval * 1000);
        timer_done.store(true, Ordering::SeqCst);
    })).unwrap_or_else(|e| panic!("{}", e));

    loop {
        if done.load(Ordering::SeqCst) {
            break
        }

        ::std::thread::yield_now();
    }

    let pid = child.id();
    let _output = Command::new("pkill")
        .arg("-TERM")
        .arg("-P")
        .arg(format!("{}", pid))
        .output().unwrap_or_else(|e| panic!("{}", e));
    assert!(passed.load(Ordering::SeqCst));
}
<|endoftext|>


<commit_before><commit_msg>Fix quick error macro<commit_after><|endoftext|>


<commit_before>
import std::vec;
import std::str;
import std::option;
import std::option::some;
import std::option::none;
import syntax::ast;
import syntax::parse::token;
import syntax::parse::parser::parser;
import syntax::parse::parser::new_parser;
import syntax::parse::parser::parse_inner_attrs_and_next;
import syntax::parse::parser::parse_mod_items;

export eval_crate_directives_to_mod;
export mode_parse;

tag eval_mode { mode_depend; mode_parse; }

type ctx =
    @rec(parser p,
         eval_mode mode,
         mutable vec[str] deps,
         parser::parse_sess sess,
         mutable uint chpos,
         ast::crate_cfg cfg);

fn eval_crate_directives(ctx cx, vec[@ast::crate_directive] cdirs,
                         str prefix, &mutable vec[@ast::view_item] view_items,
                         &mutable vec[@ast::item] items) {
    for (@ast::crate_directive sub_cdir in cdirs) {
        eval_crate_directive(cx, sub_cdir, prefix, view_items, items);
    }
}

fn eval_crate_directives_to_mod(ctx cx,
                                vec[@ast::crate_directive] cdirs, str prefix)
   -> ast::_mod {
    let vec[@ast::view_item] view_items = [];
    let vec[@ast::item] items = [];
    eval_crate_directives(cx, cdirs, prefix, view_items, items);
    ret rec(view_items=view_items, items=items);
}

fn eval_crate_directive_block(ctx cx, &ast::block blk, str prefix,
                              &mutable vec[@ast::view_item] view_items,
                              &mutable vec[@ast::item] items) {
    for (@ast::stmt s in blk.node.stmts) {
        alt (s.node) {
            case (ast::stmt_crate_directive(?cdir)) {
                eval_crate_directive(cx, cdir, prefix, view_items, items);
            }
            case (_) {
                codemap::emit_warning
                   (some(s.span), "unsupported stmt in crate-directive block",
                    cx.sess.cm);
            }
        }
    }
}

fn eval_crate_directive(ctx cx, @ast::crate_directive cdir, str prefix,
                        &mutable vec[@ast::view_item] view_items,
                        &mutable vec[@ast::item] items) {
    alt (cdir.node) {
        case (ast::cdir_src_mod(?id, ?file_opt, ?attrs)) {
            auto file_path = id + ".rs";
            alt (file_opt) {
                case (some(?f)) { file_path = f; }
                case (none) { }
            }
            auto full_path = if (std::fs::path_is_absolute(file_path)) {
                file_path
            } else {
                prefix + std::fs::path_sep() + file_path
            };
            if (cx.mode == mode_depend) { cx.deps += [full_path]; ret; }
            auto p0 =
                new_parser(cx.sess, cx.cfg, full_path, cx.chpos);
            auto inner_attrs = parse_inner_attrs_and_next(p0);
            auto mod_attrs = attrs + inner_attrs._0;
            auto first_item_outer_attrs = inner_attrs._1;
            auto m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs);

            auto i = syntax::parse::parser::mk_item
                (p0, cdir.span.lo, cdir.span.hi, id, ast::item_mod(m0),
                 mod_attrs);
            // Thread defids and chpos through the parsers
            cx.chpos = p0.get_chpos();
            vec::push[@ast::item](items, i);
        }
        case (ast::cdir_dir_mod(?id, ?dir_opt, ?cdirs, ?attrs)) {
            auto path = id;
            alt (dir_opt) { case (some(?d)) { path = d; } case (none) { } }
            auto full_path = if (std::fs::path_is_absolute(path)) {
                path
            } else {
                prefix + std::fs::path_sep() + path
            };
            auto m0 = eval_crate_directives_to_mod(cx, cdirs, full_path);
            auto i = @rec(ident=id,
                          attrs=attrs,
                          id=cx.sess.next_id,
                          node=ast::item_mod(m0),
                          span=cdir.span);
            cx.sess.next_id += 1;
            vec::push[@ast::item](items, i);
        }
        case (ast::cdir_view_item(?vi)) {
            vec::push[@ast::view_item](view_items, vi);
        }
        case (ast::cdir_syntax(?pth)) { }
        case (ast::cdir_auth(?pth, ?eff)) { }
    }
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Remove unused eval function. Issue #604<commit_after>
import std::vec;
import std::str;
import std::option;
import std::option::some;
import std::option::none;
import syntax::ast;
import syntax::parse::token;
import syntax::parse::parser::parser;
import syntax::parse::parser::new_parser;
import syntax::parse::parser::parse_inner_attrs_and_next;
import syntax::parse::parser::parse_mod_items;

export eval_crate_directives_to_mod;
export mode_parse;

tag eval_mode { mode_depend; mode_parse; }

type ctx =
    @rec(parser p,
         eval_mode mode,
         mutable vec[str] deps,
         parser::parse_sess sess,
         mutable uint chpos,
         ast::crate_cfg cfg);

fn eval_crate_directives(ctx cx, vec[@ast::crate_directive] cdirs,
                         str prefix, &mutable vec[@ast::view_item] view_items,
                         &mutable vec[@ast::item] items) {
    for (@ast::crate_directive sub_cdir in cdirs) {
        eval_crate_directive(cx, sub_cdir, prefix, view_items, items);
    }
}

fn eval_crate_directives_to_mod(ctx cx,
                                vec[@ast::crate_directive] cdirs, str prefix)
   -> ast::_mod {
    let vec[@ast::view_item] view_items = [];
    let vec[@ast::item] items = [];
    eval_crate_directives(cx, cdirs, prefix, view_items, items);
    ret rec(view_items=view_items, items=items);
}

fn eval_crate_directive(ctx cx, @ast::crate_directive cdir, str prefix,
                        &mutable vec[@ast::view_item] view_items,
                        &mutable vec[@ast::item] items) {
    alt (cdir.node) {
        case (ast::cdir_src_mod(?id, ?file_opt, ?attrs)) {
            auto file_path = id + ".rs";
            alt (file_opt) {
                case (some(?f)) { file_path = f; }
                case (none) { }
            }
            auto full_path = if (std::fs::path_is_absolute(file_path)) {
                file_path
            } else {
                prefix + std::fs::path_sep() + file_path
            };
            if (cx.mode == mode_depend) { cx.deps += [full_path]; ret; }
            auto p0 =
                new_parser(cx.sess, cx.cfg, full_path, cx.chpos);
            auto inner_attrs = parse_inner_attrs_and_next(p0);
            auto mod_attrs = attrs + inner_attrs._0;
            auto first_item_outer_attrs = inner_attrs._1;
            auto m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs);

            auto i = syntax::parse::parser::mk_item
                (p0, cdir.span.lo, cdir.span.hi, id, ast::item_mod(m0),
                 mod_attrs);
            // Thread defids and chpos through the parsers
            cx.chpos = p0.get_chpos();
            vec::push[@ast::item](items, i);
        }
        case (ast::cdir_dir_mod(?id, ?dir_opt, ?cdirs, ?attrs)) {
            auto path = id;
            alt (dir_opt) { case (some(?d)) { path = d; } case (none) { } }
            auto full_path = if (std::fs::path_is_absolute(path)) {
                path
            } else {
                prefix + std::fs::path_sep() + path
            };
            auto m0 = eval_crate_directives_to_mod(cx, cdirs, full_path);
            auto i = @rec(ident=id,
                          attrs=attrs,
                          id=cx.sess.next_id,
                          node=ast::item_mod(m0),
                          span=cdir.span);
            cx.sess.next_id += 1;
            vec::push[@ast::item](items, i);
        }
        case (ast::cdir_view_item(?vi)) {
            vec::push[@ast::view_item](view_items, vi);
        }
        case (ast::cdir_syntax(?pth)) { }
        case (ast::cdir_auth(?pth, ?eff)) { }
    }
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc_data_structures::bit_set::BitSet;

use super::*;

/// Preorder traversal of a graph.
///
/// Preorder traversal is when each node is visited before an of it's
/// successors
///
/// ```text
///
///         A
///        / \
///       /   \
///      B     C
///       \   /
///        \ /
///         D
/// ```
///
/// A preorder traversal of this graph is either `A B D C` or `A C D B`
#[derive(Clone)]
pub struct Preorder<'a, 'tcx: 'a> {
    mir: &'a Mir<'tcx>,
    visited: BitSet<BasicBlock>,
    worklist: Vec<BasicBlock>,
}

impl<'a, 'tcx> Preorder<'a, 'tcx> {
    pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
        let worklist = vec![root];

        Preorder {
            mir,
            visited: BitSet::new_empty(mir.basic_blocks().len()),
            worklist,
        }
    }
}

pub fn preorder<'a, 'tcx>(mir: &'a Mir<'tcx>) -> Preorder<'a, 'tcx> {
    Preorder::new(mir, START_BLOCK)
}

impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);

    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
        while let Some(idx) = self.worklist.pop() {
            if !self.visited.insert(idx) {
                continue;
            }

            let data = &self.mir[idx];

            if let Some(ref term) = data.terminator {
                self.worklist.extend(term.successors());
            }

            return Some((idx, data));
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // All the blocks, minus the number of blocks we've visited.
        let remaining = self.mir.basic_blocks().len() - self.visited.count();

        // We will visit all remaining blocks exactly once.
        (remaining, Some(remaining))
    }
}

impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}

/// Postorder traversal of a graph.
///
/// Postorder traversal is when each node is visited after all of it's
/// successors, except when the successor is only reachable by a back-edge
///
///
/// ```text
///
///         A
///        / \
///       /   \
///      B     C
///       \   /
///        \ /
///         D
/// ```
///
/// A Postorder traversal of this graph is `D B C A` or `D C B A`
pub struct Postorder<'a, 'tcx: 'a> {
    mir: &'a Mir<'tcx>,
    visited: BitSet<BasicBlock>,
    visit_stack: Vec<(BasicBlock, Successors<'a>)>
}

impl<'a, 'tcx> Postorder<'a, 'tcx> {
    pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
        let mut po = Postorder {
            mir,
            visited: BitSet::new_empty(mir.basic_blocks().len()),
            visit_stack: Vec::new()
        };

        let data = &po.mir[root];

        if let Some(ref term) = data.terminator {
            po.visited.insert(root);
            po.visit_stack.push((root, term.successors()));
            po.traverse_successor();
        }

        po
    }

    fn traverse_successor(&mut self) {
        // This is quite a complex loop due to 1. the borrow checker not liking it much
        // and 2. what exactly is going on is not clear
        //
        // It does the actual traversal of the graph, while the `next` method on the iterator
        // just pops off of the stack. `visit_stack` is a stack containing pairs of nodes and
        // iterators over the sucessors of those nodes. Each iteration attempts to get the next
        // node from the top of the stack, then pushes that node and an iterator over the
        // successors to the top of the stack. This loop only grows `visit_stack`, stopping when
        // we reach a child that has no children that we haven't already visited.
        //
        // For a graph that looks like this:
        //
        //         A
        //        / \
        //       /   \
        //      B     C
        //      |     |
        //      |     |
        //      D     |
        //       \   /
        //        \ /
        //         E
        //
        // The state of the stack starts out with just the root node (`A` in this case);
        //     [(A, [B, C])]
        //
        // When the first call to `traverse_sucessor` happens, the following happens:
        //
        //     [(B, [D]),  // `B` taken from the successors of `A`, pushed to the
        //                 // top of the stack along with the successors of `B`
        //      (A, [C])]
        //
        //     [(D, [E]),  // `D` taken from successors of `B`, pushed to stack
        //      (B, []),
        //      (A, [C])]
        //
        //     [(E, []),   // `E` taken from successors of `D`, pushed to stack
        //      (D, []),
        //      (B, []),
        //      (A, [C])]
        //
        // Now that the top of the stack has no successors we can traverse, each item will
        // be popped off during iteration until we get back to `A`. This yields [E, D, B].
        //
        // When we yield `B` and call `traverse_successor`, we push `C` to the stack, but
        // since we've already visited `E`, that child isn't added to the stack. The last
        // two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
        loop {
            let bb = if let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() {
                if let Some(&bb) = iter.next() {
                    bb
                } else {
                    break;
                }
            } else {
                break;
            };

            if self.visited.insert(bb) {
                if let Some(term) = &self.mir[bb].terminator {
                    self.visit_stack.push((bb, term.successors()));
                }
            }
        }
    }
}

pub fn postorder<'a, 'tcx>(mir: &'a Mir<'tcx>) -> Postorder<'a, 'tcx> {
    Postorder::new(mir, START_BLOCK)
}

impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);

    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
        let next = self.visit_stack.pop();
        if next.is_some() {
            self.traverse_successor();
        }

        next.map(|(bb, _)| (bb, &self.mir[bb]))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // All the blocks, minus the number of blocks we've visited.
        let remaining = self.mir.basic_blocks().len() - self.visited.count();

        // We will visit all remaining blocks exactly once.
        (remaining, Some(remaining))
    }
}

impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {}

/// Reverse postorder traversal of a graph
///
/// Reverse postorder is the reverse order of a postorder traversal.
/// This is different to a preorder traversal and represents a natural
/// linearization of control-flow.
///
/// ```text
///
///         A
///        / \
///       /   \
///      B     C
///       \   /
///        \ /
///         D
/// ```
///
/// A reverse postorder traversal of this graph is either `A B C D` or `A C B D`
/// Note that for a graph containing no loops (i.e. A DAG), this is equivalent to
/// a topological sort.
///
/// Construction of a `ReversePostorder` traversal requires doing a full
/// postorder traversal of the graph, therefore this traversal should be
/// constructed as few times as possible. Use the `reset` method to be able
/// to re-use the traversal
#[derive(Clone)]
pub struct ReversePostorder<'a, 'tcx: 'a> {
    mir: &'a Mir<'tcx>,
    blocks: Vec<BasicBlock>,
    idx: usize
}

impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
    pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
        let blocks : Vec<_> = Postorder::new(mir, root).map(|(bb, _)| bb).collect();

        let len = blocks.len();

        ReversePostorder {
            mir,
            blocks,
            idx: len
        }
    }

    pub fn reset(&mut self) {
        self.idx = self.blocks.len();
    }
}

pub fn reverse_postorder<'a, 'tcx>(mir: &'a Mir<'tcx>) -> ReversePostorder<'a, 'tcx> {
    ReversePostorder::new(mir, START_BLOCK)
}

impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);

    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
        if self.idx == 0 { return None; }
        self.idx -= 1;

        self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb]))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.idx, Some(self.idx))
    }
}

impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {}
<commit_msg>Rollup merge of #55271 - sinkuu:traversal_iter, r=matthewjasper<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc_data_structures::bit_set::BitSet;

use super::*;

/// Preorder traversal of a graph.
///
/// Preorder traversal is when each node is visited before an of it's
/// successors
///
/// ```text
///
///         A
///        / \
///       /   \
///      B     C
///       \   /
///        \ /
///         D
/// ```
///
/// A preorder traversal of this graph is either `A B D C` or `A C D B`
#[derive(Clone)]
pub struct Preorder<'a, 'tcx: 'a> {
    mir: &'a Mir<'tcx>,
    visited: BitSet<BasicBlock>,
    worklist: Vec<BasicBlock>,
    root_is_start_block: bool,
}

impl<'a, 'tcx> Preorder<'a, 'tcx> {
    pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
        let worklist = vec![root];

        Preorder {
            mir,
            visited: BitSet::new_empty(mir.basic_blocks().len()),
            worklist,
            root_is_start_block: root == START_BLOCK,
        }
    }
}

pub fn preorder<'a, 'tcx>(mir: &'a Mir<'tcx>) -> Preorder<'a, 'tcx> {
    Preorder::new(mir, START_BLOCK)
}

impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);

    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
        while let Some(idx) = self.worklist.pop() {
            if !self.visited.insert(idx) {
                continue;
            }

            let data = &self.mir[idx];

            if let Some(ref term) = data.terminator {
                self.worklist.extend(term.successors());
            }

            return Some((idx, data));
        }

        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // All the blocks, minus the number of blocks we've visited.
        let upper = self.mir.basic_blocks().len() - self.visited.count();

        let lower = if self.root_is_start_block {
            // We will visit all remaining blocks exactly once.
            upper
        } else {
            self.worklist.len()
        };

        (lower, Some(upper))
    }
}

/// Postorder traversal of a graph.
///
/// Postorder traversal is when each node is visited after all of it's
/// successors, except when the successor is only reachable by a back-edge
///
///
/// ```text
///
///         A
///        / \
///       /   \
///      B     C
///       \   /
///        \ /
///         D
/// ```
///
/// A Postorder traversal of this graph is `D B C A` or `D C B A`
pub struct Postorder<'a, 'tcx: 'a> {
    mir: &'a Mir<'tcx>,
    visited: BitSet<BasicBlock>,
    visit_stack: Vec<(BasicBlock, Successors<'a>)>,
    root_is_start_block: bool,
}

impl<'a, 'tcx> Postorder<'a, 'tcx> {
    pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
        let mut po = Postorder {
            mir,
            visited: BitSet::new_empty(mir.basic_blocks().len()),
            visit_stack: Vec::new(),
            root_is_start_block: root == START_BLOCK,
        };

        let data = &po.mir[root];

        if let Some(ref term) = data.terminator {
            po.visited.insert(root);
            po.visit_stack.push((root, term.successors()));
            po.traverse_successor();
        }

        po
    }

    fn traverse_successor(&mut self) {
        // This is quite a complex loop due to 1. the borrow checker not liking it much
        // and 2. what exactly is going on is not clear
        //
        // It does the actual traversal of the graph, while the `next` method on the iterator
        // just pops off of the stack. `visit_stack` is a stack containing pairs of nodes and
        // iterators over the sucessors of those nodes. Each iteration attempts to get the next
        // node from the top of the stack, then pushes that node and an iterator over the
        // successors to the top of the stack. This loop only grows `visit_stack`, stopping when
        // we reach a child that has no children that we haven't already visited.
        //
        // For a graph that looks like this:
        //
        //         A
        //        / \
        //       /   \
        //      B     C
        //      |     |
        //      |     |
        //      D     |
        //       \   /
        //        \ /
        //         E
        //
        // The state of the stack starts out with just the root node (`A` in this case);
        //     [(A, [B, C])]
        //
        // When the first call to `traverse_sucessor` happens, the following happens:
        //
        //     [(B, [D]),  // `B` taken from the successors of `A`, pushed to the
        //                 // top of the stack along with the successors of `B`
        //      (A, [C])]
        //
        //     [(D, [E]),  // `D` taken from successors of `B`, pushed to stack
        //      (B, []),
        //      (A, [C])]
        //
        //     [(E, []),   // `E` taken from successors of `D`, pushed to stack
        //      (D, []),
        //      (B, []),
        //      (A, [C])]
        //
        // Now that the top of the stack has no successors we can traverse, each item will
        // be popped off during iteration until we get back to `A`. This yields [E, D, B].
        //
        // When we yield `B` and call `traverse_successor`, we push `C` to the stack, but
        // since we've already visited `E`, that child isn't added to the stack. The last
        // two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
        loop {
            let bb = if let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() {
                if let Some(&bb) = iter.next() {
                    bb
                } else {
                    break;
                }
            } else {
                break;
            };

            if self.visited.insert(bb) {
                if let Some(term) = &self.mir[bb].terminator {
                    self.visit_stack.push((bb, term.successors()));
                }
            }
        }
    }
}

pub fn postorder<'a, 'tcx>(mir: &'a Mir<'tcx>) -> Postorder<'a, 'tcx> {
    Postorder::new(mir, START_BLOCK)
}

impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);

    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
        let next = self.visit_stack.pop();
        if next.is_some() {
            self.traverse_successor();
        }

        next.map(|(bb, _)| (bb, &self.mir[bb]))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // All the blocks, minus the number of blocks we've visited.
        let upper = self.mir.basic_blocks().len() - self.visited.count();

        let lower = if self.root_is_start_block {
            // We will visit all remaining blocks exactly once.
            upper
        } else {
            self.visit_stack.len()
        };

        (lower, Some(upper))
    }
}

/// Reverse postorder traversal of a graph
///
/// Reverse postorder is the reverse order of a postorder traversal.
/// This is different to a preorder traversal and represents a natural
/// linearization of control-flow.
///
/// ```text
///
///         A
///        / \
///       /   \
///      B     C
///       \   /
///        \ /
///         D
/// ```
///
/// A reverse postorder traversal of this graph is either `A B C D` or `A C B D`
/// Note that for a graph containing no loops (i.e. A DAG), this is equivalent to
/// a topological sort.
///
/// Construction of a `ReversePostorder` traversal requires doing a full
/// postorder traversal of the graph, therefore this traversal should be
/// constructed as few times as possible. Use the `reset` method to be able
/// to re-use the traversal
#[derive(Clone)]
pub struct ReversePostorder<'a, 'tcx: 'a> {
    mir: &'a Mir<'tcx>,
    blocks: Vec<BasicBlock>,
    idx: usize
}

impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
    pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
        let blocks : Vec<_> = Postorder::new(mir, root).map(|(bb, _)| bb).collect();

        let len = blocks.len();

        ReversePostorder {
            mir,
            blocks,
            idx: len
        }
    }

    pub fn reset(&mut self) {
        self.idx = self.blocks.len();
    }
}

pub fn reverse_postorder<'a, 'tcx>(mir: &'a Mir<'tcx>) -> ReversePostorder<'a, 'tcx> {
    ReversePostorder::new(mir, START_BLOCK)
}

impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);

    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
        if self.idx == 0 { return None; }
        self.idx -= 1;

        self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb]))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.idx, Some(self.idx))
    }
}

impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {}
<|endoftext|>


<commit_before><commit_msg>Fix queue messages on linux<commit_after><|endoftext|>


<commit_before>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::Target;

pub fn target() -> Target {
    let mut base = super::openbsd_base::opts();
    base.pre_link_args.push("-m64".to_string());

    Target {
        llvm_target: "x86_64-unknown-openbsd".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "64".to_string(),
        arch: "x86_64".to_string(),
        target_os: "openbsd".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        options: base,
    }
}
<commit_msg>Auto merge of #31727 - semarie:openbsd-llvm-cpu, r=alexcrichton<commit_after>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::Target;

pub fn target() -> Target {
    let mut base = super::openbsd_base::opts();
    base.cpu = "x86-64".to_string();
    base.pre_link_args.push("-m64".to_string());

    Target {
        llvm_target: "x86_64-unknown-openbsd".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "64".to_string(),
        arch: "x86_64".to_string(),
        target_os: "openbsd".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        options: base,
    }
}
<|endoftext|>


<commit_before><commit_msg>libimagdiary: Replace read with typed read<commit_after><|endoftext|>


<commit_before><commit_msg>Add a compile-fail test for qualification lint<commit_after>// 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.

#[deny(unnecessary_qualification)];

mod foo {
    pub fn bar() {}
}

fn main() {
    use foo::bar;
    foo::bar(); //~ ERROR: unnecessary qualification
}
<|endoftext|>


<commit_before><commit_msg>Add a test<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![deny(dead_code)]

enum Foo {
    A,
    B,
}

pub fn main() {
    match Foo::A {
        Foo::A | Foo::B => Foo::B
    };
}
<|endoftext|>


<commit_before><commit_msg>Sanity-check the code examples that appear in the object system docs.<commit_after>// Sanity-check the code examples that appear in the object system
// documentation.

fn main() {

    // Ref.Item.Obj
    obj counter(state: @mutable int) {
        fn incr() {
            *state += 1;
            }
        fn get() -> int {
            ret *state;
            }
        }

    let c: counter = counter(@mutable 1);

    c.incr();
    c.incr();
    assert c.get() == 3;

    obj my_obj() {
        fn get() -> int {
            ret 3;
        }
        fn foo() -> int{
            let c = self.get();
            ret c + 2; // returns 5
        }
    }

    let o = my_obj();
    assert o.foo() == 5;

    // Ref.Type.Obj
    type taker = obj {
        fn take(int);
    };

    obj adder(x: @mutable int) {
        fn take(y: int) {
            *x += y;
        }
    }

    obj sender(c: chan[int]) {
        fn take(z: int) {
            c <| z;
        }
    }

    fn give_ints(t: taker) {
        t.take(1);
        t.take(2);
        t.take(3);
    }

    let p: port[int] = port();

    let t1: taker = adder(@mutable 0);
    let t2: taker = sender(chan(p));

    give_ints(t1);
    give_ints(t2);
}

<|endoftext|>


<commit_before><commit_msg>Add test for issue-48638<commit_after>// check-pass

pub trait D {}
pub struct DT;
impl D for DT {}

pub trait A<R: D>: Sized {
    type AS;
}

pub struct As<R: D>(R);

pub struct AT;
impl<R: D> A<R> for AT {
    type AS = As<R>;
}

#[repr(packed)]
struct S(<AT as A<DT>>::AS);

fn main() {}
<|endoftext|>


<commit_before>// Tuples can be used as function arguments and as return values
fn reverse(pair: (int, bool)) -> (bool, int) {
    // `let` can be used to bind the members of a tuple to variables
    let (integer, boolean) = pair;

    (boolean, integer)
}

fn main() {
    // A tuple with a bunch of different types
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using the `valN` methods
    println!("long tuple first value: {}", long_tuple.val0());
    println!("long tuple second value: {}", long_tuple.val1());

    // Tuples can be tuple members
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

    // Tuples are printable
    println!("tuple of tuples: {}", tuple_of_tuples);

    let pair = (1, true);
    println!("pair is {}", pair);

    println!("the reversed pair is {}", reverse(pair));

    // To create one element tuples, the comma is required to tell them apart
    // from a literal surrounded by parentheses
    println!("one element tuple: {}", (5u,))
    println!("just an integer: {}", (5u))
}
<commit_msg>Update tuples.rs<commit_after>// Tuples can be used as function arguments and as return values
fn reverse(pair: (int, bool)) -> (bool, int) {
    // `let` can be used to bind the members of a tuple to variables
    let (integer, boolean) = pair;

    (boolean, integer)
}

fn main() {
    // A tuple with a bunch of different types
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using the `valN` methods
    println!("long tuple first value: {}", long_tuple.val0());
    println!("long tuple second value: {}", long_tuple.val1());

    // Tuples can be tuple members
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

    // Tuples are printable
    println!("tuple of tuples: {}", tuple_of_tuples);

    let pair = (1, true);
    println!("pair is {}", pair);

    println!("the reversed pair is {}", reverse(pair));

    // To create one element tuples, the comma is required to tell them apart
    // from a literal surrounded by parentheses
    println!("one element tuple: {}", (5u,));
    println!("just an integer: {}", (5u));
}
<|endoftext|>


<commit_before><commit_msg>Create a filter for the data<commit_after>extern crate simple_csv;

use std::fs::File;
use std::io::BufReader;
use std::str::FromStr;
use simple_csv::{SimpleCsvWriter, SimpleCsvReader};

const THRESHOLD: f64 = 500f64;

fn main(){
    let f = File::open("assets/brightness.csv").unwrap();
    let buf = BufReader::new(f);
    let reader = SimpleCsvReader::new(buf);

    let raw: Vec<(f64, f64)> = reader
        .map (|r| r.unwrap())
        .map(data)
        .collect();

    let mut result: Vec<(f64, f64)> = vec!();
    let mut current: Option<(f64, f64)> = None;
    for candidate in raw {
        match current {
            Some(previous) => {
                if (candidate.1 - previous.1).abs() <= THRESHOLD {
                    result.push(previous);
                    current = Some(candidate);
                }
            }

            None => {
                current = Some(candidate)
            }
        }

    }

    let o = File::create("assets/filter.csv").unwrap();
    let mut writer = SimpleCsvWriter::new(o);

    for (time, filtered) in result {
        writer.write(
            &vec!(time.to_string(), filtered.to_string())
        ).unwrap();
    }
}

fn data(row: Vec<String>) -> (f64, f64) {
    let iter = row.iter();

    let raw: Vec<f64> = iter
        .map(|s| f64::from_str(s).unwrap())
        .collect();

    (raw[0], raw[2])
}
<|endoftext|>


<commit_before><commit_msg>add an all widget example<commit_after>extern crate gui;

use gui::components::{Button, ButtonEvent, Row, Label};

fn main(){
    gui::Window::new("test",640,480).show(|ctx|{
        //TODO: do something;
        /*gui!(ctx,//macro as syntactic shugar for the code down there
            1: Button("Hallo Welt") => {
                ButtonEvent::Click => println!("Button1 geclickt");
            },
            2: Button("Tschpss Welt") => {
                ButtonEvent::Click => println!("Button2 geclickt")
            },
            3: Row(){ //child nodes können mit einfachen geschweiften Klammern eingeleited werden
                1: Label("Hallo"),
                2: Label("Ich"),
                3: Label("Heiße"),
                4: Label("Simon"),
            },
            4: Group(){
                1: Line(0,20, 0, )
            }
        )*/

        ctx.add(1, &Button::new("Hallo Welt".to_string(), 100.0,20.0), Some(|event|{
            match event{
                ButtonEvent::Click => println!("Button1 geclickt"),
                _ => {}
            }
        }));
        ctx.go_to(0.0,60.0);
        ctx.add(2, &Button::new("Tschüss Welt".to_string(), 100.0,20.0), Some(|event|{
            match event{
                ButtonEvent::Click => println!("Button2 geclickt"),
                _ => {}
            }
        }));
        ctx.go_to(0.0,120.0);
        ctx.add(3, &Label::new("test label".to_string()), None);
    });
}
<|endoftext|>


<commit_before>// 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.

use std::old_io::{Command, IoError, OtherIoError};
use target::TargetOptions;

use self::Arch::*;

#[allow(non_camel_case_types)]
#[derive(Copy)]
pub enum Arch {
    Armv7,
    Armv7s,
    Arm64,
    I386,
    X86_64
}

impl Arch {
    pub fn to_string(&self) -> &'static str {
        match self {
            &Armv7 => "armv7",
            &Armv7s => "armv7s",
            &Arm64 => "arm64",
            &I386 => "i386",
            &X86_64 => "x86_64"
        }
    }
}

pub fn get_sdk_root(sdk_name: &str) -> String {
    let res = Command::new("xcrun")
                      .arg("--show-sdk-path")
                      .arg("-sdk")
                      .arg(sdk_name)
                      .spawn()
                      .and_then(|c| c.wait_with_output())
                      .and_then(|output| {
                          if output.status.success() {
                              Ok(String::from_utf8(output.output).unwrap())
                          } else {
                              Err(IoError {
                                  kind: OtherIoError,
                                  desc: "process exit with error",
                                  detail: String::from_utf8(output.error).ok()})
                          }
                      });

    match res {
        Ok(output) => output.trim().to_string(),
        Err(e) => panic!("failed to get {} SDK path: {}", sdk_name, e)
    }
}

fn pre_link_args(arch: Arch) -> Vec<String> {
    let sdk_name = match arch {
        Armv7 | Armv7s | Arm64 => "iphoneos",
        I386 | X86_64 => "iphonesimulator"
    };

    let arch_name = arch.to_string();

    vec!["-arch".to_string(), arch_name.to_string(),
         "-Wl,-syslibroot".to_string(), get_sdk_root(sdk_name)]
}

fn target_cpu(arch: Arch) -> String {
    match arch {
        X86_64 => "x86-64",
        _ => "generic",
    }.to_string()
}

pub fn opts(arch: Arch) -> TargetOptions {
    TargetOptions {
        cpu: target_cpu(arch),
        dynamic_linking: false,
        executables: true,
        // Although there is an experimental implementation of LLVM which
        // supports SS on armv7 it wasn't approved by Apple, see:
        // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
        // It looks like it might be never accepted to upstream LLVM.
        //
        // SS might be also enabled on Arm64 as it has builtin support in LLVM
        // but I haven't tested it through yet
        morestack: false,
        pre_link_args: pre_link_args(arch),
        .. super::apple_base::opts()
    }
}
<commit_msg>Rollup merge of #22229 - vhbit:ios-default-cpus, r=alexcrichton<commit_after>// 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.

use std::old_io::{Command, IoError, OtherIoError};
use target::TargetOptions;

use self::Arch::*;

#[allow(non_camel_case_types)]
#[derive(Copy)]
pub enum Arch {
    Armv7,
    Armv7s,
    Arm64,
    I386,
    X86_64
}

impl Arch {
    pub fn to_string(&self) -> &'static str {
        match self {
            &Armv7 => "armv7",
            &Armv7s => "armv7s",
            &Arm64 => "arm64",
            &I386 => "i386",
            &X86_64 => "x86_64"
        }
    }
}

pub fn get_sdk_root(sdk_name: &str) -> String {
    let res = Command::new("xcrun")
                      .arg("--show-sdk-path")
                      .arg("-sdk")
                      .arg(sdk_name)
                      .spawn()
                      .and_then(|c| c.wait_with_output())
                      .and_then(|output| {
                          if output.status.success() {
                              Ok(String::from_utf8(output.output).unwrap())
                          } else {
                              Err(IoError {
                                  kind: OtherIoError,
                                  desc: "process exit with error",
                                  detail: String::from_utf8(output.error).ok()})
                          }
                      });

    match res {
        Ok(output) => output.trim().to_string(),
        Err(e) => panic!("failed to get {} SDK path: {}", sdk_name, e)
    }
}

fn pre_link_args(arch: Arch) -> Vec<String> {
    let sdk_name = match arch {
        Armv7 | Armv7s | Arm64 => "iphoneos",
        I386 | X86_64 => "iphonesimulator"
    };

    let arch_name = arch.to_string();

    vec!["-arch".to_string(), arch_name.to_string(),
         "-Wl,-syslibroot".to_string(), get_sdk_root(sdk_name)]
}

fn target_cpu(arch: Arch) -> String {
    match arch {
        Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
        Armv7s => "cortex-a9",
        Arm64 => "cyclone",
        I386 => "generic",
        X86_64 => "x86-64",
    }.to_string()
}

pub fn opts(arch: Arch) -> TargetOptions {
    TargetOptions {
        cpu: target_cpu(arch),
        dynamic_linking: false,
        executables: true,
        // Although there is an experimental implementation of LLVM which
        // supports SS on armv7 it wasn't approved by Apple, see:
        // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
        // It looks like it might be never accepted to upstream LLVM.
        //
        // SS might be also enabled on Arm64 as it has builtin support in LLVM
        // but I haven't tested it through yet
        morestack: false,
        pre_link_args: pre_link_args(arch),
        .. super::apple_base::opts()
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix trace count space width<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: Remove (empty) Drop implementation for Store<commit_after><|endoftext|>


<commit_before><commit_msg>Fixes help command, makes it dynamically get group names<commit_after><|endoftext|>


<commit_before><commit_msg>Auto merge of #34252 - dsprenkels:issue-32364-test, r=eddyb<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -C no-prepopulate-passes

struct Foo;

impl Foo {
// CHECK: define internal x86_stdcallcc void @{{.*}}foo{{.*}}()
    #[inline(never)]
    pub extern "stdcall" fn foo<T>() {
    }
}

fn main() {
    Foo::foo::<Foo>();
}
<|endoftext|>


<commit_before><commit_msg>Added concurrent game window back-end<commit_after><|endoftext|>