<commit_before>use std::ffi::{OsString, OsStr};

use ops::{self, Compilation};
use util::{self, CargoTestError, Test, ProcessError};
use util::errors::CargoResult;
use core::Workspace;

pub struct TestOptions<'a> {
    pub compile_opts: ops::CompileOptions<'a>,
    pub no_run: bool,
    pub no_fail_fast: bool,
    pub only_doc: bool,
}

pub fn run_tests(ws: &Workspace,
                 options: &TestOptions,
                 test_args: &[String]) -> CargoResult<Option<CargoTestError>> {
    let compilation = compile_tests(ws, options)?;

    if options.no_run {
        return Ok(None)
    }
    let (test, mut errors) = if options.only_doc {
        assert!(options.compile_opts.filter.is_specific());
        run_doc_tests(options, test_args, &compilation)?
    } else {
        run_unit_tests(options, test_args, &compilation)?
    };

    // If we have an error and want to fail fast, return
    if !errors.is_empty() && !options.no_fail_fast {
        return Ok(Some(CargoTestError::new(test, errors)))
    }

    // If a specific test was requested or we're not running any tests at all,
    // don't run any doc tests.
    if options.compile_opts.filter.is_specific() {
        match errors.len() {
            0 => return Ok(None),
            _ => return Ok(Some(CargoTestError::new(test, errors)))
        }
    }

    let (doctest, docerrors) = run_doc_tests(options, test_args, &compilation)?;
    let test = if docerrors.is_empty() { test } else { doctest };
    errors.extend(docerrors);
    if errors.is_empty() {
        Ok(None)
    } else {
        Ok(Some(CargoTestError::new(test, errors)))
    }
}

pub fn run_benches(ws: &Workspace,
                   options: &TestOptions,
                   args: &[String]) -> CargoResult<Option<CargoTestError>> {
    let mut args = args.to_vec();
    args.push("--bench".to_string());
    let compilation = compile_tests(ws, options)?;

    if options.no_run {
        return Ok(None)
    }
    let (test, errors) = run_unit_tests(options, &args, &compilation)?;
    match errors.len() {
        0 => Ok(None),
        _ => Ok(Some(CargoTestError::new(test, errors))),
    }
}

fn compile_tests<'a>(ws: &Workspace<'a>,
                     options: &TestOptions<'a>)
                     -> CargoResult<Compilation<'a>> {
    let mut compilation = ops::compile(ws, &options.compile_opts)?;
    compilation.tests.sort_by(|a, b| {
        (a.0.package_id(), &a.1, &a.2).cmp(&(b.0.package_id(), &b.1, &b.2))
    });
    Ok(compilation)
}

/// Run the unit and integration tests of a project.
fn run_unit_tests(options: &TestOptions,
                  test_args: &[String],
                  compilation: &Compilation)
                  -> CargoResult<(Test, Vec<ProcessError>)> {
    let config = options.compile_opts.config;
    let cwd = options.compile_opts.config.cwd();

    let mut errors = Vec::new();

    for &(ref pkg, ref kind, ref test, ref exe) in &compilation.tests {
        let to_display = match util::without_prefix(exe, cwd) {
            Some(path) => path,
            None => &**exe,
        };
        let mut cmd = compilation.target_process(exe, pkg)?;
        cmd.args(test_args);
        config.shell().concise(|shell| {
            shell.status("Running", to_display.display().to_string())
        })?;
        config.shell().verbose(|shell| {
            shell.status("Running", cmd.to_string())
        })?;

        let result = cmd.exec();

        match result {
            Err(e) => {
                let e = e.downcast::<ProcessError>()?;
                errors.push((kind.clone(), test.clone(), e));
                if !options.no_fail_fast {
                    break;
                }
            }
            Ok(()) => {}
        }
    }

    if errors.len() == 1 {
        let (kind, test, e) = errors.pop().unwrap();
        Ok((Test::UnitTest(kind, test), vec![e]))
    } else {
        Ok((Test::Multiple, errors.into_iter().map((|(_, _, e)| e)).collect()))
    }
}

fn run_doc_tests(options: &TestOptions,
                 test_args: &[String],
                 compilation: &Compilation)
                 -> CargoResult<(Test, Vec<ProcessError>)> {
    let mut errors = Vec::new();
    let config = options.compile_opts.config;

    // We don't build/rust doctests if target != host
    if config.rustc()?.host != compilation.target {
        return Ok((Test::Doc, errors));
    }

    let libs = compilation.to_doc_test.iter().map(|package| {
        (package, package.targets().iter().filter(|t| t.doctested())
                         .map(|t| (t.src_path(), t.name(), t.crate_name())))
    });

    for (package, tests) in libs {
        for (lib, name, crate_name) in tests {
            config.shell().status("Doc-tests", name)?;
            let mut p = compilation.rustdoc_process(package)?;
            p.arg("--test").arg(lib)
             .arg("--crate-name").arg(&crate_name);

            for &rust_dep in &[&compilation.deps_output] {
                let mut arg = OsString::from("dependency=");
                arg.push(rust_dep);
                p.arg("-L").arg(arg);
            }

            for native_dep in compilation.native_dirs.iter() {
                p.arg("-L").arg(native_dep);
            }

            for &host_rust_dep in &[&compilation.host_deps_output] {
                let mut arg = OsString::from("dependency=");
                arg.push(host_rust_dep);
                p.arg("-L").arg(arg);
            }

            for arg in test_args {
                p.arg("--test-args").arg(arg);
            }

            if let Some(cfgs) = compilation.cfgs.get(package.package_id()) {
                for cfg in cfgs.iter() {
                    p.arg("--cfg").arg(cfg);
                }
            }

            let libs = &compilation.libraries[package.package_id()];
            for &(ref target, ref lib) in libs.iter() {
                // Note that we can *only* doctest rlib outputs here.  A
                // staticlib output cannot be linked by the compiler (it just
                // doesn't do that). A dylib output, however, can be linked by
                // the compiler, but will always fail. Currently all dylibs are
                // built as "static dylibs" where the standard library is
                // statically linked into the dylib. The doc tests fail,
                // however, for now as they try to link the standard library
                // dynamically as well, causing problems. As a result we only
                // pass `--extern` for rlib deps and skip out on all other
                // artifacts.
                if lib.extension() != Some(OsStr::new("rlib")) &&
                   !target.for_host() {
                    continue
                }
                let mut arg = OsString::from(target.crate_name());
                arg.push("=");
                arg.push(lib);
                p.arg("--extern").arg(&arg);
            }

            if let Some(flags) = compilation.rustdocflags.get(package.package_id()) {
                p.args(flags);
            }

            config.shell().verbose(|shell| {
                shell.status("Running", p.to_string())
            })?;
            if let Err(e) = p.exec() {
                let e = e.downcast::<ProcessError>()?;
                errors.push(e);
                if !options.no_fail_fast {
                    return Ok((Test::Doc, errors));
                }
            }
        }
    }
    Ok((Test::Doc, errors))
}
<commit_msg>clean up an unused pair of parentheses<commit_after>use std::ffi::{OsString, OsStr};

use ops::{self, Compilation};
use util::{self, CargoTestError, Test, ProcessError};
use util::errors::CargoResult;
use core::Workspace;

pub struct TestOptions<'a> {
    pub compile_opts: ops::CompileOptions<'a>,
    pub no_run: bool,
    pub no_fail_fast: bool,
    pub only_doc: bool,
}

pub fn run_tests(ws: &Workspace,
                 options: &TestOptions,
                 test_args: &[String]) -> CargoResult<Option<CargoTestError>> {
    let compilation = compile_tests(ws, options)?;

    if options.no_run {
        return Ok(None)
    }
    let (test, mut errors) = if options.only_doc {
        assert!(options.compile_opts.filter.is_specific());
        run_doc_tests(options, test_args, &compilation)?
    } else {
        run_unit_tests(options, test_args, &compilation)?
    };

    // If we have an error and want to fail fast, return
    if !errors.is_empty() && !options.no_fail_fast {
        return Ok(Some(CargoTestError::new(test, errors)))
    }

    // If a specific test was requested or we're not running any tests at all,
    // don't run any doc tests.
    if options.compile_opts.filter.is_specific() {
        match errors.len() {
            0 => return Ok(None),
            _ => return Ok(Some(CargoTestError::new(test, errors)))
        }
    }

    let (doctest, docerrors) = run_doc_tests(options, test_args, &compilation)?;
    let test = if docerrors.is_empty() { test } else { doctest };
    errors.extend(docerrors);
    if errors.is_empty() {
        Ok(None)
    } else {
        Ok(Some(CargoTestError::new(test, errors)))
    }
}

pub fn run_benches(ws: &Workspace,
                   options: &TestOptions,
                   args: &[String]) -> CargoResult<Option<CargoTestError>> {
    let mut args = args.to_vec();
    args.push("--bench".to_string());
    let compilation = compile_tests(ws, options)?;

    if options.no_run {
        return Ok(None)
    }
    let (test, errors) = run_unit_tests(options, &args, &compilation)?;
    match errors.len() {
        0 => Ok(None),
        _ => Ok(Some(CargoTestError::new(test, errors))),
    }
}

fn compile_tests<'a>(ws: &Workspace<'a>,
                     options: &TestOptions<'a>)
                     -> CargoResult<Compilation<'a>> {
    let mut compilation = ops::compile(ws, &options.compile_opts)?;
    compilation.tests.sort_by(|a, b| {
        (a.0.package_id(), &a.1, &a.2).cmp(&(b.0.package_id(), &b.1, &b.2))
    });
    Ok(compilation)
}

/// Run the unit and integration tests of a project.
fn run_unit_tests(options: &TestOptions,
                  test_args: &[String],
                  compilation: &Compilation)
                  -> CargoResult<(Test, Vec<ProcessError>)> {
    let config = options.compile_opts.config;
    let cwd = options.compile_opts.config.cwd();

    let mut errors = Vec::new();

    for &(ref pkg, ref kind, ref test, ref exe) in &compilation.tests {
        let to_display = match util::without_prefix(exe, cwd) {
            Some(path) => path,
            None => &**exe,
        };
        let mut cmd = compilation.target_process(exe, pkg)?;
        cmd.args(test_args);
        config.shell().concise(|shell| {
            shell.status("Running", to_display.display().to_string())
        })?;
        config.shell().verbose(|shell| {
            shell.status("Running", cmd.to_string())
        })?;

        let result = cmd.exec();

        match result {
            Err(e) => {
                let e = e.downcast::<ProcessError>()?;
                errors.push((kind.clone(), test.clone(), e));
                if !options.no_fail_fast {
                    break;
                }
            }
            Ok(()) => {}
        }
    }

    if errors.len() == 1 {
        let (kind, test, e) = errors.pop().unwrap();
        Ok((Test::UnitTest(kind, test), vec![e]))
    } else {
        Ok((Test::Multiple, errors.into_iter().map(|(_, _, e)| e).collect()))
    }
}

fn run_doc_tests(options: &TestOptions,
                 test_args: &[String],
                 compilation: &Compilation)
                 -> CargoResult<(Test, Vec<ProcessError>)> {
    let mut errors = Vec::new();
    let config = options.compile_opts.config;

    // We don't build/rust doctests if target != host
    if config.rustc()?.host != compilation.target {
        return Ok((Test::Doc, errors));
    }

    let libs = compilation.to_doc_test.iter().map(|package| {
        (package, package.targets().iter().filter(|t| t.doctested())
                         .map(|t| (t.src_path(), t.name(), t.crate_name())))
    });

    for (package, tests) in libs {
        for (lib, name, crate_name) in tests {
            config.shell().status("Doc-tests", name)?;
            let mut p = compilation.rustdoc_process(package)?;
            p.arg("--test").arg(lib)
             .arg("--crate-name").arg(&crate_name);

            for &rust_dep in &[&compilation.deps_output] {
                let mut arg = OsString::from("dependency=");
                arg.push(rust_dep);
                p.arg("-L").arg(arg);
            }

            for native_dep in compilation.native_dirs.iter() {
                p.arg("-L").arg(native_dep);
            }

            for &host_rust_dep in &[&compilation.host_deps_output] {
                let mut arg = OsString::from("dependency=");
                arg.push(host_rust_dep);
                p.arg("-L").arg(arg);
            }

            for arg in test_args {
                p.arg("--test-args").arg(arg);
            }

            if let Some(cfgs) = compilation.cfgs.get(package.package_id()) {
                for cfg in cfgs.iter() {
                    p.arg("--cfg").arg(cfg);
                }
            }

            let libs = &compilation.libraries[package.package_id()];
            for &(ref target, ref lib) in libs.iter() {
                // Note that we can *only* doctest rlib outputs here.  A
                // staticlib output cannot be linked by the compiler (it just
                // doesn't do that). A dylib output, however, can be linked by
                // the compiler, but will always fail. Currently all dylibs are
                // built as "static dylibs" where the standard library is
                // statically linked into the dylib. The doc tests fail,
                // however, for now as they try to link the standard library
                // dynamically as well, causing problems. As a result we only
                // pass `--extern` for rlib deps and skip out on all other
                // artifacts.
                if lib.extension() != Some(OsStr::new("rlib")) &&
                   !target.for_host() {
                    continue
                }
                let mut arg = OsString::from(target.crate_name());
                arg.push("=");
                arg.push(lib);
                p.arg("--extern").arg(&arg);
            }

            if let Some(flags) = compilation.rustdocflags.get(package.package_id()) {
                p.args(flags);
            }

            config.shell().verbose(|shell| {
                shell.status("Running", p.to_string())
            })?;
            if let Err(e) = p.exec() {
                let e = e.downcast::<ProcessError>()?;
                errors.push(e);
                if !options.no_fail_fast {
                    return Ok((Test::Doc, errors));
                }
            }
        }
    }
    Ok((Test::Doc, errors))
}
<|endoftext|>


<commit_before>use common::VolatileCell;
use common::take_cell::TakeCell;
use core::mem;

struct Registers {
    pub tasks_hfclkstart    : VolatileCell<u32>,
    pub tasks_hfclkstop     : VolatileCell<u32>,
    pub tasks_lfclkstart    : VolatileCell<u32>,
    pub tasks_lfclkstop     : VolatileCell<u32>,
    pub tasks_cal           : VolatileCell<u32>,
    pub tasks_cstart        : VolatileCell<u32>,
    pub tasks_cstop         : VolatileCell<u32>,
    _reserved1: [VolatileCell<u32>; 57],
    pub events_hfclkstarted : VolatileCell<u32>,
    pub events_lfclkstarted : VolatileCell<u32>,
    pub done                : VolatileCell<u32>,
    pub ctto                : VolatileCell<u32>,
    _reserved2: [VolatileCell<u32>; 125],
    pub intenset            : VolatileCell<u32>,
    pub intenclr            : VolatileCell<u32>,
    _reserved3: [VolatileCell<u32>; 63],
    pub hfclkrun            : VolatileCell<u32>,
    pub hfclkstat           : VolatileCell<u32>,
    _reserved4: [VolatileCell<u32>; 1],
    pub lfclkrun            : VolatileCell<u32>,
    pub lfclkstat           : VolatileCell<u32>,
    pub lfclksrccopy        : VolatileCell<u32>,
    _reserved5: [VolatileCell<u32>; 62],
    pub lfclksrc            : VolatileCell<u32>,
    _reserved6: [VolatileCell<u32>; 7],
    pub ctiv                : VolatileCell<u32>,
    _reserved7: [VolatileCell<u32>; 5],
    pub xtalfreq            : VolatileCell<u32>,
}

const CLOCK_BASE: usize = 0x40000000;

pub enum InterruptField {
    HFCLKSTARTED = (1 << 0),
    LFCLKSTARTED = (1 << 1),
    DONE         = (1 << 3),
    CTTO         = (1 << 4),
}

pub enum ClockTaskTriggered {
    NO   = 0,
    YES  = 1,
}

pub enum ClockRunning {
    NORUN   = 0,
    RUN     = (1 << 16),
}

pub enum LowClockSource {
    RC            = 0,
    XTAL          = 1,
    SYNTH         = 2,
    MASK          = 0x3,
}

pub enum HighClockSource {
    RC            = 0,
    XTAL          = 1,
}

pub enum XtalFreq {
    F16MHz         = 0xFF,
    F32MHz         = 0,
}

pub struct Clock {
    client: TakeCell<&'static ClockClient>,
}

pub trait ClockClient {
    // All clock interrupts are control signals, e.g., when
    // a clock has started etc. We don't actually handle any
    // of them for now, but keep this trait in place for if we
    // do need to in the future.
    fn event(&self);
}

pub static mut CLOCK : Clock = Clock {
    client: TakeCell::empty(),
};

impl Clock {
    #[allow(non_snake_case)]
    fn CLOCK(&self) -> &'static Registers {
        unsafe { mem::transmute(CLOCK_BASE as usize) }
    }

    pub fn set_client(&self, client: &'static ClockClient) {
        self.client.replace(client);
    }

    pub fn interrupt_enable(&self, interrupt: InterruptField) {
        self.CLOCK().intenset.set(interrupt as u32);
    }

    pub fn interrupt_disable(&self, interrupt: InterruptField) {
        self.CLOCK().intenclr.set(interrupt as u32);
    }

    pub fn high_start(&self) {
        self.CLOCK().tasks_hfclkstart.set(1);
    }

    pub fn high_stop(&self) {
        self.CLOCK().tasks_hfclkstop.set(1);
    }

    pub fn high_started(&self) -> bool {
        self.CLOCK().events_hfclkstarted.get() == 1
    }

    pub fn high_source(&self) -> HighClockSource {
        match self.CLOCK().hfclkstat.get() & 1 {
            0b0   => HighClockSource::RC,
            _     => HighClockSource::XTAL,
        }
    }

    pub fn high_freq(&self) -> XtalFreq {
        match self.CLOCK().xtalfreq.get() {
            0xff => XtalFreq::F16MHz,
            _    => XtalFreq::F32MHz,
        }
    }

    pub fn high_set_freq(&self, freq: XtalFreq) {
        self.CLOCK().xtalfreq.set(freq as u32);
    }

    pub fn high_running(&self) -> bool {
        (self.CLOCK().hfclkstat.get() & ClockRunning::RUN as u32) ==
            ClockRunning::RUN as u32
    }

    pub fn low_start(&self) {
        self.CLOCK().tasks_lfclkstart.set(1);
    }

    pub fn low_stop(&self) {
        self.CLOCK().tasks_lfclkstop.set(1);
    }

    pub fn low_started(&self) -> bool {
        self.CLOCK().events_lfclkstarted.get() == 1
    }

    pub fn low_source(&self) -> LowClockSource {
        match self.CLOCK().lfclkstat.get() & (LowClockSource::MASK as u32) {
            0b1    => LowClockSource::XTAL,
            0b10   => LowClockSource::SYNTH,
            _ => LowClockSource::RC
        }
    }

    pub fn low_running(&self) -> bool {
        (self.CLOCK().lfclkstat.get() & ClockRunning::RUN as u32) ==
            ClockRunning::RUN as u32
    }

    pub fn low_set_source(&self, src: LowClockSource) {
        self.CLOCK().lfclksrc.set(src as u32);

    }
}
<commit_msg>Clock peripheral comments.<commit_after>//! The clock peripheral of the nRF51 series (chapter 13 of
//! the nRF51 reference manual v3.0), which manages the
//! low frequency and high frequency clocks. The low frequency
//! clock drives the real time clock (RTC), while the
//! high frequency clocks drive the timer system.
//!
//! Author: Philip Levis
//! Date: 8/16/18

use common::VolatileCell;
use common::take_cell::TakeCell;
use core::mem;

struct Registers {
    pub tasks_hfclkstart    : VolatileCell<u32>,
    pub tasks_hfclkstop     : VolatileCell<u32>,
    pub tasks_lfclkstart    : VolatileCell<u32>,
    pub tasks_lfclkstop     : VolatileCell<u32>,
    pub tasks_cal           : VolatileCell<u32>,
    pub tasks_cstart        : VolatileCell<u32>,
    pub tasks_cstop         : VolatileCell<u32>,
    _reserved1: [VolatileCell<u32>; 57],
    pub events_hfclkstarted : VolatileCell<u32>,
    pub events_lfclkstarted : VolatileCell<u32>,
    pub done                : VolatileCell<u32>,
    pub ctto                : VolatileCell<u32>,
    _reserved2: [VolatileCell<u32>; 125],
    pub intenset            : VolatileCell<u32>,
    pub intenclr            : VolatileCell<u32>,
    _reserved3: [VolatileCell<u32>; 63],
    pub hfclkrun            : VolatileCell<u32>,
    pub hfclkstat           : VolatileCell<u32>,
    _reserved4: [VolatileCell<u32>; 1],
    pub lfclkrun            : VolatileCell<u32>,
    pub lfclkstat           : VolatileCell<u32>,
    pub lfclksrccopy        : VolatileCell<u32>,
    _reserved5: [VolatileCell<u32>; 62],
    pub lfclksrc            : VolatileCell<u32>,
    _reserved6: [VolatileCell<u32>; 7],
    pub ctiv                : VolatileCell<u32>,
    _reserved7: [VolatileCell<u32>; 5],
    pub xtalfreq            : VolatileCell<u32>,
}

const CLOCK_BASE: usize = 0x40000000;

pub enum InterruptField {
    HFCLKSTARTED = (1 << 0),
    LFCLKSTARTED = (1 << 1),
    DONE         = (1 << 3),
    CTTO         = (1 << 4),
}

pub enum ClockTaskTriggered {
    NO   = 0,
    YES  = 1,
}

pub enum ClockRunning {
    NORUN   = 0,
    RUN     = (1 << 16),
}

pub enum LowClockSource {
    RC            = 0,
    XTAL          = 1,
    SYNTH         = 2,
    MASK          = 0x3,
}

pub enum HighClockSource {
    RC            = 0,
    XTAL          = 1,
}

pub enum XtalFreq {
    F16MHz         = 0xFF,
    F32MHz         = 0,
}

pub struct Clock {
    client: TakeCell<&'static ClockClient>,
}

pub trait ClockClient {
    /// All clock interrupts are control signals, e.g., when
    /// a clock has started etc. We don't actually handle any
    /// of them for now, but keep this trait in place for if we
    /// do need to in the future.
    fn event(&self);
}

pub static mut CLOCK : Clock = Clock {
    client: TakeCell::empty(),
};

impl Clock {
    #[allow(non_snake_case)]
    fn CLOCK(&self) -> &'static Registers {
        unsafe { mem::transmute(CLOCK_BASE as usize) }
    }

    pub fn set_client(&self, client: &'static ClockClient) {
        self.client.replace(client);
    }

    pub fn interrupt_enable(&self, interrupt: InterruptField) {
        self.CLOCK().intenset.set(interrupt as u32);
    }

    pub fn interrupt_disable(&self, interrupt: InterruptField) {
        self.CLOCK().intenclr.set(interrupt as u32);
    }

    pub fn high_start(&self) {
        self.CLOCK().tasks_hfclkstart.set(1);
    }

    pub fn high_stop(&self) {
        self.CLOCK().tasks_hfclkstop.set(1);
    }

    pub fn high_started(&self) -> bool {
        self.CLOCK().events_hfclkstarted.get() == 1
    }

    pub fn high_source(&self) -> HighClockSource {
        match self.CLOCK().hfclkstat.get() & 1 {
            0b0   => HighClockSource::RC,
            _     => HighClockSource::XTAL,
        }
    }

    pub fn high_freq(&self) -> XtalFreq {
        match self.CLOCK().xtalfreq.get() {
            0xff => XtalFreq::F16MHz,
            _    => XtalFreq::F32MHz,
        }
    }

    pub fn high_set_freq(&self, freq: XtalFreq) {
        self.CLOCK().xtalfreq.set(freq as u32);
    }

    pub fn high_running(&self) -> bool {
        (self.CLOCK().hfclkstat.get() & ClockRunning::RUN as u32) ==
            ClockRunning::RUN as u32
    }

    pub fn low_start(&self) {
        self.CLOCK().tasks_lfclkstart.set(1);
    }

    pub fn low_stop(&self) {
        self.CLOCK().tasks_lfclkstop.set(1);
    }

    pub fn low_started(&self) -> bool {
        self.CLOCK().events_lfclkstarted.get() == 1
    }

    pub fn low_source(&self) -> LowClockSource {
        match self.CLOCK().lfclkstat.get() & (LowClockSource::MASK as u32) {
            0b1    => LowClockSource::XTAL,
            0b10   => LowClockSource::SYNTH,
            _ => LowClockSource::RC
        }
    }

    pub fn low_running(&self) -> bool {
        (self.CLOCK().lfclkstat.get() & ClockRunning::RUN as u32) ==
            ClockRunning::RUN as u32
    }

    pub fn low_set_source(&self, src: LowClockSource) {
        self.CLOCK().lfclksrc.set(src as u32);

    }
}
<|endoftext|>


<commit_before>use command_prelude::*;

use cargo::print_json;

pub fn cli() -> App {
    subcommand("locate-project")
        .about("Checkout a copy of a Git repository")
        .arg_manifest_path()
}

#[derive(Serialize)]
pub struct ProjectLocation {
    root: String,
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
    let root = args.root_manifest(config)?;

    let root = root.to_str()
        .ok_or_else(|| {
            format_err!(
                "your project path contains characters \
                 not representable in Unicode"
            )
        })
        .map_err(|e| CliError::new(e, 1))?
        .to_string();

    let location = ProjectLocation { root };

    print_json(&location);
    Ok(())
}
<commit_msg>Auto merge of #5290 - ehuss:lp-help, r=matklad<commit_after>use command_prelude::*;

use cargo::print_json;

pub fn cli() -> App {
    subcommand("locate-project")
        .about("Print a JSON representation of a Cargo.toml file's location")
        .arg_manifest_path()
}

#[derive(Serialize)]
pub struct ProjectLocation {
    root: String,
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
    let root = args.root_manifest(config)?;

    let root = root.to_str()
        .ok_or_else(|| {
            format_err!(
                "your project path contains characters \
                 not representable in Unicode"
            )
        })
        .map_err(|e| CliError::new(e, 1))?
        .to_string();

    let location = ProjectLocation { root };

    print_json(&location);
    Ok(())
}
<|endoftext|>


<commit_before>/// A command.
#[derive(Clone, Debug)]
pub enum Command {
    /// [Establish][1] a new current point.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands
    Move(Position, Vec<f32>),

    /// [Draw][1] straight lines.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
    Line(Position, Vec<f32>),

    /// [Draw][1] horizontal lines.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
    HorizontalLine(Position, Vec<f32>),

    /// [Draw][1] vertical lines.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
    VerticalLine(Position, Vec<f32>),

    /// [Draw][1] a quadratic Bézier curve.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands
    QuadraticCurve(Position, Vec<f32>),

    /// [Draw][1] a quadratic Bézier curve assuming the control point to be the
    /// reflection of the control point on the previous command relative to the
    /// current point.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands
    SmoothQuadraticCurve(Position, Vec<f32>),

    /// [Draw][1] a cubic Bézier curve.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands
    CubicCurve(Position, Vec<f32>),

    /// [Draw][1] a cubic Bézier curve assuming the first control point to be
    /// the reflection of the second control point on the previous command
    /// relative to the current point.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands
    SmoothCubicCurve(Position, Vec<f32>),

    /// [Draw][1] an elliptical arc.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
    EllipticalArc(Position, Vec<f32>),

    /// [End][1] the current subpath.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand
    Close,
}

/// Parameters.
pub trait Parameters {
    /// Convert into a vector.
    fn into(self) -> Vec<f32>;
}

/// A type of positioning.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Position {
    /// Absolute.
    Absolute,
    /// Relative.
    Relative,
}

impl Parameters for Vec<f32> {
    #[inline]
    fn into(self) -> Vec<f32> {
        self
    }
}

macro_rules! implement {
    ($($primitive:ty,)*) => (
        $(impl Parameters for $primitive {
            #[inline]
            fn into(self) -> Vec<f32> {
                vec![self as f32]
            }
        })*
    );
}

implement! {
    i8, i16, i32, i64, isize,
    u8, u16, u32, u64, usize,
    f32, f64,
}

macro_rules! implement {
    (@express $e:expr) => ($e);
    ($(($t:ident, $n:tt)),*) => (
        impl<$($t),*> Parameters for ($($t),*) where $($t: Parameters),* {
            #[inline]
            fn into(self) -> Vec<f32> {
                let mut result = vec![];
                $(result.append(&mut implement!(@express self.$n).into());)*
                result
            }
        }
    );
}

implement! { (T0, 0), (T1, 1) }
implement! { (T0, 0), (T1, 1), (T2, 2), (T3, 3) }
implement! { (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5) }
implement! { (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6) }
<commit_msg>Eliminate an inlining<commit_after>/// A command.
#[derive(Clone, Debug)]
pub enum Command {
    /// [Establish][1] a new current point.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands
    Move(Position, Vec<f32>),

    /// [Draw][1] straight lines.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
    Line(Position, Vec<f32>),

    /// [Draw][1] horizontal lines.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
    HorizontalLine(Position, Vec<f32>),

    /// [Draw][1] vertical lines.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands
    VerticalLine(Position, Vec<f32>),

    /// [Draw][1] a quadratic Bézier curve.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands
    QuadraticCurve(Position, Vec<f32>),

    /// [Draw][1] a quadratic Bézier curve assuming the control point to be the
    /// reflection of the control point on the previous command relative to the
    /// current point.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands
    SmoothQuadraticCurve(Position, Vec<f32>),

    /// [Draw][1] a cubic Bézier curve.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands
    CubicCurve(Position, Vec<f32>),

    /// [Draw][1] a cubic Bézier curve assuming the first control point to be
    /// the reflection of the second control point on the previous command
    /// relative to the current point.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands
    SmoothCubicCurve(Position, Vec<f32>),

    /// [Draw][1] an elliptical arc.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands
    EllipticalArc(Position, Vec<f32>),

    /// [End][1] the current subpath.
    ///
    /// [1]: http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand
    Close,
}

/// Parameters.
pub trait Parameters {
    /// Convert into a vector.
    fn into(self) -> Vec<f32>;
}

/// A type of positioning.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Position {
    /// Absolute.
    Absolute,
    /// Relative.
    Relative,
}

impl Parameters for Vec<f32> {
    #[inline]
    fn into(self) -> Vec<f32> {
        self
    }
}

macro_rules! implement {
    ($($primitive:ty,)*) => (
        $(impl Parameters for $primitive {
            #[inline]
            fn into(self) -> Vec<f32> {
                vec![self as f32]
            }
        })*
    );
}

implement! {
    i8, i16, i32, i64, isize,
    u8, u16, u32, u64, usize,
    f32, f64,
}

macro_rules! implement {
    (@express $e:expr) => ($e);
    ($(($t:ident, $n:tt)),*) => (
        impl<$($t),*> Parameters for ($($t),*) where $($t: Parameters),* {
            fn into(self) -> Vec<f32> {
                let mut result = vec![];
                $(result.append(&mut implement!(@express self.$n).into());)*
                result
            }
        }
    );
}

implement! { (T0, 0), (T1, 1) }
implement! { (T0, 0), (T1, 1), (T2, 2), (T3, 3) }
implement! { (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5) }
implement! { (T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5), (T6, 6) }
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::EventBinding;
use dom::bindings::codegen::EventBinding::EventConstants;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::Fallible;
use dom::eventtarget::EventTarget;
use dom::window::Window;
use servo_util::str::DOMString;

use geom::point::Point2D;

pub enum Event_ {
    ResizeEvent(uint, uint),
    ReflowEvent,
    ClickEvent(uint, Point2D<f32>),
    MouseDownEvent(uint, Point2D<f32>),
    MouseUpEvent(uint, Point2D<f32>),
    MouseMoveEvent(Point2D<f32>)
}

#[deriving(Encodable)]
pub enum EventPhase {
    PhaseNone      = EventConstants::NONE,
    PhaseCapturing = EventConstants::CAPTURING_PHASE,
    PhaseAtTarget  = EventConstants::AT_TARGET,
    PhaseBubbling  = EventConstants::BUBBLING_PHASE,
}

#[deriving(Eq, Encodable)]
pub enum EventTypeId {
    HTMLEventTypeId,
    UIEventTypeId,
    MouseEventTypeId,
    KeyEventTypeId
}

#[deriving(Encodable)]
pub struct Event {
    type_id: EventTypeId,
    reflector_: Reflector,
    current_target: Option<JS<EventTarget>>,
    target: Option<JS<EventTarget>>,
    type_: DOMString,
    phase: EventPhase,
    default_prevented: bool,
    stop_propagation: bool,
    stop_immediate: bool,
    cancelable: bool,
    bubbles: bool,
    trusted: bool,
    dispatching: bool,
    initialized: bool,
}

impl Event {
    pub fn new_inherited(type_id: EventTypeId) -> Event {
        Event {
            type_id: type_id,
            reflector_: Reflector::new(),
            current_target: None,
            target: None,
            phase: PhaseNone,
            type_: ~"",
            default_prevented: false,
            cancelable: true,
            bubbles: true,
            trusted: false,
            dispatching: false,
            stop_propagation: false,
            stop_immediate: false,
            initialized: false,
        }
    }

    pub fn new(window: &JS<Window>) -> JS<Event> {
        reflect_dom_object(~Event::new_inherited(HTMLEventTypeId),
                           window,
                           EventBinding::Wrap)
    }

    pub fn EventPhase(&self) -> u16 {
        self.phase as u16
    }

    pub fn Type(&self) -> DOMString {
        self.type_.clone()
    }

    pub fn GetTarget(&self) -> Option<JS<EventTarget>> {
        self.target.clone()
    }

    pub fn GetCurrentTarget(&self) -> Option<JS<EventTarget>> {
        self.current_target.clone()
    }

    pub fn DefaultPrevented(&self) -> bool {
        self.default_prevented
    }

    pub fn PreventDefault(&mut self) {
        if self.cancelable {
            self.default_prevented = true
        }
    }

    pub fn StopPropagation(&mut self) {
        self.stop_propagation = true;
    }

    pub fn StopImmediatePropagation(&mut self) {
        self.stop_immediate = true;
        self.stop_propagation = true;
    }

    pub fn Bubbles(&self) -> bool {
        self.bubbles
    }

    pub fn Cancelable(&self) -> bool {
        self.cancelable
    }

    pub fn TimeStamp(&self) -> u64 {
        0
    }

    pub fn InitEvent(&mut self,
                     type_: DOMString,
                     bubbles: bool,
                     cancelable: bool) {
        self.type_ = type_;
        self.cancelable = cancelable;
        self.bubbles = bubbles;
        self.initialized = true;
        self.default_prevented = false;
    }

    pub fn IsTrusted(&self) -> bool {
        self.trusted
    }

    pub fn Constructor(global: &JS<Window>,
                       type_: DOMString,
                       init: &EventBinding::EventInit) -> Fallible<JS<Event>> {
        let mut ev = Event::new(global);
        ev.get_mut().InitEvent(type_, init.bubbles, init.cancelable);
        Ok(ev)
    }
}

impl Reflectable for Event {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}
<commit_msg>auto merge of #2179 : Manishearth/servo/refactor-canceled, r=Ms2ger<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::EventBinding;
use dom::bindings::codegen::EventBinding::EventConstants;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::Fallible;
use dom::eventtarget::EventTarget;
use dom::window::Window;
use servo_util::str::DOMString;

use geom::point::Point2D;

pub enum Event_ {
    ResizeEvent(uint, uint),
    ReflowEvent,
    ClickEvent(uint, Point2D<f32>),
    MouseDownEvent(uint, Point2D<f32>),
    MouseUpEvent(uint, Point2D<f32>),
    MouseMoveEvent(Point2D<f32>)
}

#[deriving(Encodable)]
pub enum EventPhase {
    PhaseNone      = EventConstants::NONE,
    PhaseCapturing = EventConstants::CAPTURING_PHASE,
    PhaseAtTarget  = EventConstants::AT_TARGET,
    PhaseBubbling  = EventConstants::BUBBLING_PHASE,
}

#[deriving(Eq, Encodable)]
pub enum EventTypeId {
    HTMLEventTypeId,
    UIEventTypeId,
    MouseEventTypeId,
    KeyEventTypeId
}

#[deriving(Encodable)]
pub struct Event {
    type_id: EventTypeId,
    reflector_: Reflector,
    current_target: Option<JS<EventTarget>>,
    target: Option<JS<EventTarget>>,
    type_: DOMString,
    phase: EventPhase,
    canceled: bool,
    stop_propagation: bool,
    stop_immediate: bool,
    cancelable: bool,
    bubbles: bool,
    trusted: bool,
    dispatching: bool,
    initialized: bool,
}

impl Event {
    pub fn new_inherited(type_id: EventTypeId) -> Event {
        Event {
            type_id: type_id,
            reflector_: Reflector::new(),
            current_target: None,
            target: None,
            phase: PhaseNone,
            type_: ~"",
            canceled: false,
            cancelable: true,
            bubbles: true,
            trusted: false,
            dispatching: false,
            stop_propagation: false,
            stop_immediate: false,
            initialized: false,
        }
    }

    pub fn new(window: &JS<Window>) -> JS<Event> {
        reflect_dom_object(~Event::new_inherited(HTMLEventTypeId),
                           window,
                           EventBinding::Wrap)
    }

    pub fn EventPhase(&self) -> u16 {
        self.phase as u16
    }

    pub fn Type(&self) -> DOMString {
        self.type_.clone()
    }

    pub fn GetTarget(&self) -> Option<JS<EventTarget>> {
        self.target.clone()
    }

    pub fn GetCurrentTarget(&self) -> Option<JS<EventTarget>> {
        self.current_target.clone()
    }

    pub fn DefaultPrevented(&self) -> bool {
        self.canceled
    }

    pub fn PreventDefault(&mut self) {
        if self.cancelable {
            self.canceled = true
        }
    }

    pub fn StopPropagation(&mut self) {
        self.stop_propagation = true;
    }

    pub fn StopImmediatePropagation(&mut self) {
        self.stop_immediate = true;
        self.stop_propagation = true;
    }

    pub fn Bubbles(&self) -> bool {
        self.bubbles
    }

    pub fn Cancelable(&self) -> bool {
        self.cancelable
    }

    pub fn TimeStamp(&self) -> u64 {
        0
    }

    pub fn InitEvent(&mut self,
                     type_: DOMString,
                     bubbles: bool,
                     cancelable: bool) {
        self.type_ = type_;
        self.cancelable = cancelable;
        self.bubbles = bubbles;
        self.initialized = true;
        self.canceled = false;
    }

    pub fn IsTrusted(&self) -> bool {
        self.trusted
    }

    pub fn Constructor(global: &JS<Window>,
                       type_: DOMString,
                       init: &EventBinding::EventInit) -> Fallible<JS<Event>> {
        let mut ev = Event::new(global);
        ev.get_mut().InitEvent(type_, init.bubbles, init.cancelable);
        Ok(ev)
    }
}

impl Reflectable for Event {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}
<|endoftext|>


<commit_before>// This assumes that either uchardet dev packages are installed where
// `pkg_config` can find them, or that CMake and supporting tools are
// available.  Patches are welcome to help make it work on other operating
// systems!

extern crate pkg_config;
extern crate cmake;

use cmake::Config;

fn main() {
    // Do nothing if this package is already provided by the system.
    if pkg_config::find_library("uchardet").is_ok() { return; }

    // Build uchardet ourselves
    let mut config = Config::new("uchardet");

    // Mustn't build the binaries as they aren't compatible with Windows
    // and cause a compiler error
    config.define("BUILD_BINARY", "OFF");

    if cfg!(target_os = "windows") && cfg!(target_env = "gnu") {
        // FIXME: This is only needed on newer versions of gcc (>5 ?); Older
        //        versions fail with "unrecognized command line option" and
        //        abort the build; We need to somehow detect the compiler version
        // Disable sized deallocation as we're unable to link when it's enabled
        config.cxxflag("-fno-sized-deallocation");
    }

    let dst = config.build();

    // Print out link instructions for Cargo.
    println!("cargo:rustc-link-search=native={}/lib", dst.display());
    println!("cargo:rustc-link-search=native={}/lib64", dst.display());
    println!("cargo:rustc-link-lib=static=uchardet");

    if !(cfg!(target_os = "windows") && cfg!(target_env = "msvc")) {
        // Not needed on windows-msvc

        // Decide how to link our C++ runtime.  Feel free to submit patches
        // to make this work on your platform.  Other likely options are "c++"
        // and "c++abi" depending on OS and compiler.
        let cxx_abi = "stdc++";
        println!("cargo:rustc-flags=-l {}", cxx_abi);
    }
}
<commit_msg>Only build static libs<commit_after>// This assumes that either uchardet dev packages are installed where
// `pkg_config` can find them, or that CMake and supporting tools are
// available.  Patches are welcome to help make it work on other operating
// systems!

extern crate pkg_config;
extern crate cmake;

use cmake::Config;

fn main() {
    // Do nothing if this package is already provided by the system.
    if pkg_config::find_library("uchardet").is_ok() { return; }

    // Build uchardet ourselves
    let mut config = Config::new("uchardet");

    // Mustn't build the binaries as they aren't compatible with Windows
    // and cause a compiler error
    config.define("BUILD_BINARY", "OFF");
    config.define("BUILD_STATIC", "ON");
    config.define("BUILD_SHARED_LIBS", "OFF");

    if cfg!(target_os = "windows") && cfg!(target_env = "gnu") {
        // FIXME: This is only needed on newer versions of gcc (>5 ?); Older
        //        versions fail with "unrecognized command line option" and
        //        abort the build; We need to somehow detect the compiler version
        // Disable sized deallocation as we're unable to link when it's enabled
        config.cxxflag("-fno-sized-deallocation");
    }

    let dst = config.build();

    // Print out link instructions for Cargo.
    println!("cargo:rustc-link-search=native={}/lib", dst.display());
    println!("cargo:rustc-link-search=native={}/lib64", dst.display());
    println!("cargo:rustc-link-lib=static=uchardet");

    if !(cfg!(target_os = "windows") && cfg!(target_env = "msvc")) {
        // Not needed on windows-msvc

        // Decide how to link our C++ runtime.  Feel free to submit patches
        // to make this work on your platform.  Other likely options are "c++"
        // and "c++abi" depending on OS and compiler.
        let cxx_abi = "stdc++";
        println!("cargo:rustc-flags=-l {}", cxx_abi);
    }
}
<|endoftext|>


<commit_before>
extern crate arrayvec;
#[macro_use] extern crate bencher;

use arrayvec::ArrayVec;

use bencher::Bencher;
use bencher::black_box;

fn extend_with_constant(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let cap = v.capacity();
    b.iter(|| {
        v.clear();
        v.extend((0..cap).map(|_| 1));
        v[0]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_with_range(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let cap = v.capacity();
    b.iter(|| {
        v.clear();
        v.extend((0..cap).map(|x| x as _));
        v[0]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_with_slice(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let data = [1; 512];
    b.iter(|| {
        v.clear();
        v.extend(black_box(data.iter()).cloned());
        v[0]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_from_slice(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let data = [1; 512];
    b.iter(|| {
        v.clear();
        v.try_extend_from_slice(&data).ok();
        v[511]
    });
    b.bytes = v.capacity() as u64;
}

benchmark_group!(benches, extend_with_constant, extend_with_range, extend_with_slice, extend_from_slice);
benchmark_main!(benches);
<commit_msg>TEST: Tweak extend benchmarks, add write benchmark<commit_after>
extern crate arrayvec;
#[macro_use] extern crate bencher;

use std::io::Write;

use arrayvec::ArrayVec;

use bencher::Bencher;
use bencher::black_box;

fn extend_with_constant(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let cap = v.capacity();
    b.iter(|| {
        v.clear();
        let constant = black_box(1);
        v.extend((0..cap).map(move |_| constant));
        v[511]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_with_range(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let cap = v.capacity();
    b.iter(|| {
        v.clear();
        let range = 0..cap;
        v.extend(range.map(|x| black_box(x as _)));
        v[511]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_with_slice(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let data = [1; 512];
    b.iter(|| {
        v.clear();
        let iter = data.iter().map(|&x| x);
        v.extend(iter);
        v[511]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_with_write(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let data = [1; 512];
    b.iter(|| {
        v.clear();
        v.write(&data[..]).ok();
        v[511]
    });
    b.bytes = v.capacity() as u64;
}

fn extend_from_slice(b: &mut Bencher) {
    let mut v = ArrayVec::<[u8; 512]>::new();
    let data = [1; 512];
    b.iter(|| {
        v.clear();
        v.try_extend_from_slice(&data).ok();
        v[511]
    });
    b.bytes = v.capacity() as u64;
}

benchmark_group!(benches,
                 extend_with_constant,
                 extend_with_range,
                 extend_with_slice,
                 extend_with_write,
                 extend_from_slice
);

benchmark_main!(benches);
<|endoftext|>


<commit_before>pub mod term;
pub mod display;
pub mod reduction;
pub mod arithmetic;
pub mod booleans;
pub mod list;<commit_msg>Delete lib.rs<commit_after><|endoftext|>


<commit_before>#![macro_escape]
macro_rules! auth_module (($auth_name:ident,
                           $verify_name:ident,
                           $verify_fn:ident,
                           $keybytes:expr,
                           $tagbytes:expr) => (

#[link(name = "sodium")]
extern {
    fn $auth_name(a: *mut u8,
                  m: *u8,
                  mlen: c_ulonglong,
                  k: *u8) -> c_int;
    fn $verify_name(a: *u8,
                    m: *u8,
                    mlen: c_ulonglong,
                    k: *u8) -> c_int;
}

pub static KEYBYTES: uint = $keybytes;
pub static TAGBYTES: uint = $tagbytes;

/**
 * Authentication `Key`
 *
 * When a `Key` goes out of scope its contents
 * will be zeroed out
 */
pub struct Key(pub [u8, ..KEYBYTES]);

impl Drop for Key {
    fn drop(&mut self) {
        let &Key(ref mut k) = self;
        for e in k.mut_iter() { *e = 0 }
    }
}

/**
  * Authentication `Tag`
  *
  * The tag implements the traits `TotalEq` and `Eq` using constant-time
  * comparison functions. See `sodiumoxide::crypto::verify::verify_32`
  */
pub struct Tag(pub [u8, ..TAGBYTES]);
impl TotalEq for Tag { }
impl Eq for Tag {
    fn eq(&self, &Tag(other): &Tag) -> bool {
        let &Tag(ref tag) = self;
        $verify_fn(tag, &other)
    }
}

/**
 * `gen_key()` randomly generates a key for authentication
 *
 * THREAD SAFETY: `gen_key()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_key() -> Key {
    let mut k = [0, ..KEYBYTES];
    randombytes_into(k);
    Key(k)
}

/**
 * `authenticate()` authenticates a message `m` using a secret key `k`.
 * The function returns an authenticator tag.
 */
pub fn authenticate(m: &[u8],
                    &Key(k): &Key) -> Tag {
    unsafe {
        let mut tag = [0, ..TAGBYTES];
        $auth_name(tag.as_mut_ptr(),
                   m.as_ptr(),
                   m.len() as c_ulonglong,
                   k.as_ptr());
        Tag(tag)
    }
}

/**
 * `verify()` returns `true` if `tag` is a correct authenticator of message `m`
 * under a secret key `k`. Otherwise it returns false.
 */
pub fn verify(&Tag(tag): &Tag, m: &[u8],
              &Key(k): &Key) -> bool {
    unsafe {
        $verify_name(tag.as_ptr(),
                     m.as_ptr(),
                     m.len() as c_ulonglong,
                     k.as_ptr()) == 0
    }
}

#[test]
fn test_auth_verify() {
    use randombytes::randombytes;
    for i in range(0, 256u) {
        let k = gen_key();
        let m = randombytes(i);
        let tag = authenticate(m.as_slice(), &k);
        assert!(verify(&tag, m.as_slice(), &k));
    }
}

#[test]
fn test_auth_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32u) {
        let k = gen_key();
        let mut mv = randombytes(i);
        let m = mv.as_mut_slice();
        let Tag(mut tagbuf) = authenticate(m.as_slice(), &k);
        for j in range(0, m.len()) {
            m[j] ^= 0x20;
            assert!(!verify(&Tag(tagbuf), m.as_slice(), &k));
            m[j] ^= 0x20;
        }
        for j in range(0, tagbuf.len()) {
            tagbuf[j] ^= 0x20;
            assert!(!verify(&Tag(tagbuf), m, &k));
            tagbuf[j] ^= 0x20;
        }
    }
}

))
<commit_msg>update for Eq trait changes<commit_after>#![macro_escape]
macro_rules! auth_module (($auth_name:ident,
                           $verify_name:ident,
                           $verify_fn:ident,
                           $keybytes:expr,
                           $tagbytes:expr) => (

#[link(name = "sodium")]
extern {
    fn $auth_name(a: *mut u8,
                  m: *u8,
                  mlen: c_ulonglong,
                  k: *u8) -> c_int;
    fn $verify_name(a: *u8,
                    m: *u8,
                    mlen: c_ulonglong,
                    k: *u8) -> c_int;
}

pub static KEYBYTES: uint = $keybytes;
pub static TAGBYTES: uint = $tagbytes;

/**
 * Authentication `Key`
 *
 * When a `Key` goes out of scope its contents
 * will be zeroed out
 */
pub struct Key(pub [u8, ..KEYBYTES]);

impl Drop for Key {
    fn drop(&mut self) {
        let &Key(ref mut k) = self;
        for e in k.mut_iter() { *e = 0 }
    }
}

/**
  * Authentication `Tag`
  *
  * The tag implements the traits `PartialEq` and `Eq` using constant-time
  * comparison functions. See `sodiumoxide::crypto::verify::verify_32`
  */
pub struct Tag(pub [u8, ..TAGBYTES]);
impl Eq for Tag {}
impl PartialEq for Tag {
    fn eq(&self, &Tag(other): &Tag) -> bool {
        let &Tag(ref tag) = self;
        $verify_fn(tag, &other)
    }
}

/**
 * `gen_key()` randomly generates a key for authentication
 *
 * THREAD SAFETY: `gen_key()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_key() -> Key {
    let mut k = [0, ..KEYBYTES];
    randombytes_into(k);
    Key(k)
}

/**
 * `authenticate()` authenticates a message `m` using a secret key `k`.
 * The function returns an authenticator tag.
 */
pub fn authenticate(m: &[u8],
                    &Key(k): &Key) -> Tag {
    unsafe {
        let mut tag = [0, ..TAGBYTES];
        $auth_name(tag.as_mut_ptr(),
                   m.as_ptr(),
                   m.len() as c_ulonglong,
                   k.as_ptr());
        Tag(tag)
    }
}

/**
 * `verify()` returns `true` if `tag` is a correct authenticator of message `m`
 * under a secret key `k`. Otherwise it returns false.
 */
pub fn verify(&Tag(tag): &Tag, m: &[u8],
              &Key(k): &Key) -> bool {
    unsafe {
        $verify_name(tag.as_ptr(),
                     m.as_ptr(),
                     m.len() as c_ulonglong,
                     k.as_ptr()) == 0
    }
}

#[test]
fn test_auth_verify() {
    use randombytes::randombytes;
    for i in range(0, 256u) {
        let k = gen_key();
        let m = randombytes(i);
        let tag = authenticate(m.as_slice(), &k);
        assert!(verify(&tag, m.as_slice(), &k));
    }
}

#[test]
fn test_auth_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32u) {
        let k = gen_key();
        let mut mv = randombytes(i);
        let m = mv.as_mut_slice();
        let Tag(mut tagbuf) = authenticate(m.as_slice(), &k);
        for j in range(0, m.len()) {
            m[j] ^= 0x20;
            assert!(!verify(&Tag(tagbuf), m.as_slice(), &k));
            m[j] ^= 0x20;
        }
        for j in range(0, tagbuf.len()) {
            tagbuf[j] ^= 0x20;
            assert!(!verify(&Tag(tagbuf), m, &k));
            tagbuf[j] ^= 0x20;
        }
    }
}

))
<|endoftext|>


<commit_before>/// `ArgGroup`s are a family of related arguments and way for you to say, "Any of these arguments".
/// By placing arguments in a logical group, you can make easier requirement and exclusion rules
/// intead of having to list each individually, or when you want a rule to apply "any but not all"
/// arguments.
///
/// For instance, you can make an entire ArgGroup required, this means that one (and *only* one)
/// argument. from that group must be present. Using more than one argument from an ArgGroup causes
/// a failure (graceful exit).
///
/// You can also do things such as name an ArgGroup as a confliction or requirement, meaning any
/// of the arguments that belong to that group will cause a failure if present, or must present
/// respectively.
///
/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be
/// present out of a given set. Imagine that you had multiple arguments, and you want one of them to
/// be required, but making all of them required isn't feasible because perhaps they conflict with
/// each other. For example, lets say that you were building an application where one could set a
/// given version number by supplying a string with an option argument, i.e. `--set-ver v1.2.3`, you
/// also wanted to support automatically using a previous version number and simply incrementing one
/// of the three numbers. So you create three flags `--major`, `--minor`, and `--patch`. All of
/// these arguments shouldn't be used at one time but you want to specify that *at least one* of
/// them is used. For this, you can create a group.

extern crate clap;

use clap::{App, Arg, ArgGroup};

fn main() {
    // Create application like normal
    let matches = App::new("myapp")
                      // Add the version arguments
                      .args_from_usage("--set-ver [ver] 'set version manually'
                                        --major         'auto inc major'
                                        --minor         'auto inc minor'
                                        --patch         'auto inc patch'")
                      // Create a group, make it required, and add the above arguments
                      .group(ArgGroup::with_name("vers")
                                          .required(true)
                                          .args(&["ver", "major", "minor", "patch"]))
                      // Arguments can also be added to a group individually, these two arguments
                      // are part of the "input" group which is not required
                      .arg(Arg::from_usage("[INPUT_FILE] 'some regular input'")
                        .group("input"))
                      .arg(Arg::from_usage("--spec-in [SPEC_IN] 'some special input argument'")
                        .group("input"))
                      // Now let's assume we have a -c [config] argument which requires one of
                      // (but **not** both) the "input" arguments
                      .arg(Arg::with_name("config")
                        .short("c")
                        .takes_value(true)
                        .requires("input"))
                      .get_matches();

    // Let's assume the old version 1.2.3
    let mut major = 1;
    let mut minor = 2;
    let mut patch = 3;

    // See if --set-ver was used to set the version manually
    let version = if let Some(ver) = matches.value_of("ver") {
        format!("{}", ver)
    } else {
        // Increment the one requested (in a real program, we'd reset the lower numbers)
        let (maj, min, pat) = (matches.is_present("major"),
                                     matches.is_present("minor"),
                                     matches.is_present("patch"));
        match (maj, min, pat) {
            (true, _, _) => major += 1,
            (_, true, _) => minor += 1,
            (_, _, true) => patch += 1,
            _            => unreachable!(),
        };
        format!("{}.{}.{}", major, minor, patch)
    };

    println!("Version: {}", version);

    // Check for usage of -c
    if matches.is_present("config") {
        let input = matches.value_of("INPUT_FILE").unwrap_or(matches.value_of("SPEC_IN").unwrap());
        println!("Doing work using input {} and config {}",
                                                     input,
                                                     matches.value_of("config").unwrap());
    }

}
<commit_msg>Fix doc typo in 14_groups.rs<commit_after>/// `ArgGroup`s are a family of related arguments and way for you to say, "Any of these arguments".
/// By placing arguments in a logical group, you can make easier requirement and exclusion rules
/// instead of having to list each individually, or when you want a rule to apply "any but not all"
/// arguments.
///
/// For instance, you can make an entire ArgGroup required, this means that one (and *only* one)
/// argument. from that group must be present. Using more than one argument from an ArgGroup causes
/// a failure (graceful exit).
///
/// You can also do things such as name an ArgGroup as a confliction or requirement, meaning any
/// of the arguments that belong to that group will cause a failure if present, or must present
/// respectively.
///
/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be
/// present out of a given set. Imagine that you had multiple arguments, and you want one of them to
/// be required, but making all of them required isn't feasible because perhaps they conflict with
/// each other. For example, lets say that you were building an application where one could set a
/// given version number by supplying a string with an option argument, i.e. `--set-ver v1.2.3`, you
/// also wanted to support automatically using a previous version number and simply incrementing one
/// of the three numbers. So you create three flags `--major`, `--minor`, and `--patch`. All of
/// these arguments shouldn't be used at one time but you want to specify that *at least one* of
/// them is used. For this, you can create a group.

extern crate clap;

use clap::{App, Arg, ArgGroup};

fn main() {
    // Create application like normal
    let matches = App::new("myapp")
                      // Add the version arguments
                      .args_from_usage("--set-ver [ver] 'set version manually'
                                        --major         'auto inc major'
                                        --minor         'auto inc minor'
                                        --patch         'auto inc patch'")
                      // Create a group, make it required, and add the above arguments
                      .group(ArgGroup::with_name("vers")
                                          .required(true)
                                          .args(&["ver", "major", "minor", "patch"]))
                      // Arguments can also be added to a group individually, these two arguments
                      // are part of the "input" group which is not required
                      .arg(Arg::from_usage("[INPUT_FILE] 'some regular input'")
                        .group("input"))
                      .arg(Arg::from_usage("--spec-in [SPEC_IN] 'some special input argument'")
                        .group("input"))
                      // Now let's assume we have a -c [config] argument which requires one of
                      // (but **not** both) the "input" arguments
                      .arg(Arg::with_name("config")
                        .short("c")
                        .takes_value(true)
                        .requires("input"))
                      .get_matches();

    // Let's assume the old version 1.2.3
    let mut major = 1;
    let mut minor = 2;
    let mut patch = 3;

    // See if --set-ver was used to set the version manually
    let version = if let Some(ver) = matches.value_of("ver") {
        format!("{}", ver)
    } else {
        // Increment the one requested (in a real program, we'd reset the lower numbers)
        let (maj, min, pat) = (matches.is_present("major"),
                                     matches.is_present("minor"),
                                     matches.is_present("patch"));
        match (maj, min, pat) {
            (true, _, _) => major += 1,
            (_, true, _) => minor += 1,
            (_, _, true) => patch += 1,
            _            => unreachable!(),
        };
        format!("{}.{}.{}", major, minor, patch)
    };

    println!("Version: {}", version);

    // Check for usage of -c
    if matches.is_present("config") {
        let input = matches.value_of("INPUT_FILE").unwrap_or(matches.value_of("SPEC_IN").unwrap());
        println!("Doing work using input {} and config {}",
                                                     input,
                                                     matches.value_of("config").unwrap());
    }

}
<|endoftext|>


<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use bindgen;
use cc;
use fs_utils::copy::copy_directory;
use glob::glob;

use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command;

fn sed_htslib_makefile(out: &PathBuf, patterns: &[&str], feature: &str) {
    for pattern in patterns {
        if !Command::new("sed")
            .current_dir(out.join("htslib"))
            .arg("-i")
            .arg("-e")
            .arg(pattern)
            .arg("Makefile")
            .status()
            .unwrap()
            .success()
        {
            panic!("failed to strip {} support", feature);
        }
    }
}

fn main() {
    let out = PathBuf::from(env::var("OUT_DIR").unwrap());
    let mut cfg = cc::Build::new();
    cfg.warnings(false).static_flag(true).pic(true);

    if let Ok(z_inc) = env::var("DEP_Z_INCLUDE") {
        cfg.include(z_inc);
    }

    if !out.join("htslib").exists() {
        copy_directory("htslib", &out).unwrap();
    }

    let use_bzip2 = env::var("CARGO_FEATURE_BZIP2").is_ok();
    if !use_bzip2 {
        let bzip2_patterns = vec!["s/ -lbz2//", "/#define HAVE_LIBBZ2/d"];
        sed_htslib_makefile(&out, &bzip2_patterns, "bzip2");
    } else if let Ok(inc) = env::var("DEP_BZIP2_ROOT")
        .map(PathBuf::from)
        .map(|path| path.join("include"))
    {
        cfg.include(inc);
    }

    let use_lzma = env::var("CARGO_FEATURE_LZMA").is_ok();
    if !use_lzma {
        let lzma_patterns = vec!["s/ -llzma//", "/#define HAVE_LIBLZMA/d"];
        sed_htslib_makefile(&out, &lzma_patterns, "lzma");
    } else if let Ok(inc) = env::var("DEP_LZMA_INCLUDE").map(PathBuf::from) {
        cfg.include(inc);
    }

    let use_curl = env::var("CARGO_FEATURE_CURL").is_ok();
    if !use_curl {
        let curl_patterns = vec!["s/ -lcurl//", "/#define HAVE_LIBCURL/d"];
        sed_htslib_makefile(&out, &curl_patterns, "curl");
    } else if let Ok(inc) = env::var("DEP_CURL_INCLUDE").map(PathBuf::from) {
        cfg.include(inc);
    }

    let tool = cfg.get_compiler();
    let (cc_path, cflags_env) = (tool.path(), tool.cflags_env());
    let cc_cflags = cflags_env.to_string_lossy().replace("-O0", "");
    if !Command::new("make")
        .current_dir(out.join("htslib"))
        .arg(format!("CC={}", cc_path.display()))
        .arg(format!("CFLAGS={}", cc_cflags))
        .arg("lib-static")
        .arg("-B")
        .status()
        .unwrap()
        .success()
    {
        panic!("failed to build htslib");
    }

    cfg.file("wrapper.c").compile("wrapper");

    bindgen::Builder::default()
        .header("wrapper.h")
        .generate_comments(false)
        .blacklist_function("strtold")
        .blacklist_type("max_align_t")
        .generate()
        .expect("Unable to generate bindings.")
        .write_to_file(out.join("bindings.rs"))
        .expect("Could not write bindings.");

    let include = out.join("include");
    fs::create_dir_all(&include).unwrap();
    if include.join("htslib").exists() {
        fs::remove_dir_all(include.join("htslib")).expect("remove exist include dir");
    }
    copy_directory(out.join("htslib").join("htslib"), &include).unwrap();
    fs::copy(out.join("htslib").join("libhts.a"), out.join("libhts.a")).unwrap();

    println!("cargo:root={}", out.display());
    println!("cargo:include={}", include.display());
    println!("cargo:libdir={}", out.display());
    println!("cargo:rustc-link-lib=static=hts");
    println!("cargo:rerun-if-changed=wrapper.c");
    println!("cargo:rerun-if-changed=wrapper.h");
    for htsfile in glob("htslib/**/*").unwrap() {
        let htsfile = htsfile.as_ref().unwrap().to_str().unwrap();
        println!("cargo:rerun-if-changed={}", htsfile);
    }
}
<commit_msg>restrict rerun-if-changed to build files (#203)<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use bindgen;
use cc;
use fs_utils::copy::copy_directory;
use glob::glob;

use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command;

fn sed_htslib_makefile(out: &PathBuf, patterns: &[&str], feature: &str) {
    for pattern in patterns {
        if !Command::new("sed")
            .current_dir(out.join("htslib"))
            .arg("-i")
            .arg("-e")
            .arg(pattern)
            .arg("Makefile")
            .status()
            .unwrap()
            .success()
        {
            panic!("failed to strip {} support", feature);
        }
    }
}

fn main() {
    let out = PathBuf::from(env::var("OUT_DIR").unwrap());
    let mut cfg = cc::Build::new();
    cfg.warnings(false).static_flag(true).pic(true);

    if let Ok(z_inc) = env::var("DEP_Z_INCLUDE") {
        cfg.include(z_inc);
    }

    if !out.join("htslib").exists() {
        copy_directory("htslib", &out).unwrap();
    }

    let use_bzip2 = env::var("CARGO_FEATURE_BZIP2").is_ok();
    if !use_bzip2 {
        let bzip2_patterns = vec!["s/ -lbz2//", "/#define HAVE_LIBBZ2/d"];
        sed_htslib_makefile(&out, &bzip2_patterns, "bzip2");
    } else if let Ok(inc) = env::var("DEP_BZIP2_ROOT")
        .map(PathBuf::from)
        .map(|path| path.join("include"))
    {
        cfg.include(inc);
    }

    let use_lzma = env::var("CARGO_FEATURE_LZMA").is_ok();
    if !use_lzma {
        let lzma_patterns = vec!["s/ -llzma//", "/#define HAVE_LIBLZMA/d"];
        sed_htslib_makefile(&out, &lzma_patterns, "lzma");
    } else if let Ok(inc) = env::var("DEP_LZMA_INCLUDE").map(PathBuf::from) {
        cfg.include(inc);
    }

    let use_curl = env::var("CARGO_FEATURE_CURL").is_ok();
    if !use_curl {
        let curl_patterns = vec!["s/ -lcurl//", "/#define HAVE_LIBCURL/d"];
        sed_htslib_makefile(&out, &curl_patterns, "curl");
    } else if let Ok(inc) = env::var("DEP_CURL_INCLUDE").map(PathBuf::from) {
        cfg.include(inc);
    }

    let tool = cfg.get_compiler();
    let (cc_path, cflags_env) = (tool.path(), tool.cflags_env());
    let cc_cflags = cflags_env.to_string_lossy().replace("-O0", "");
    if !Command::new("make")
        .current_dir(out.join("htslib"))
        .arg(format!("CC={}", cc_path.display()))
        .arg(format!("CFLAGS={}", cc_cflags))
        .arg("lib-static")
        .arg("-B")
        .status()
        .unwrap()
        .success()
    {
        panic!("failed to build htslib");
    }

    cfg.file("wrapper.c").compile("wrapper");

    bindgen::Builder::default()
        .header("wrapper.h")
        .generate_comments(false)
        .blacklist_function("strtold")
        .blacklist_type("max_align_t")
        .generate()
        .expect("Unable to generate bindings.")
        .write_to_file(out.join("bindings.rs"))
        .expect("Could not write bindings.");

    let include = out.join("include");
    fs::create_dir_all(&include).unwrap();
    if include.join("htslib").exists() {
        fs::remove_dir_all(include.join("htslib")).expect("remove exist include dir");
    }
    copy_directory(out.join("htslib").join("htslib"), &include).unwrap();
    fs::copy(out.join("htslib").join("libhts.a"), out.join("libhts.a")).unwrap();

    println!("cargo:root={}", out.display());
    println!("cargo:include={}", include.display());
    println!("cargo:libdir={}", out.display());
    println!("cargo:rustc-link-lib=static=hts");
    println!("cargo:rerun-if-changed=wrapper.c");
    println!("cargo:rerun-if-changed=wrapper.h");
    println!("cargo:rerun-if-changed=htslib/Makefile");
    let globs = std::iter::empty()
        .chain(glob("htslib/*.[ch]").unwrap())
        .chain(glob("htslib/cram/*.[ch]").unwrap())
        .chain(glob("htslib/htslib/*.h").unwrap())
        .chain(glob("htslib/os/*.[ch]").unwrap())
        .filter_map(Result::ok);
    for htsfile in globs {
        println!("cargo:rerun-if-changed={}", htsfile.display());
    }
}
<|endoftext|>


<commit_before>#![feature(augmented_assignments)]

#![allow(dead_code)]
extern crate polydraw;

use std::i64;
use std::cmp::{min, max};

use polydraw::{Application, Renderer, Frame};
use polydraw::geom::point::Point;
use polydraw::geom::ring::Ring;
use polydraw::draw::RGB;

const DIV_PER_PIXEL: i64 = 1000;
const DOUBLE_PIXEL_AREA: i64 = DIV_PER_PIXEL * DIV_PER_PIXEL * 2;

#[inline]
fn to_px(v: i64) -> i64 {
   v / DIV_PER_PIXEL
}

#[inline]
fn from_px(v: i64) -> i64 {
   v as i64 * DIV_PER_PIXEL
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Poly {
   color: RGB,
   start: usize,
   end: usize,
}

impl Poly {
   #[inline]
   pub fn new(color: RGB, start: usize, end: usize) -> Self {
      Poly {
         color: color,
         start: start,
         end: end,
      }
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum EdgeType {
   Inclined,
   InclinedRev,
   Horizontal,
   HorizontalRev,
   Vertical,
   VerticalRev,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Edge {
   etype: EdgeType,
   points: usize,
}

impl Edge {
   #[inline]
   pub fn new(etype: EdgeType, points: usize) -> Self {
      Edge {
         etype: etype,
         points: points,
      }
   }

   #[inline]
   pub fn inclined(points: usize) -> Self {
      Edge::new(EdgeType::Inclined, points)
   }

   #[inline]
   pub fn inclined_rev(points: usize) -> Self {
      Edge::new(EdgeType::InclinedRev, points)
   }

   #[inline]
   pub fn horizontal(points: usize) -> Self {
      Edge::new(EdgeType::Horizontal, points)
   }

   #[inline]
   pub fn horizontal_rev(points: usize) -> Self {
      Edge::new(EdgeType::HorizontalRev, points)
   }

   #[inline]
   pub fn vertical(points: usize) -> Self {
      Edge::new(EdgeType::Vertical, points)
   }

   #[inline]
   pub fn vertical_rev(points: usize) -> Self {
      Edge::new(EdgeType::VerticalRev, points)
   }
}

impl Default for Edge {
   #[inline]
   fn default() -> Edge {
      Edge::inclined(0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct EdgePoints {
   p1: usize,
   p2: usize,
}

impl EdgePoints {
   #[inline]
   pub fn new(p1: usize, p2: usize) -> Self {
      EdgePoints {
         p1: p1,
         p2: p2,
      }
   }
}

impl Default for EdgePoints {
   #[inline]
   fn default() -> EdgePoints {
      EdgePoints::new(0, 0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct EdgePointsRef {
   p1: usize,
   p2: usize,
   s1: usize,
   s2: usize,
}

impl EdgePointsRef {
   #[inline]
   pub fn new(p1: usize, p2: usize, s1: usize, s2: usize) -> Self {
      EdgePointsRef {
         p1: p1,
         p2: p2,
         s1: s1,
         s2: s2,
      }
   }
}

impl Default for EdgePointsRef {
   #[inline]
   fn default() -> EdgePointsRef {
      EdgePointsRef::new(0, 0, 0, 0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct PolyRef {
   src: usize,
   start: usize,
   end: usize,
}

impl PolyRef {
   #[inline]
   pub fn new(src: usize, start: usize, end: usize) -> Self {
      PolyRef {
         src: src,
         start: start,
         end: end,
      }
   }
}

impl Default for PolyRef {
   #[inline]
   fn default() -> PolyRef {
      PolyRef::new(0, 0, 0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct PolyMinYRef {
   poly: usize,
   min_y: i64,
}

struct PolySource {
   polys: Vec<Poly>,
   edges: Vec<Edge>,
   edge_points: Vec<EdgePoints>,
   points: Vec<Point>,
}

impl PolySource {
   fn new() -> Self {
      let polys = vec![
         // A
         Poly::new(RGB::new(18, 78, 230), 0, 3),
         // B
         Poly::new(RGB::new(47, 11, 206), 3, 6),
         // C
         Poly::new(RGB::new(170, 44, 206), 6, 9),
         // D
         Poly::new(RGB::new(243, 0, 149), 9, 12),
         // E
         Poly::new(RGB::new(170, 36, 14), 12, 15),
         // F
         Poly::new(RGB::new(219, 65, 18), 15, 18),
         // G
         Poly::new(RGB::new(254, 185, 21), 18, 21),
         // H
         Poly::new(RGB::new(244, 239, 114), 21, 24),
         // I
         Poly::new(RGB::new(109, 233, 158), 24, 27),
         // J
         Poly::new(RGB::new(66, 222, 241), 27, 30),
      ];

      let edges = vec![
         // 0: A
         Edge::vertical(13),
         Edge::inclined_rev(0),
         Edge::inclined_rev(1),

         // 1: B
         Edge::inclined(1),
         Edge::inclined_rev(2),
         Edge::inclined_rev(3),

         // 2: C
         Edge::inclined(3),
         Edge::inclined_rev(4),
         Edge::horizontal_rev(14),

         // 3: D
         Edge::inclined(4),
         Edge::inclined(5),
         Edge::inclined_rev(6),

         // 4: E
         Edge::inclined(6),
         Edge::inclined(7),
         Edge::vertical_rev(15),

         // 5: F
         Edge::inclined(2),
         Edge::inclined(8),
         Edge::inclined_rev(9),

         // 6: G
         Edge::inclined(9),
         Edge::inclined_rev(10),
         Edge::inclined_rev(5),

         // 7: H
         Edge::inclined(0),
         Edge::inclined_rev(11),
         Edge::inclined_rev(8),

         // 8: I
         Edge::inclined(10),
         Edge::inclined(12),
         Edge::inclined_rev(7),

         // 9: J
         Edge::inclined(11),
         Edge::horizontal(16),
         Edge::inclined_rev(12),
      ];

      let edge_points = vec![
         EdgePoints::new(2, 1),  // 0
         EdgePoints::new(0, 2),  // 1
         EdgePoints::new(3, 2),  // 2
         EdgePoints::new(0, 3),  // 3
         EdgePoints::new(4, 3),  // 4
         EdgePoints::new(3, 5),  // 5
         EdgePoints::new(4, 5),  // 6
         EdgePoints::new(5, 6),  // 7
         EdgePoints::new(2, 7),  // 8
         EdgePoints::new(3, 7),  // 9
         EdgePoints::new(5, 7),  // 10
         EdgePoints::new(7, 1),  // 11
         EdgePoints::new(7, 6),  // 12
         EdgePoints::new(0, 1),  // 13
         EdgePoints::new(0, 4),  // 14
         EdgePoints::new(4, 6),  // 15
         EdgePoints::new(1, 6),  // 16
      ];

      let mut points = vec![
         Point::new(0, 0),   // 0
         Point::new(0, 10),  // 1
         Point::new(2, 5),   // 2
         Point::new(3, 1),   // 3
         Point::new(10, 0),  // 4
         Point::new(8, 5),   // 5
         Point::new(10, 10), // 6
         Point::new(7, 9),   // 7
      ];

      for point in &mut points {
         *point *= 50 * DIV_PER_PIXEL;
      }

      PolySource {
         polys: polys,
         edges: edges,
         edge_points: edge_points,
         points: points,
      }
   }

   pub fn polys_min_y(&self) -> Vec<PolyMinYRef> {
      let mut v = Vec::new();

      for (poly_index, poly) in self.polys.iter().enumerate() {
         let mut min_y = i64::MAX;

         for edge_index in poly.start..poly.end {
            let edge_points = self.edge_points[self.edges[edge_index].points];
            let y = min(
               self.points[edge_points.p1].y,
               self.points[edge_points.p2].y
            );

            if y < min_y {
               min_y = y;
            }
         }

         v.push(PolyMinYRef {
            poly: poly_index,
            min_y: min_y,
         });
      }

      v.sort_by(|a, b| a.min_y.cmp(&b.min_y));

      v
   }

   #[inline]
   fn min_max_x_y(&self) -> (i64, i64, i64, i64) {
      let mut min_x = i64::MAX;
      let mut min_y = i64::MAX;

      let mut max_x = i64::MIN;
      let mut max_y = i64::MIN;

      for p in &self.points {
         if p.x < min_x {
            min_x = p.x;
         }

         if p.y < min_y {
            min_y = p.y;
         }

         if p.x > max_x {
            max_x = p.x;
         }

         if p.y > max_y {
            max_y = p.y;
         }
      }

      (min_x, min_y, max_x, max_y)
   }
}

struct TriangleRenderer {
   src: PolySource,
   src_min_y: Vec<PolyMinYRef>,

   upper_polys: Ring<PolyRef>,
   upper_edges: Ring<Edge>,

   lower_polys: Ring<PolyRef>,
   lower_edges: Ring<Edge>,

   edge_points: Ring<EdgePointsRef>,
   points: Ring<Point>,
}

impl TriangleRenderer {
   fn new() -> Self {
      let src = PolySource::new();
      let src_min_y = src.polys_min_y();

      TriangleRenderer {
         src: src,
         src_min_y: src_min_y,

         upper_polys: Ring::new(65536),
         upper_edges: Ring::new(262144),

         lower_polys: Ring::new(65536),
         lower_edges: Ring::new(262144),

         edge_points: Ring::new(262144),
         points: Ring::new(262144),
      }
   }

   pub fn clear(&mut self) {
      self.upper_polys.clear();
      self.upper_edges.clear();

      self.lower_polys.clear();
      self.lower_edges.clear();

      self.edge_points.clear();
      self.points.clear();
   }
}

impl Renderer for TriangleRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.clear();

      let (min_x, min_y, max_x, max_y) = self.src.min_max_x_y();

      let min_x = max(to_px(min_x), 0);
      let min_y = max(to_px(min_y), 0);
      let max_x = min(to_px(max_x), frame.width as i64 - 1);
      let max_y = min(to_px(max_y), frame.height as i64 - 1);

      let back = RGB::new(1, 1, 1);

      for y in min_y..max_y + 1 {
         for x in min_x..max_x + 1 {
            frame.put_pixel(x as i32, y as i32, &back);
         }
      }
   }
}

fn main() {
   let mut renderer = TriangleRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Triangle3")
      .run();
}
<commit_msg>Function for transferring source polys and data to the working set<commit_after>#![feature(augmented_assignments)]

#![allow(dead_code)]
extern crate polydraw;

use std::i64;
use std::usize;
use std::cmp::{min, max};
use std::iter::repeat;
use std::fmt::Debug;

use polydraw::{Application, Renderer, Frame};
use polydraw::geom::point::Point;
use polydraw::geom::ring::Ring;
use polydraw::draw::RGB;

const DIV_PER_PIXEL: i64 = 1000;
const DOUBLE_PIXEL_AREA: i64 = DIV_PER_PIXEL * DIV_PER_PIXEL * 2;

#[inline]
fn to_px(v: i64) -> i64 {
   v / DIV_PER_PIXEL
}

#[inline]
fn from_px(v: i64) -> i64 {
   v as i64 * DIV_PER_PIXEL
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Poly {
   color: RGB,
   start: usize,
   end: usize,
}

impl Poly {
   #[inline]
   pub fn new(color: RGB, start: usize, end: usize) -> Self {
      Poly {
         color: color,
         start: start,
         end: end,
      }
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum EdgeType {
   Inclined,
   InclinedRev,
   Horizontal,
   HorizontalRev,
   Vertical,
   VerticalRev,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Edge {
   edge_type: EdgeType,
   points: usize,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, points: usize) -> Self {
      Edge {
         edge_type: edge_type,
         points: points,
      }
   }

   #[inline]
   pub fn inclined(points: usize) -> Self {
      Edge::new(EdgeType::Inclined, points)
   }

   #[inline]
   pub fn inclined_rev(points: usize) -> Self {
      Edge::new(EdgeType::InclinedRev, points)
   }

   #[inline]
   pub fn horizontal(points: usize) -> Self {
      Edge::new(EdgeType::Horizontal, points)
   }

   #[inline]
   pub fn horizontal_rev(points: usize) -> Self {
      Edge::new(EdgeType::HorizontalRev, points)
   }

   #[inline]
   pub fn vertical(points: usize) -> Self {
      Edge::new(EdgeType::Vertical, points)
   }

   #[inline]
   pub fn vertical_rev(points: usize) -> Self {
      Edge::new(EdgeType::VerticalRev, points)
   }
}

impl Default for Edge {
   #[inline]
   fn default() -> Edge {
      Edge::inclined(0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct EdgePoints {
   p1: usize,
   p2: usize,
}

impl EdgePoints {
   #[inline]
   pub fn new(p1: usize, p2: usize) -> Self {
      EdgePoints {
         p1: p1,
         p2: p2,
      }
   }
}

impl Default for EdgePoints {
   #[inline]
   fn default() -> EdgePoints {
      EdgePoints::new(0, 0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct EdgePointsRef {
   p1: usize,
   p2: usize,
   s1: usize,
   s2: usize,
}

impl EdgePointsRef {
   #[inline]
   pub fn new(p1: usize, p2: usize, s1: usize, s2: usize) -> Self {
      EdgePointsRef {
         p1: p1,
         p2: p2,
         s1: s1,
         s2: s2,
      }
   }
}

impl Default for EdgePointsRef {
   #[inline]
   fn default() -> EdgePointsRef {
      EdgePointsRef::new(0, 0, 0, 0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct PolyRef {
   src: usize,
   start: usize,
   end: usize,
}

impl PolyRef {
   #[inline]
   pub fn new(src: usize, start: usize, end: usize) -> Self {
      PolyRef {
         src: src,
         start: start,
         end: end,
      }
   }
}

impl Default for PolyRef {
   #[inline]
   fn default() -> PolyRef {
      PolyRef::new(0, 0, 0)
   }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct PolyMinYRef {
   poly: usize,
   min_y: i64,
}

struct PolySource {
   polys: Vec<Poly>,
   edges: Vec<Edge>,
   edge_points: Vec<EdgePoints>,
   points: Vec<Point>,
}

impl PolySource {
   fn new() -> Self {
      let polys = vec![
         // A
         Poly::new(RGB::new(18, 78, 230), 0, 3),
         // B
         Poly::new(RGB::new(47, 11, 206), 3, 6),
         // C
         Poly::new(RGB::new(170, 44, 206), 6, 9),
         // D
         Poly::new(RGB::new(243, 0, 149), 9, 12),
         // E
         Poly::new(RGB::new(170, 36, 14), 12, 15),
         // F
         Poly::new(RGB::new(219, 65, 18), 15, 18),
         // G
         Poly::new(RGB::new(254, 185, 21), 18, 21),
         // H
         Poly::new(RGB::new(244, 239, 114), 21, 24),
         // I
         Poly::new(RGB::new(109, 233, 158), 24, 27),
         // J
         Poly::new(RGB::new(66, 222, 241), 27, 30),
      ];

      let edges = vec![
         // 0: A
         Edge::vertical(13),
         Edge::inclined_rev(0),
         Edge::inclined_rev(1),

         // 1: B
         Edge::inclined(1),
         Edge::inclined_rev(2),
         Edge::inclined_rev(3),

         // 2: C
         Edge::inclined(3),
         Edge::inclined_rev(4),
         Edge::horizontal_rev(14),

         // 3: D
         Edge::inclined(4),
         Edge::inclined(5),
         Edge::inclined_rev(6),

         // 4: E
         Edge::inclined(6),
         Edge::inclined(7),
         Edge::vertical_rev(15),

         // 5: F
         Edge::inclined(2),
         Edge::inclined(8),
         Edge::inclined_rev(9),

         // 6: G
         Edge::inclined(9),
         Edge::inclined_rev(10),
         Edge::inclined_rev(5),

         // 7: H
         Edge::inclined(0),
         Edge::inclined_rev(11),
         Edge::inclined_rev(8),

         // 8: I
         Edge::inclined(10),
         Edge::inclined(12),
         Edge::inclined_rev(7),

         // 9: J
         Edge::inclined(11),
         Edge::horizontal(16),
         Edge::inclined_rev(12),
      ];

      let edge_points = vec![
         EdgePoints::new(2, 1),  // 0
         EdgePoints::new(0, 2),  // 1
         EdgePoints::new(3, 2),  // 2
         EdgePoints::new(0, 3),  // 3
         EdgePoints::new(4, 3),  // 4
         EdgePoints::new(3, 5),  // 5
         EdgePoints::new(4, 5),  // 6
         EdgePoints::new(5, 6),  // 7
         EdgePoints::new(2, 7),  // 8
         EdgePoints::new(3, 7),  // 9
         EdgePoints::new(5, 7),  // 10
         EdgePoints::new(7, 1),  // 11
         EdgePoints::new(7, 6),  // 12
         EdgePoints::new(0, 1),  // 13
         EdgePoints::new(0, 4),  // 14
         EdgePoints::new(4, 6),  // 15
         EdgePoints::new(1, 6),  // 16
      ];

      let mut points = vec![
         Point::new(0, 0),   // 0
         Point::new(0, 10),  // 1
         Point::new(2, 5),   // 2
         Point::new(3, 1),   // 3
         Point::new(10, 0),  // 4
         Point::new(8, 5),   // 5
         Point::new(10, 10), // 6
         Point::new(7, 9),   // 7
      ];

      for point in &mut points {
         *point *= 50 * DIV_PER_PIXEL;
      }

      PolySource {
         polys: polys,
         edges: edges,
         edge_points: edge_points,
         points: points,
      }
   }

   pub fn polys_min_y(&self) -> Vec<PolyMinYRef> {
      let mut v = Vec::new();

      for (poly_index, poly) in self.polys.iter().enumerate() {
         let mut min_y = i64::MAX;

         for edge_index in poly.start..poly.end {
            let edge_points = self.edge_points[self.edges[edge_index].points];
            let y = min(
               self.points[edge_points.p1].y,
               self.points[edge_points.p2].y
            );

            if y < min_y {
               min_y = y;
            }
         }

         v.push(PolyMinYRef {
            poly: poly_index,
            min_y: min_y,
         });
      }

      v.sort_by(|a, b| a.min_y.cmp(&b.min_y));

      v
   }

   #[inline]
   fn min_max_x_y(&self) -> (i64, i64, i64, i64) {
      let mut min_x = i64::MAX;
      let mut min_y = i64::MAX;

      let mut max_x = i64::MIN;
      let mut max_y = i64::MIN;

      for p in &self.points {
         if p.x < min_x {
            min_x = p.x;
         }

         if p.y < min_y {
            min_y = p.y;
         }

         if p.x > max_x {
            max_x = p.x;
         }

         if p.y > max_y {
            max_y = p.y;
         }
      }

      (min_x, min_y, max_x, max_y)
   }
}

struct TriangleRenderer {
   src: PolySource,
   src_min_y: Vec<PolyMinYRef>,
   src_poly_marker: usize,

   edge_points_map: Vec<usize>,
   points_map: Vec<usize>,

   upper_polys: Ring<PolyRef>,
   upper_edges: Ring<Edge>,

   lower_polys: Ring<PolyRef>,
   lower_edges: Ring<Edge>,

   edge_points: Ring<EdgePointsRef>,
   points: Ring<Point>,
}

impl TriangleRenderer {
   fn new() -> Self {
      let src = PolySource::new();
      let src_min_y = src.polys_min_y();

      let edge_points_map = repeat(usize::MAX).take(src.edge_points.len()).collect();
      let points_map = repeat(usize::MAX).take(src.points.len()).collect();

      TriangleRenderer {
         src: src,
         src_min_y: src_min_y,
         src_poly_marker: 0,

         edge_points_map: edge_points_map,
         points_map: points_map,

         upper_polys: Ring::new(65536),
         upper_edges: Ring::new(262144),

         lower_polys: Ring::new(65536),
         lower_edges: Ring::new(262144),

         edge_points: Ring::new(262144),
         points: Ring::new(262144),
      }
   }

   fn clear(&mut self) {
      self.upper_polys.clear();
      self.upper_edges.clear();

      self.lower_polys.clear();
      self.lower_edges.clear();

      self.edge_points.clear();
      self.points.clear();
   }

   fn transfer(&mut self, min_y: i64) {
      let end = self.src_min_y.len();

      for min_y_i in self.src_poly_marker..end {
         let poly_min_y = self.src_min_y[min_y_i];

         if poly_min_y.min_y != min_y {
            break;
         }

         self.transfer_poly(poly_min_y.poly);
      }
   }

   fn transfer_poly(&mut self, src_i: usize) {
      let poly = self.src.polys[src_i];

      let edge_start = self.upper_edges.end();

      for src_edge_i in poly.start..poly.end {
         self.transfer_edge(src_edge_i);
      }

      let edge_end = self.upper_edges.end();

      self.upper_polys.push(
         PolyRef::new(src_i, edge_start, edge_end)
      );
   }

   fn transfer_edge(&mut self, src_i: usize) {
      let edge = self.src.edges[src_i];

      let src_edge_points_i = edge.points;
      let mut edge_points_i = self.edge_points_map[src_edge_points_i];

      if edge_points_i == usize::MAX {
         let edge_points = self.src.edge_points[src_edge_points_i];

         let s1 = edge_points.p1;
         let s2 = edge_points.p2;

         let p1 = self.transfer_point(s1);
         let p2 = self.transfer_point(s2);

         edge_points_i = self.edge_points.end();

         self.edge_points.push(
            EdgePointsRef::new(p1, p2, s1, s2)
         );

         self.edge_points_map[src_edge_points_i] = edge_points_i;
      }

      self.upper_edges.push(
         Edge::new(edge.edge_type, edge_points_i)
      );
   }

   fn transfer_point(&mut self, src_i: usize) -> usize {
      let mut i = self.points_map[src_i];

      if i == usize::MAX {
         i = self.points.end();

         self.points_map[src_i] = i;

         self.points.push(
            self.src.points[src_i]
         );
      }

      i
   }
}

#[inline]
fn print_ring<T>(name: &str, ring: &Ring<T>) where T: Default + Clone + Debug {
   println!("{}: s {} e {} :", name, ring.start(), ring.end());

   for item in ring[..].iter() {
      println!("{:?}", item);
   }
}

impl Renderer for TriangleRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.clear();

      let (min_x, min_y, max_x, max_y) = self.src.min_max_x_y();

      let min_x = max(to_px(min_x), 0);
      let min_y = max(to_px(min_y), 0);
      let max_x = min(to_px(max_x), frame.width as i64 - 1);
      let max_y = min(to_px(max_y), frame.height as i64 - 1);

      let back = RGB::new(1, 1, 1);

      for y in min_y..max_y + 1 {
         self.transfer(y);

         for x in min_x..max_x + 1 {

            frame.put_pixel(x as i32, y as i32, &back);
         }
      }
   }
}

fn main() {
   let mut renderer = TriangleRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Triangle3")
      .run();
}
<|endoftext|>