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

//! The ChaCha random number generator.

use core::prelude::*;
use core::num::Int;

use {Rng, SeedableRng, Rand};

const KEY_WORDS    : uint =  8; // 8 words for the 256-bit key
const STATE_WORDS  : uint = 16;
const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of this writing

/// A random number generator that uses the ChaCha20 algorithm [1].
///
/// The ChaCha algorithm is widely accepted as suitable for
/// cryptographic purposes, but this implementation has not been
/// verified as such. Prefer a generator like `OsRng` that defers to
/// the operating system for cases that need high security.
///
/// [1]: D. J. Bernstein, [*ChaCha, a variant of
/// Salsa20*](http://cr.yp.to/chacha.html)

pub struct ChaChaRng {
    buffer:  [u32, ..STATE_WORDS], // Internal buffer of output
    state:   [u32, ..STATE_WORDS], // Initial state
    index:   uint,                 // Index into state
}

static EMPTY: ChaChaRng = ChaChaRng {
    buffer:  [0, ..STATE_WORDS],
    state:   [0, ..STATE_WORDS],
    index:   STATE_WORDS
};

macro_rules! quarter_round{
    ($a: expr, $b: expr, $c: expr, $d: expr) => {{
        $a += $b; $d ^= $a; $d = $d.rotate_left(16);
        $c += $d; $b ^= $c; $b = $b.rotate_left(12);
        $a += $b; $d ^= $a; $d = $d.rotate_left( 8);
        $c += $d; $b ^= $c; $b = $b.rotate_left( 7);
    }}
}

macro_rules! double_round{
    ($x: expr) => {{
        // Column round
        quarter_round!($x[ 0], $x[ 4], $x[ 8], $x[12]);
        quarter_round!($x[ 1], $x[ 5], $x[ 9], $x[13]);
        quarter_round!($x[ 2], $x[ 6], $x[10], $x[14]);
        quarter_round!($x[ 3], $x[ 7], $x[11], $x[15]);
        // Diagonal round
        quarter_round!($x[ 0], $x[ 5], $x[10], $x[15]);
        quarter_round!($x[ 1], $x[ 6], $x[11], $x[12]);
        quarter_round!($x[ 2], $x[ 7], $x[ 8], $x[13]);
        quarter_round!($x[ 3], $x[ 4], $x[ 9], $x[14]);
    }}
}

#[inline]
fn core(output: &mut [u32, ..STATE_WORDS], input: &[u32, ..STATE_WORDS]) {
    *output = *input;

    for _ in range(0, CHACHA_ROUNDS / 2) {
        double_round!(output);
    }

    for i in range(0, STATE_WORDS) {
        output[i] += input[i];
    }
}

impl ChaChaRng {

    /// Create an ChaCha random number generator using the default
    /// fixed key of 8 zero words.
    pub fn new_unseeded() -> ChaChaRng {
        let mut rng = EMPTY;
        rng.init(&[0, ..KEY_WORDS]);
        rng
    }

    /// Sets the internal 128-bit ChaCha counter to
    /// a user-provided value. This permits jumping
    /// arbitrarily ahead (or backwards) in the pseudorandom stream.
    ///
    /// Since the nonce words are used to extend the counter to 128 bits,
    /// users wishing to obtain the conventional ChaCha pseudorandom stream
    /// associated with a particular nonce can call this function with
    /// arguments `0, desired_nonce`.
    pub fn set_counter(&mut self, counter_low: u64, counter_high: u64) {
        self.state[12] = (counter_low >>  0) as u32;
        self.state[13] = (counter_low >> 32) as u32;
        self.state[14] = (counter_high >>  0) as u32;
        self.state[15] = (counter_high >> 32) as u32;
        self.index = STATE_WORDS; // force recomputation
    }

    /// Initializes `self.state` with the appropriate key and constants
    ///
    /// We deviate slightly from the ChaCha specification regarding
    /// the nonce, which is used to extend the counter to 128 bits.
    /// This is provably as strong as the original cipher, though,
    /// since any distinguishing attack on our variant also works
    /// against ChaCha with a chosen-nonce. See the XSalsa20 [1]
    /// security proof for a more involved example of this.
    ///
    /// The modified word layout is:
    /// ```notrust
    /// constant constant constant constant
    /// key      key      key      key
    /// key      key      key      key
    /// counter  counter  counter  counter
    /// ```
    /// [1]: Daniel J. Bernstein. [*Extending the Salsa20
    /// nonce.*](http://cr.yp.to/papers.html#xsalsa)
    fn init(&mut self, key: &[u32, ..KEY_WORDS]) {
        self.state[0] = 0x61707865;
        self.state[1] = 0x3320646E;
        self.state[2] = 0x79622D32;
        self.state[3] = 0x6B206574;

        for i in range(0, KEY_WORDS) {
            self.state[4+i] = key[i];
        }

        self.state[12] = 0;
        self.state[13] = 0;
        self.state[14] = 0;
        self.state[15] = 0;

        self.index = STATE_WORDS;
    }

    /// Refill the internal output buffer (`self.buffer`)
    fn update(&mut self) {
        core(&mut self.buffer, &self.state);
        self.index = 0;
        // update 128-bit counter
        self.state[12] += 1;
        if self.state[12] != 0 { return };
        self.state[13] += 1;
        if self.state[13] != 0 { return };
        self.state[14] += 1;
        if self.state[14] != 0 { return };
        self.state[15] += 1;
    }
}

impl Rng for ChaChaRng {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        if self.index == STATE_WORDS {
            self.update();
        }

        let value = self.buffer[self.index % STATE_WORDS];
        self.index += 1;
        value
    }
}

impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {

    fn reseed(&mut self, seed: &'a [u32]) {
        // reset state
        self.init(&[0u32, ..KEY_WORDS]);
        // set key in place
        let key = self.state.slice_mut(4, 4+KEY_WORDS);
        for (k, s) in key.iter_mut().zip(seed.iter()) {
            *k = *s;
        }
    }

    /// Create a ChaCha generator from a seed,
    /// obtained from a variable-length u32 array.
    /// Only up to 8 words are used; if less than 8
    /// words are used, the remaining are set to zero.
    fn from_seed(seed: &'a [u32]) -> ChaChaRng {
        let mut rng = EMPTY;
        rng.reseed(seed);
        rng
    }
}

impl Rand for ChaChaRng {
    fn rand<R: Rng>(other: &mut R) -> ChaChaRng {
        let mut key : [u32, ..KEY_WORDS] = [0, ..KEY_WORDS];
        for word in key.iter_mut() {
            *word = other.gen();
        }
        SeedableRng::from_seed(key.as_slice())
    }
}

#[cfg(test)]
mod test {
    use std::prelude::*;

    use core::iter::order;
    use {Rng, SeedableRng};
    use super::ChaChaRng;

    #[test]
    fn test_rng_rand_seeded() {
        let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
        let mut ra: ChaChaRng = SeedableRng::from_seed(s.as_slice());
        let mut rb: ChaChaRng = SeedableRng::from_seed(s.as_slice());
        assert!(order::equals(ra.gen_ascii_chars().take(100),
                              rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_seeded() {
        let seed : &[_] = &[0,1,2,3,4,5,6,7];
        let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
        let mut rb: ChaChaRng = SeedableRng::from_seed(seed);
        assert!(order::equals(ra.gen_ascii_chars().take(100),
                              rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_reseed() {
        let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
        let mut r: ChaChaRng = SeedableRng::from_seed(s.as_slice());
        let string1: String = r.gen_ascii_chars().take(100).collect();

        r.reseed(s.as_slice());

        let string2: String = r.gen_ascii_chars().take(100).collect();
        assert_eq!(string1, string2);
    }

    #[test]
    fn test_rng_true_values() {
        // Test vectors 1 and 2 from
        // http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
        let seed : &[_] = &[0u32, ..8];
        let mut ra: ChaChaRng = SeedableRng::from_seed(seed);

        let v = Vec::from_fn(16, |_| ra.next_u32());
        assert_eq!(v,
                   vec!(0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653,
                        0xb819d2bd, 0x1aed8da0, 0xccef36a8, 0xc70d778b,
                        0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8,
                        0xf4b8436a, 0x1ca11815, 0x69b687c3, 0x8665eeb2));

        let v = Vec::from_fn(16, |_| ra.next_u32());
        assert_eq!(v,
                   vec!(0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73,
                        0xa0290fcb, 0x6965e348, 0x3e53c612, 0xed7aee32,
                        0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874,
                        0x281fed31, 0x45fb0a51, 0x1f0ae1ac, 0x6f4d794b));

        let seed : &[_] = &[0,1,2,3,4,5,6,7];
        let mut ra: ChaChaRng = SeedableRng::from_seed(seed);

        // Store the 17*i-th 32-bit word,
        // i.e., the i-th word of the i-th 16-word block
        let mut v : Vec<u32> = Vec::new();
        for _ in range(0u, 16) {
            v.push(ra.next_u32());
            for _ in range(0u, 16) {
                ra.next_u32();
            }
        }

        assert_eq!(v,
                   vec!(0xf225c81a, 0x6ab1be57, 0x04d42951, 0x70858036,
                        0x49884684, 0x64efec72, 0x4be2d186, 0x3615b384,
                        0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530,
                        0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4));
    }
}

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

//! The ChaCha random number generator.

use core::prelude::*;
use core::num::Int;

use {Rng, SeedableRng, Rand};

const KEY_WORDS    : uint =  8; // 8 words for the 256-bit key
const STATE_WORDS  : uint = 16;
const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of this writing

/// A random number generator that uses the ChaCha20 algorithm [1].
///
/// The ChaCha algorithm is widely accepted as suitable for
/// cryptographic purposes, but this implementation has not been
/// verified as such. Prefer a generator like `OsRng` that defers to
/// the operating system for cases that need high security.
///
/// [1]: D. J. Bernstein, [*ChaCha, a variant of
/// Salsa20*](http://cr.yp.to/chacha.html)

pub struct ChaChaRng {
    buffer:  [u32, ..STATE_WORDS], // Internal buffer of output
    state:   [u32, ..STATE_WORDS], // Initial state
    index:   uint,                 // Index into state
}

static EMPTY: ChaChaRng = ChaChaRng {
    buffer:  [0, ..STATE_WORDS],
    state:   [0, ..STATE_WORDS],
    index:   STATE_WORDS
};

macro_rules! quarter_round{
    ($a: expr, $b: expr, $c: expr, $d: expr) => {{
        $a += $b; $d ^= $a; $d = $d.rotate_left(16);
        $c += $d; $b ^= $c; $b = $b.rotate_left(12);
        $a += $b; $d ^= $a; $d = $d.rotate_left( 8);
        $c += $d; $b ^= $c; $b = $b.rotate_left( 7);
    }}
}

macro_rules! double_round{
    ($x: expr) => {{
        // Column round
        quarter_round!($x[ 0], $x[ 4], $x[ 8], $x[12]);
        quarter_round!($x[ 1], $x[ 5], $x[ 9], $x[13]);
        quarter_round!($x[ 2], $x[ 6], $x[10], $x[14]);
        quarter_round!($x[ 3], $x[ 7], $x[11], $x[15]);
        // Diagonal round
        quarter_round!($x[ 0], $x[ 5], $x[10], $x[15]);
        quarter_round!($x[ 1], $x[ 6], $x[11], $x[12]);
        quarter_round!($x[ 2], $x[ 7], $x[ 8], $x[13]);
        quarter_round!($x[ 3], $x[ 4], $x[ 9], $x[14]);
    }}
}

#[inline]
fn core(output: &mut [u32, ..STATE_WORDS], input: &[u32, ..STATE_WORDS]) {
    *output = *input;

    for _ in range(0, CHACHA_ROUNDS / 2) {
        double_round!(output);
    }

    for i in range(0, STATE_WORDS) {
        output[i] += input[i];
    }
}

impl ChaChaRng {

    /// Create an ChaCha random number generator using the default
    /// fixed key of 8 zero words.
    pub fn new_unseeded() -> ChaChaRng {
        let mut rng = EMPTY;
        rng.init(&[0, ..KEY_WORDS]);
        rng
    }

    /// Sets the internal 128-bit ChaCha counter to
    /// a user-provided value. This permits jumping
    /// arbitrarily ahead (or backwards) in the pseudorandom stream.
    ///
    /// Since the nonce words are used to extend the counter to 128 bits,
    /// users wishing to obtain the conventional ChaCha pseudorandom stream
    /// associated with a particular nonce can call this function with
    /// arguments `0, desired_nonce`.
    pub fn set_counter(&mut self, counter_low: u64, counter_high: u64) {
        self.state[12] = (counter_low >>  0) as u32;
        self.state[13] = (counter_low >> 32) as u32;
        self.state[14] = (counter_high >>  0) as u32;
        self.state[15] = (counter_high >> 32) as u32;
        self.index = STATE_WORDS; // force recomputation
    }

    /// Initializes `self.state` with the appropriate key and constants
    ///
    /// We deviate slightly from the ChaCha specification regarding
    /// the nonce, which is used to extend the counter to 128 bits.
    /// This is provably as strong as the original cipher, though,
    /// since any distinguishing attack on our variant also works
    /// against ChaCha with a chosen-nonce. See the XSalsa20 [1]
    /// security proof for a more involved example of this.
    ///
    /// The modified word layout is:
    /// ```ignore
    /// constant constant constant constant
    /// key      key      key      key
    /// key      key      key      key
    /// counter  counter  counter  counter
    /// ```
    /// [1]: Daniel J. Bernstein. [*Extending the Salsa20
    /// nonce.*](http://cr.yp.to/papers.html#xsalsa)
    fn init(&mut self, key: &[u32, ..KEY_WORDS]) {
        self.state[0] = 0x61707865;
        self.state[1] = 0x3320646E;
        self.state[2] = 0x79622D32;
        self.state[3] = 0x6B206574;

        for i in range(0, KEY_WORDS) {
            self.state[4+i] = key[i];
        }

        self.state[12] = 0;
        self.state[13] = 0;
        self.state[14] = 0;
        self.state[15] = 0;

        self.index = STATE_WORDS;
    }

    /// Refill the internal output buffer (`self.buffer`)
    fn update(&mut self) {
        core(&mut self.buffer, &self.state);
        self.index = 0;
        // update 128-bit counter
        self.state[12] += 1;
        if self.state[12] != 0 { return };
        self.state[13] += 1;
        if self.state[13] != 0 { return };
        self.state[14] += 1;
        if self.state[14] != 0 { return };
        self.state[15] += 1;
    }
}

impl Rng for ChaChaRng {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        if self.index == STATE_WORDS {
            self.update();
        }

        let value = self.buffer[self.index % STATE_WORDS];
        self.index += 1;
        value
    }
}

impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {

    fn reseed(&mut self, seed: &'a [u32]) {
        // reset state
        self.init(&[0u32, ..KEY_WORDS]);
        // set key in place
        let key = self.state.slice_mut(4, 4+KEY_WORDS);
        for (k, s) in key.iter_mut().zip(seed.iter()) {
            *k = *s;
        }
    }

    /// Create a ChaCha generator from a seed,
    /// obtained from a variable-length u32 array.
    /// Only up to 8 words are used; if less than 8
    /// words are used, the remaining are set to zero.
    fn from_seed(seed: &'a [u32]) -> ChaChaRng {
        let mut rng = EMPTY;
        rng.reseed(seed);
        rng
    }
}

impl Rand for ChaChaRng {
    fn rand<R: Rng>(other: &mut R) -> ChaChaRng {
        let mut key : [u32, ..KEY_WORDS] = [0, ..KEY_WORDS];
        for word in key.iter_mut() {
            *word = other.gen();
        }
        SeedableRng::from_seed(key.as_slice())
    }
}

#[cfg(test)]
mod test {
    use std::prelude::*;

    use core::iter::order;
    use {Rng, SeedableRng};
    use super::ChaChaRng;

    #[test]
    fn test_rng_rand_seeded() {
        let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
        let mut ra: ChaChaRng = SeedableRng::from_seed(s.as_slice());
        let mut rb: ChaChaRng = SeedableRng::from_seed(s.as_slice());
        assert!(order::equals(ra.gen_ascii_chars().take(100),
                              rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_seeded() {
        let seed : &[_] = &[0,1,2,3,4,5,6,7];
        let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
        let mut rb: ChaChaRng = SeedableRng::from_seed(seed);
        assert!(order::equals(ra.gen_ascii_chars().take(100),
                              rb.gen_ascii_chars().take(100)));
    }

    #[test]
    fn test_rng_reseed() {
        let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
        let mut r: ChaChaRng = SeedableRng::from_seed(s.as_slice());
        let string1: String = r.gen_ascii_chars().take(100).collect();

        r.reseed(s.as_slice());

        let string2: String = r.gen_ascii_chars().take(100).collect();
        assert_eq!(string1, string2);
    }

    #[test]
    fn test_rng_true_values() {
        // Test vectors 1 and 2 from
        // http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
        let seed : &[_] = &[0u32, ..8];
        let mut ra: ChaChaRng = SeedableRng::from_seed(seed);

        let v = Vec::from_fn(16, |_| ra.next_u32());
        assert_eq!(v,
                   vec!(0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653,
                        0xb819d2bd, 0x1aed8da0, 0xccef36a8, 0xc70d778b,
                        0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8,
                        0xf4b8436a, 0x1ca11815, 0x69b687c3, 0x8665eeb2));

        let v = Vec::from_fn(16, |_| ra.next_u32());
        assert_eq!(v,
                   vec!(0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73,
                        0xa0290fcb, 0x6965e348, 0x3e53c612, 0xed7aee32,
                        0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874,
                        0x281fed31, 0x45fb0a51, 0x1f0ae1ac, 0x6f4d794b));

        let seed : &[_] = &[0,1,2,3,4,5,6,7];
        let mut ra: ChaChaRng = SeedableRng::from_seed(seed);

        // Store the 17*i-th 32-bit word,
        // i.e., the i-th word of the i-th 16-word block
        let mut v : Vec<u32> = Vec::new();
        for _ in range(0u, 16) {
            v.push(ra.next_u32());
            for _ in range(0u, 16) {
                ra.next_u32();
            }
        }

        assert_eq!(v,
                   vec!(0xf225c81a, 0x6ab1be57, 0x04d42951, 0x70858036,
                        0x49884684, 0x64efec72, 0x4be2d186, 0x3615b384,
                        0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530,
                        0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4));
    }
}

<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::mem::{self, size_of};
use std::ptr;
use window::Message::*;
use window::*;
use super::winapi::*;
use super::user32;

// use windows::winapi::winuser::RAWINPUTDEVICE;
// use windows::xinput::*;
//
// pub fn get_state(controller_index: DWORD) {
//     let mut state = XINPUT_STATE {
//         dwPacketNumber: 0,
//         Gamepad: XINPUT_GAMEPAD {
//             wButtons: 0,
//             bLeftTrigger: 0,
//             bRightTrigger: 0,
//             sThumbLX: 0,
//             sThumbLY: 0,
//             sThumbRX: 0,
//             sThumbRY: 0
//         }
//     };
//
//     // Simply get the state of the controller from XInput.
//     let result = unsafe { XInputGetState(controller_index, &mut state) };
//
//     println!("result: {}", result);
//
//     if (result == ERROR_SUCCESS) {
//         // Controller is connected
//     } else {
//         // Controller is not connected
//     }
// }

pub fn set_cursor_visibility(visible: bool) {
    unsafe { user32::ShowCursor(visible as i32); }
}

pub fn set_cursor_bounds(top: i32, left: i32, bottom: i32, right: i32) {
    let rect = RECT {
        top: top,
        left: left,
        bottom: bottom,
        right: right,
    };

    unsafe {
        user32::ClipCursor(&rect);
    }
}

pub fn clear_cursor_bounds() {
    unsafe {
        user32::ClipCursor(ptr::null());
    }
}

pub fn register_raw_input(hwnd: HWND) {
    let devices = RAWINPUTDEVICE {
        usUsagePage: 0x01,
        usUsage: 0x02,
        dwFlags: 0, //RIDEV_NOLEGACY,   // Adds HID mouse and also ignores legacy mouse messages.
        hwndTarget: hwnd
    };

    if unsafe { user32::RegisterRawInputDevices(&devices, 1, size_of::<RAWINPUTDEVICE>() as u32) } == FALSE {
        // Registration failed. Call GetLastError for the cause of the error.
        println!("WARNING: Raw input registration failed because reasons.");
    }
}

pub fn handle_raw_input(messages: &mut VecDeque<Message>, lParam: LPARAM) {
    // Call GetRawInputData once to get the size of the data.
    let mut size: UINT = 0;
    unsafe {
        user32::GetRawInputData(
            lParam as HRAWINPUT,
            RID_INPUT,
            ptr::null_mut(),
            &mut size,
            size_of::<RAWINPUTHEADER>() as u32);
    }

    let raw = unsafe {
        let mut raw = mem::uninitialized::<RAWINPUT>();
        assert!(
            user32::GetRawInputData(
                lParam as HRAWINPUT,
                RID_INPUT,
                ((&mut raw) as *mut RAWINPUT) as LPVOID,
                &mut size,
                size_of::<RAWINPUTHEADER>() as u32)
            == size);
        raw
    };

    let raw_mouse = unsafe { raw.mouse() };

    assert!(raw.header.dwType == RIM_TYPEMOUSE);
    assert!(raw_mouse.usFlags == MOUSE_MOVE_RELATIVE);

    messages.push_back(MouseMove(raw_mouse.lLastX, raw_mouse.lLastY));

    if raw_mouse.usButtonFlags != 0 {
        let button_flags = raw_mouse.usButtonFlags;
        if button_flags & RI_MOUSE_LEFT_BUTTON_DOWN != 0 {
            messages.push_back(MouseButtonPressed(0));
        }
        if button_flags & RI_MOUSE_LEFT_BUTTON_UP != 0 {
            messages.push_back(MouseButtonReleased(0));
        }
        if button_flags & RI_MOUSE_RIGHT_BUTTON_DOWN != 0 {
            messages.push_back(MouseButtonPressed(1));
        }
        if button_flags & RI_MOUSE_RIGHT_BUTTON_UP != 0 {
            messages.push_back(MouseButtonReleased(1));
        }
        if button_flags & RI_MOUSE_MIDDLE_BUTTON_DOWN != 0 {
            messages.push_back(MouseButtonPressed(2));
        }
        if button_flags & RI_MOUSE_MIDDLE_BUTTON_UP != 0 {
            messages.push_back(MouseButtonReleased(2));
        }
        if button_flags & RI_MOUSE_BUTTON_4_DOWN != 0 {
            messages.push_back(MouseButtonPressed(3));
        }
        if button_flags & RI_MOUSE_BUTTON_4_UP != 0 {
            messages.push_back(MouseButtonReleased(3));
        }
        if button_flags & RI_MOUSE_BUTTON_5_DOWN != 0 {
            messages.push_back(MouseButtonPressed(4));
        }
        if button_flags & RI_MOUSE_BUTTON_5_UP != 0 {
            messages.push_back(MouseButtonReleased(4));
        }
        if button_flags & RI_MOUSE_WHEEL != 0 {
            messages.push_back(MouseWheel(raw_mouse.usButtonData as i32))
        }
    }
}
<commit_msg>Fix mouse wheel handling on Windows<commit_after>use std::collections::VecDeque;
use std::mem::{self, size_of};
use std::ptr;
use window::Message::*;
use window::*;
use super::winapi::*;
use super::user32;

// use windows::winapi::winuser::RAWINPUTDEVICE;
// use windows::xinput::*;
//
// pub fn get_state(controller_index: DWORD) {
//     let mut state = XINPUT_STATE {
//         dwPacketNumber: 0,
//         Gamepad: XINPUT_GAMEPAD {
//             wButtons: 0,
//             bLeftTrigger: 0,
//             bRightTrigger: 0,
//             sThumbLX: 0,
//             sThumbLY: 0,
//             sThumbRX: 0,
//             sThumbRY: 0
//         }
//     };
//
//     // Simply get the state of the controller from XInput.
//     let result = unsafe { XInputGetState(controller_index, &mut state) };
//
//     println!("result: {}", result);
//
//     if (result == ERROR_SUCCESS) {
//         // Controller is connected
//     } else {
//         // Controller is not connected
//     }
// }

pub fn set_cursor_visibility(visible: bool) {
    unsafe { user32::ShowCursor(visible as i32); }
}

pub fn set_cursor_bounds(top: i32, left: i32, bottom: i32, right: i32) {
    let rect = RECT {
        top: top,
        left: left,
        bottom: bottom,
        right: right,
    };

    unsafe {
        user32::ClipCursor(&rect);
    }
}

pub fn clear_cursor_bounds() {
    unsafe {
        user32::ClipCursor(ptr::null());
    }
}

pub fn register_raw_input(hwnd: HWND) {
    let devices = RAWINPUTDEVICE {
        usUsagePage: 0x01,
        usUsage: 0x02,
        dwFlags: 0, //RIDEV_NOLEGACY,   // Adds HID mouse and also ignores legacy mouse messages.
        hwndTarget: hwnd
    };

    if unsafe { user32::RegisterRawInputDevices(&devices, 1, size_of::<RAWINPUTDEVICE>() as u32) } == FALSE {
        // Registration failed. Call GetLastError for the cause of the error.
        println!("WARNING: Raw input registration failed because reasons.");
    }
}

pub fn handle_raw_input(messages: &mut VecDeque<Message>, lParam: LPARAM) {
    // Call GetRawInputData once to get the size of the data.
    let mut size: UINT = 0;
    unsafe {
        user32::GetRawInputData(
            lParam as HRAWINPUT,
            RID_INPUT,
            ptr::null_mut(),
            &mut size,
            size_of::<RAWINPUTHEADER>() as u32);
    }

    let raw = unsafe {
        let mut raw = mem::uninitialized::<RAWINPUT>();
        assert!(
            user32::GetRawInputData(
                lParam as HRAWINPUT,
                RID_INPUT,
                ((&mut raw) as *mut RAWINPUT) as LPVOID,
                &mut size,
                size_of::<RAWINPUTHEADER>() as u32)
            == size);
        raw
    };

    let raw_mouse = unsafe { raw.mouse() };

    assert!(raw.header.dwType == RIM_TYPEMOUSE);
    assert!(raw_mouse.usFlags == MOUSE_MOVE_RELATIVE);

    messages.push_back(MouseMove(raw_mouse.lLastX, raw_mouse.lLastY));

    if raw_mouse.usButtonFlags != 0 {
        let button_flags = raw_mouse.usButtonFlags;
        if button_flags & RI_MOUSE_LEFT_BUTTON_DOWN != 0 {
            messages.push_back(MouseButtonPressed(0));
        }
        if button_flags & RI_MOUSE_LEFT_BUTTON_UP != 0 {
            messages.push_back(MouseButtonReleased(0));
        }
        if button_flags & RI_MOUSE_RIGHT_BUTTON_DOWN != 0 {
            messages.push_back(MouseButtonPressed(1));
        }
        if button_flags & RI_MOUSE_RIGHT_BUTTON_UP != 0 {
            messages.push_back(MouseButtonReleased(1));
        }
        if button_flags & RI_MOUSE_MIDDLE_BUTTON_DOWN != 0 {
            messages.push_back(MouseButtonPressed(2));
        }
        if button_flags & RI_MOUSE_MIDDLE_BUTTON_UP != 0 {
            messages.push_back(MouseButtonReleased(2));
        }
        if button_flags & RI_MOUSE_BUTTON_4_DOWN != 0 {
            messages.push_back(MouseButtonPressed(3));
        }
        if button_flags & RI_MOUSE_BUTTON_4_UP != 0 {
            messages.push_back(MouseButtonReleased(3));
        }
        if button_flags & RI_MOUSE_BUTTON_5_DOWN != 0 {
            messages.push_back(MouseButtonPressed(4));
        }
        if button_flags & RI_MOUSE_BUTTON_5_UP != 0 {
            messages.push_back(MouseButtonReleased(4));
        }
        if button_flags & RI_MOUSE_WHEEL != 0 {
            // NOTE: Mouse wheel handling is a bit of a nightmare. The raw input docs don't
            // specify anything meaningful about the data in `usButtonData`, but in practice it
            // seems to behave the same as the data for `WM_MOUSEWHEEL`, so that's how we interpret
            // it. The relevant docs are here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms645617.aspx

            // `usButtonData` is a u16, but if it represents a mouse wheel movement it's *actually*
            // signed, so we need to transmute it to treat it as signed.
            let scroll: i16 = unsafe { mem::transmute(raw_mouse.usButtonData) };

            // The high order 16 bits provides the distance the wheel was rotated in multiples of
            // `WHEEL_DELTA`, so we divide by `WHEEL_DELTA` to get the value we want.
            let scroll = scroll as i32 / WHEEL_DELTA as i32;

            messages.push_back(MouseWheel(scroll))
        }
    }
}
<|endoftext|>


<commit_before>//! mediasoup prelude.
//!
//! Re-exports commonly used traits and structs from this crate.
//!
//! # Examples
//!
//! Import the prelude with:
//!
//! ```
//! # #[allow(unused_imports)]
//! use mediasoup::prelude::*;
//! ```
pub use crate::worker_manager::WorkerManager;

pub use crate::worker::{Worker, WorkerSettings};

pub use crate::router::{
    PipeDataProducerToRouterError, PipeDataProducerToRouterPair, PipeProducerToRouterError,
    PipeProducerToRouterPair, PipeToRouterOptions, Router, RouterOptions,
};

pub use crate::direct_transport::{DirectTransport, DirectTransportOptions, WeakDirectTransport};
pub use crate::pipe_transport::{
    PipeTransport, PipeTransportOptions, PipeTransportRemoteParameters, WeakPipeTransport,
};
pub use crate::plain_transport::{
    PlainTransport, PlainTransportOptions, PlainTransportRemoteParameters, WeakPlainTransport,
};
pub use crate::transport::{
    ConsumeDataError, ConsumeError, ProduceDataError, ProduceError, Transport, TransportGeneric,
    TransportId,
};
pub use crate::webrtc_transport::{
    TransportListenIps, WebRtcTransport, WebRtcTransportOptions, WebRtcTransportRemoteParameters,
};

pub use crate::active_speaker_observer::{
    ActiveSpeakerObserver, ActiveSpeakerObserverDominantSpeaker, ActiveSpeakerObserverOptions,
    WeakActiveSpeakerObserver,
};
pub use crate::audio_level_observer::{
    AudioLevelObserver, AudioLevelObserverOptions, AudioLevelObserverVolume, WeakAudioLevelObserver,
};
pub use crate::rtp_observer::{RtpObserver, RtpObserverAddProducerOptions, RtpObserverId};

pub use crate::consumer::{Consumer, ConsumerId, ConsumerLayers, ConsumerOptions, WeakConsumer};
pub use crate::data_consumer::{
    DataConsumer, DataConsumerId, DataConsumerOptions, DirectDataConsumer, RegularDataConsumer,
    WeakDataConsumer,
};
pub use crate::data_producer::{
    DataProducer, DataProducerId, DataProducerOptions, DirectDataProducer, NonClosingDataProducer,
    RegularDataProducer, WeakDataProducer,
};
pub use crate::producer::{Producer, ProducerId, ProducerOptions, WeakProducer};

pub use crate::data_structures::{
    AppData, DtlsParameters, IceCandidate, IceParameters, ListenIp, WebRtcMessage,
};
pub use crate::rtp_parameters::{
    MediaKind, MimeTypeAudio, MimeTypeVideo, RtcpFeedback, RtpCapabilities,
    RtpCapabilitiesFinalized, RtpCodecCapability, RtpCodecParametersParameters, RtpParameters,
};
pub use crate::sctp_parameters::SctpStreamParameters;
pub use crate::srtp_parameters::SrtpCryptoSuite;
<commit_msg>Add WebRtcServer to prelude<commit_after>//! mediasoup prelude.
//!
//! Re-exports commonly used traits and structs from this crate.
//!
//! # Examples
//!
//! Import the prelude with:
//!
//! ```
//! # #[allow(unused_imports)]
//! use mediasoup::prelude::*;
//! ```
pub use crate::worker_manager::WorkerManager;

pub use crate::worker::{Worker, WorkerSettings};

pub use crate::router::{
    PipeDataProducerToRouterError, PipeDataProducerToRouterPair, PipeProducerToRouterError,
    PipeProducerToRouterPair, PipeToRouterOptions, Router, RouterOptions,
};

pub use crate::webrtc_server::{
    WebRtcServer, WebRtcServerId, WebRtcServerListenInfo, WebRtcServerListenInfos,
    WebRtcServerOptions,
};

pub use crate::direct_transport::{DirectTransport, DirectTransportOptions, WeakDirectTransport};
pub use crate::pipe_transport::{
    PipeTransport, PipeTransportOptions, PipeTransportRemoteParameters, WeakPipeTransport,
};
pub use crate::plain_transport::{
    PlainTransport, PlainTransportOptions, PlainTransportRemoteParameters, WeakPlainTransport,
};
pub use crate::transport::{
    ConsumeDataError, ConsumeError, ProduceDataError, ProduceError, Transport, TransportGeneric,
    TransportId,
};
pub use crate::webrtc_transport::{
    TransportListenIps, WebRtcTransport, WebRtcTransportOptions, WebRtcTransportRemoteParameters,
};

pub use crate::active_speaker_observer::{
    ActiveSpeakerObserver, ActiveSpeakerObserverDominantSpeaker, ActiveSpeakerObserverOptions,
    WeakActiveSpeakerObserver,
};
pub use crate::audio_level_observer::{
    AudioLevelObserver, AudioLevelObserverOptions, AudioLevelObserverVolume, WeakAudioLevelObserver,
};
pub use crate::rtp_observer::{RtpObserver, RtpObserverAddProducerOptions, RtpObserverId};

pub use crate::consumer::{Consumer, ConsumerId, ConsumerLayers, ConsumerOptions, WeakConsumer};
pub use crate::data_consumer::{
    DataConsumer, DataConsumerId, DataConsumerOptions, DirectDataConsumer, RegularDataConsumer,
    WeakDataConsumer,
};
pub use crate::data_producer::{
    DataProducer, DataProducerId, DataProducerOptions, DirectDataProducer, NonClosingDataProducer,
    RegularDataProducer, WeakDataProducer,
};
pub use crate::producer::{Producer, ProducerId, ProducerOptions, WeakProducer};

pub use crate::data_structures::{
    AppData, DtlsParameters, IceCandidate, IceParameters, ListenIp, WebRtcMessage,
};
pub use crate::rtp_parameters::{
    MediaKind, MimeTypeAudio, MimeTypeVideo, RtcpFeedback, RtpCapabilities,
    RtpCapabilitiesFinalized, RtpCodecCapability, RtpCodecParametersParameters, RtpParameters,
};
pub use crate::sctp_parameters::SctpStreamParameters;
pub use crate::srtp_parameters::SrtpCryptoSuite;
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

extern crate semver;
extern crate clap;
extern crate toml;
extern crate url;
#[macro_use] extern crate log;
#[macro_use] extern crate version;

extern crate libimagrt;
extern crate libimagmail;
extern crate libimagerror;
extern crate libimagutil;
extern crate libimagref;

use libimagutil::debug_result::*;
use libimagutil::info_result::*;
use libimagref::reference::Ref;

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup("imag-mail",
                                    &version!()[..],
                                    "Mail collection tool",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "import-mail" => import_mail(&rt),
                "list"        => list(&rt),
                "mail-store"  => mail_store(&rt),
                _             => debug!("Unknown command") // More error handling
            }
        });
}

fn import_mail(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("import-mail").unwrap();
    let path = scmd.value_of("path").unwrap(); // enforced by clap

    Mail::import_from_path(rt.store(), path)
        .map_err_trace()
        .map_info_str("Ok");
}

fn list(rt: &Runtime) {
    use libimagmail::error::MailErrorKind as MEK;
    use libimagmail::error::MapErrInto;

    let scmd = rt.cli().subcommand_matches("list").unwrap();
    let do_check_dead            = scmd.is_present("check-dead");
    let do_check_changed         = scmd.is_present("check-changed");
    let do_check_changed_content = scmd.is_present("check-changed-content");
    let do_check_changed_permiss = scmd.is_present("check-changed-permissions");
    let store = rt.store();

    let iter = match store.retrieve_for_module("ref") {
        Ok(iter) => iter.filter_map(|id| {
            Ref::get(store, id)
                .map_err_into(MEK::RefHandlingError)
                .and_then(|rf| Mail::from_ref(rf))
                .map_err_trace()
                .ok()
        }),
        Err(e)   => trace_error_exit(&e, 1),
    };

    fn list_mail(m: Mail) {
        unimplemented!()
    }

    // TODO: Implement lister type in libimagmail for this
    for mail in iter {
        list_mail(mail)
    }
}

fn mail_store(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("mail-store").unwrap();
    error!("This feature is currently not implemented.");
    unimplemented!()
}

<commit_msg>Add imports<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

extern crate semver;
extern crate clap;
extern crate toml;
extern crate url;
#[macro_use] extern crate log;
#[macro_use] extern crate version;

extern crate libimagrt;
extern crate libimagmail;
extern crate libimagerror;
extern crate libimagutil;
extern crate libimagref;

use libimagerror::trace::{MapErrTrace, trace_error, trace_error_exit};
use libimagmail::mail::Mail;
use libimagref::reference::Ref;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagutil::debug_result::*;
use libimagutil::info_result::*;

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup("imag-mail",
                                    &version!()[..],
                                    "Mail collection tool",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "import-mail" => import_mail(&rt),
                "list"        => list(&rt),
                "mail-store"  => mail_store(&rt),
                _             => debug!("Unknown command") // More error handling
            }
        });
}

fn import_mail(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("import-mail").unwrap();
    let path = scmd.value_of("path").unwrap(); // enforced by clap

    Mail::import_from_path(rt.store(), path)
        .map_err_trace()
        .map_info_str("Ok");
}

fn list(rt: &Runtime) {
    use libimagmail::error::MailErrorKind as MEK;
    use libimagmail::error::MapErrInto;

    let scmd = rt.cli().subcommand_matches("list").unwrap();
    let do_check_dead            = scmd.is_present("check-dead");
    let do_check_changed         = scmd.is_present("check-changed");
    let do_check_changed_content = scmd.is_present("check-changed-content");
    let do_check_changed_permiss = scmd.is_present("check-changed-permissions");
    let store = rt.store();

    let iter = match store.retrieve_for_module("ref") {
        Ok(iter) => iter.filter_map(|id| {
            Ref::get(store, id)
                .map_err_into(MEK::RefHandlingError)
                .and_then(|rf| Mail::from_ref(rf))
                .map_err_trace()
                .ok()
        }),
        Err(e)   => trace_error_exit(&e, 1),
    };

    fn list_mail(m: Mail) {
        unimplemented!()
    }

    // TODO: Implement lister type in libimagmail for this
    for mail in iter {
        list_mail(mail)
    }
}

fn mail_store(rt: &Runtime) {
    let scmd = rt.cli().subcommand_matches("mail-store").unwrap();
    error!("This feature is currently not implemented.");
    unimplemented!()
}

<|endoftext|>


<commit_before>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;

use task_hookrs::import::import_tasks;
use task_hookrs::status::TaskStatus;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagtodo::task::Task;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let rt = generate_runtime_setup("imag-todo",
                                    &version!()[..],
                                    "Interface with taskwarrior",
                                    build_ui);

    match rt.cli().subcommand_name() {
        Some("tw-hook") => tw_hook(&rt),
        Some("list") => list(&rt),
        _ => unreachable!(),
    } // end match scmd
} // end main

fn tw_hook(rt: &Runtime) {
    let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
    if subcmd.is_present("add") {
        let stdin = stdin();
        let stdin = stdin.lock();

        match Task::import(rt.store(), stdin) {
            Ok((_, uuid)) => info!("Task {} stored in imag", uuid),
            Err(e) => {
                trace_error(&e);
                exit(1);
            }
        }
    } else if subcmd.is_present("delete") {
        // The used hook is "on-modify". This hook gives two json-objects
        // per usage und wants one (the second one) back.
        let stdin         = stdin();
        let stdin         = stdin.lock();

        match import_tasks(stdin) {
            Ok(ttasks) => for (counter, ttask) in ttasks.iter().enumerate() {
                if counter % 2 == 1 {
                    // Only every second task is needed, the first one is the
                    // task before the change, and the second one after
                    // the change. The (maybe modified) second one is
                    // expected by taskwarrior.
                    match serde_json::ser::to_string(&ttask) {
                        Ok(val) => println!("{}", val),
                        Err(e) => {
                            trace_error(&e);
                            exit(1);
                        }
                    }

                    if *ttask.status() == TaskStatus::Deleted {
                        match Task::delete_by_uuid(rt.store(), *ttask.uuid()) {
                            Ok(_) => println!("Deleted task {}", *ttask.uuid()),
                            Err(e) => {
                                trace_error(&e);
                                exit(1);
                            }
                        }
                    }
                } // end if c % 2
            },
            Err(e) => {
                trace_error(&e);
                exit(1);
            },
        }
    } else {
        // Should not be possible, as one argument is required via
        // ArgGroup
        unreachable!();
    }
}

fn list(rt: &Runtime) {
    let subcmd   = rt.cli().subcommand_matches("list").unwrap();
    let mut args = Vec::new();
    let verbose  = subcmd.is_present("verbose");
    let iter     = match Task::all(rt.store()) {
        Ok(iter) => iter,
        Err(e)   => {
            trace_error(&e);
            exit(1);
        },
    };

    for task in iter {
        match task {
            Ok(val) => {
                let uuid = match val.get_header().read("todo.uuid") {
                    Ok(Some(u)) => u,
                    Ok(None)    => continue,
                    Err(e)      => {
                        trace_error(&e);
                        continue;
                    }
                };

                if verbose {
                    args.clear();
                    args.push(format!("uuid:{} information", uuid));

                    let tw_process = Command::new("task")
                        .stdin(Stdio::null())
                        .args(&args)
                        .spawn()
                        .unwrap_or_else(|e| {
                            trace_error(&e);
                            panic!("failed");
                        });
                    let output = tw_process
                        .wait_with_output()
                        .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e));
                    let outstring = String::from_utf8(output.stdout)
                        .unwrap_or_else(|e| panic!("failed to execute: {}", e));

                    println!("{}", outstring);
                } else {
                    println!("{}", match uuid {
                        toml::Value::String(s) => s,
                        _ => {
                            error!("Unexpected type for todo.uuid: {}", uuid);
                            continue;
                        },
                    });
                }
            }
            Err(e) => {
                trace_error(&e);
                continue;
            }
        } // end match task
    } // end for
}

<commit_msg>Reimplement list()<commit_after>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;

use toml::Value;

use task_hookrs::import::import_tasks;
use task_hookrs::status::TaskStatus;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagtodo::task::Task;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let rt = generate_runtime_setup("imag-todo",
                                    &version!()[..],
                                    "Interface with taskwarrior",
                                    build_ui);

    match rt.cli().subcommand_name() {
        Some("tw-hook") => tw_hook(&rt),
        Some("list") => list(&rt),
        _ => unreachable!(),
    } // end match scmd
} // end main

fn tw_hook(rt: &Runtime) {
    let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
    if subcmd.is_present("add") {
        let stdin = stdin();
        let stdin = stdin.lock();

        match Task::import(rt.store(), stdin) {
            Ok((_, uuid)) => info!("Task {} stored in imag", uuid),
            Err(e) => {
                trace_error(&e);
                exit(1);
            }
        }
    } else if subcmd.is_present("delete") {
        // The used hook is "on-modify". This hook gives two json-objects
        // per usage und wants one (the second one) back.
        let stdin         = stdin();
        let stdin         = stdin.lock();

        match import_tasks(stdin) {
            Ok(ttasks) => for (counter, ttask) in ttasks.iter().enumerate() {
                if counter % 2 == 1 {
                    // Only every second task is needed, the first one is the
                    // task before the change, and the second one after
                    // the change. The (maybe modified) second one is
                    // expected by taskwarrior.
                    match serde_json::ser::to_string(&ttask) {
                        Ok(val) => println!("{}", val),
                        Err(e) => {
                            trace_error(&e);
                            exit(1);
                        }
                    }

                    if *ttask.status() == TaskStatus::Deleted {
                        match Task::delete_by_uuid(rt.store(), *ttask.uuid()) {
                            Ok(_) => println!("Deleted task {}", *ttask.uuid()),
                            Err(e) => {
                                trace_error(&e);
                                exit(1);
                            }
                        }
                    }
                } // end if c % 2
            },
            Err(e) => {
                trace_error(&e);
                exit(1);
            },
        }
    } else {
        // Should not be possible, as one argument is required via
        // ArgGroup
        unreachable!();
    }
}

fn list(rt: &Runtime) {
    let subcmd  = rt.cli().subcommand_matches("list").unwrap();
    let verbose = subcmd.is_present("verbose");

    let res = Task::all(rt.store())
        .map(|iter| {
            let uuids : Vec<_> = iter.filter_map(|t| match t {
                Ok(v) => match v.get_header().read("todo.uuid") {
                    Ok(Some(Value::String(ref u))) => Some(u.clone()),
                    Ok(Some(_)) => {
                        warn!("Header type error");
                        None
                    },
                    Ok(None) => None,
                    Err(e) => {
                        trace_error(&e);
                        None
                    }
                },
                Err(e) => {
                    trace_error(&e);
                    None
                }
            })
            .collect();

            let outstring = if verbose {
                let output = Command::new("task")
                    .stdin(Stdio::null())
                    .args(&uuids)
                    .spawn()
                    .unwrap_or_else(|e| {
                        trace_error(&e);
                        panic!("Failed to execute `task` on the commandline. I'm dying now.");
                    })
                    .wait_with_output()
                    .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e));

                String::from_utf8(output.stdout)
                    .unwrap_or_else(|e| panic!("failed to execute: {}", e))
            } else {
                uuids.join("\n")
            };

            println!("{}", outstring);
        });

    if let Err(e) = res {
        trace_error(&e);
    }
}

<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// 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 std::ascii::AsciiExt;
use std::str;

use super::Input;

/// A `struct` useful for matching in-memory `String`s.
///
/// # Examples
///
/// ```
/// # use pest::{Input, StringInput};
/// let input = StringInput::new("asdasdf");
///
/// assert!(input.match_string("asd", 0));
/// assert!(input.match_string("asd", 3));
/// assert!(!input.match_string("asd", 4));
/// ```
pub struct StringInput<'a> {
    string: &'a str
}

impl<'a> StringInput<'a> {
    /// Creates a new `StringInput` from a `&str`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use pest::{Input, StringInput};
    /// let input = StringInput::new("asd");
    ///
    /// assert_eq!(input.len(), 3);
    /// ```
    pub fn new(string: &str) -> StringInput {
        StringInput {
            string: string
        }
    }
}

impl<'a> Input for StringInput<'a> {
    #[inline]
    fn len(&self) -> usize {
        self.string.len()
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.string.is_empty()
    }

    #[inline]
    fn slice(&self, start: usize, end: usize) -> &str {
        &self.string[start..end]
    }

    #[inline]
    unsafe fn slice_unchecked(&self, start: usize, end: usize) -> &str {
        self.string.slice_unchecked(start, end)
    }

    #[inline]
    fn line_col(&self, pos: usize) -> (usize, usize) {
        if pos > self.string.len() {
            panic!("position out of bounds");
        }

        let mut pos = pos;
        let slice = &self.string[..pos];
        let mut chars = slice.chars().peekable();

        let mut line_col = (1, 1);

        while pos != 0 {
            match chars.next() {
                Some('\r') => {
                    if let Some(&'\n') = chars.peek() {
                        chars.next();

                        if pos == 1 {
                            pos -= 1;
                            line_col = (line_col.0 + 1, 1);
                        } else {
                            pos -= 2;
                            line_col = (line_col.0 + 1, 1);
                        }
                    } else {
                        pos -= 1;
                        line_col = (line_col.0, line_col.1 + 1);
                    }
                }
                Some('\n') => {
                    pos -= 1;
                    line_col = (line_col.0 + 1, 1);
                },
                Some(c) => {
                    pos -= c.len_utf8();
                    line_col = (line_col.0, line_col.1 + 1);
                },
                None => unreachable!(),
            }
        }

        line_col
    }

    #[inline]
    fn line_of(&self, mut pos: usize) -> &str {
        if pos > self.string.len() {
            panic!("position out of bounds");
        }

        if unsafe { self.string.slice_unchecked(pos, pos + 1) == "\n" } {
            pos -= 1;
        }

        let start = self.string.char_indices()
                               .rev()
                               .skip_while(|&(i, _)| i > pos)
                               .find(|&(_, c)| c == '\n');
        let start = match start {
            Some((i, _)) => i + 1,
            None         => 0
        };

        let end = self.string.char_indices()
                             .skip_while(|&(i, _)| i < pos)
                             .find(|&(_, c)| c == '\n');
        let mut end = match end {
            Some((i, _)) => i,
            None         => self.string.len()
        };
        if end > 0 && unsafe { self.string.slice_unchecked(end - 1, end) == "\r" } {
            end -= 1;
        }

        unsafe { self.string.slice_unchecked(start, end) }
    }

    #[inline]
    fn match_string(&self, string: &str, pos: usize) -> bool {
        let to = pos + string.len();

        if to <= self.string.len() {
            let slice = unsafe { self.string.slice_unchecked(pos, to) };
            slice == string
        } else {
            false
        }
    }

    #[inline]
    fn match_insensitive(&self, string: &str, pos: usize) -> bool {
        let slice = unsafe { self.string.slice_unchecked(pos, self.string.len()) };

        if slice.is_char_boundary(string.len()) {
            let slice = unsafe { slice.slice_unchecked(0, string.len()) };
            slice.eq_ignore_ascii_case(string)
        } else {
            false
        }
    }

    #[inline]
    fn match_range(&self, left: char, right: char, pos: usize) -> bool {
        let len = left.len_utf8();

        if len != right.len_utf8() {
            panic!("ranges should have same-sized UTF-8 limits");
        }

        let to = pos + len;

        if to <= self.string.len() {
            if let Ok(string) = str::from_utf8(&self.string.as_bytes()[pos..to]) {
                let c = string.chars().next().unwrap();

                left <= c && c <= right
            } else {
                false
            }
        } else {
            false
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn empty() {
        let input = StringInput::new("");

        assert!(input.is_empty());
        assert!(input.match_string("", 0));
        assert!(!input.match_string("a", 0));
    }

    #[test]
    fn parts() {
        let input = StringInput::new("asdasdf");

        assert!(!input.is_empty());
        assert!(input.match_string("asd", 0));
        assert!(input.match_string("asdf", 3));
    }

    #[test]
    fn len() {
        assert_eq!(StringInput::new("asdasdf").len(), 7);
    }

    #[test]
    fn slice() {
        let input = StringInput::new("asdasdf");

        assert_eq!(input.slice(1, 3), "sd");
    }

    #[test]
    fn line_col() {
        let input = StringInput::new("a\rb\nc\r\nd嗨");

        assert_eq!(input.line_col(0), (1, 1));
        assert_eq!(input.line_col(1), (1, 2));
        assert_eq!(input.line_col(2), (1, 3));
        assert_eq!(input.line_col(3), (1, 4));
        assert_eq!(input.line_col(4), (2, 1));
        assert_eq!(input.line_col(5), (2, 2));
        assert_eq!(input.line_col(6), (2, 3));
        assert_eq!(input.line_col(7), (3, 1));
        assert_eq!(input.line_col(8), (3, 2));
        assert_eq!(input.line_col(11), (3, 3));
    }

    #[test]
    fn line_of() {
        let input = StringInput::new("a\rb\nc\r\nd嗨");

        assert_eq!(input.line_of(0), "a\rb");
        assert_eq!(input.line_of(1), "a\rb");
        assert_eq!(input.line_of(2), "a\rb");
        assert_eq!(input.line_of(3), "a\rb");
        assert_eq!(input.line_of(4), "c");
        assert_eq!(input.line_of(5), "c");
        assert_eq!(input.line_of(6), "c");
        assert_eq!(input.line_of(7), "d嗨");
        assert_eq!(input.line_of(8), "d嗨");
        assert_eq!(input.line_of(11), "d嗨");
    }

    #[test]
    fn match_range() {
        let input = StringInput::new("b");

        assert!(input.match_range('a', 'c', 0));
        assert!(input.match_range('b', 'b', 0));
        assert!(!input.match_range('a', 'a', 0));
        assert!(!input.match_range('c', 'c', 0));
    }

    #[test]
    fn match_insensitive() {
        let input = StringInput::new("AsdASdF");

        assert!(input.match_insensitive("asd", 0));
        assert!(input.match_insensitive("asdf", 3));
    }
}
<commit_msg>Added support for unicode ranges. Fixes #94.<commit_after>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// 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 std::ascii::AsciiExt;
use std::str;

use super::Input;

/// A `struct` useful for matching in-memory `String`s.
///
/// # Examples
///
/// ```
/// # use pest::{Input, StringInput};
/// let input = StringInput::new("asdasdf");
///
/// assert!(input.match_string("asd", 0));
/// assert!(input.match_string("asd", 3));
/// assert!(!input.match_string("asd", 4));
/// ```
pub struct StringInput<'a> {
    string: &'a str
}

impl<'a> StringInput<'a> {
    /// Creates a new `StringInput` from a `&str`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use pest::{Input, StringInput};
    /// let input = StringInput::new("asd");
    ///
    /// assert_eq!(input.len(), 3);
    /// ```
    pub fn new(string: &str) -> StringInput {
        StringInput {
            string: string
        }
    }
}

impl<'a> Input for StringInput<'a> {
    #[inline]
    fn len(&self) -> usize {
        self.string.len()
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.string.is_empty()
    }

    #[inline]
    fn slice(&self, start: usize, end: usize) -> &str {
        &self.string[start..end]
    }

    #[inline]
    unsafe fn slice_unchecked(&self, start: usize, end: usize) -> &str {
        self.string.slice_unchecked(start, end)
    }

    #[inline]
    fn line_col(&self, pos: usize) -> (usize, usize) {
        if pos > self.string.len() {
            panic!("position out of bounds");
        }

        let mut pos = pos;
        let slice = &self.string[..pos];
        let mut chars = slice.chars().peekable();

        let mut line_col = (1, 1);

        while pos != 0 {
            match chars.next() {
                Some('\r') => {
                    if let Some(&'\n') = chars.peek() {
                        chars.next();

                        if pos == 1 {
                            pos -= 1;
                            line_col = (line_col.0 + 1, 1);
                        } else {
                            pos -= 2;
                            line_col = (line_col.0 + 1, 1);
                        }
                    } else {
                        pos -= 1;
                        line_col = (line_col.0, line_col.1 + 1);
                    }
                }
                Some('\n') => {
                    pos -= 1;
                    line_col = (line_col.0 + 1, 1);
                },
                Some(c) => {
                    pos -= c.len_utf8();
                    line_col = (line_col.0, line_col.1 + 1);
                },
                None => unreachable!(),
            }
        }

        line_col
    }

    #[inline]
    fn line_of(&self, mut pos: usize) -> &str {
        if pos > self.string.len() {
            panic!("position out of bounds");
        }

        if unsafe { self.string.slice_unchecked(pos, pos + 1) == "\n" } {
            pos -= 1;
        }

        let start = self.string.char_indices()
                               .rev()
                               .skip_while(|&(i, _)| i > pos)
                               .find(|&(_, c)| c == '\n');
        let start = match start {
            Some((i, _)) => i + 1,
            None         => 0
        };

        let end = self.string.char_indices()
                             .skip_while(|&(i, _)| i < pos)
                             .find(|&(_, c)| c == '\n');
        let mut end = match end {
            Some((i, _)) => i,
            None         => self.string.len()
        };
        if end > 0 && unsafe { self.string.slice_unchecked(end - 1, end) == "\r" } {
            end -= 1;
        }

        unsafe { self.string.slice_unchecked(start, end) }
    }

    #[inline]
    fn match_string(&self, string: &str, pos: usize) -> bool {
        let to = pos + string.len();

        if to <= self.string.len() {
            let slice = unsafe { self.string.slice_unchecked(pos, to) };
            slice == string
        } else {
            false
        }
    }

    #[inline]
    fn match_insensitive(&self, string: &str, pos: usize) -> bool {
        let slice = unsafe { self.string.slice_unchecked(pos, self.string.len()) };

        if slice.is_char_boundary(string.len()) {
            let slice = unsafe { slice.slice_unchecked(0, string.len()) };
            slice.eq_ignore_ascii_case(string)
        } else {
            false
        }
    }

    #[inline]
    fn match_range(&self, left: char, right: char, pos: usize) -> bool {
        let slice = unsafe { self.string.slice_unchecked(pos, self.string.len()) };

        if let Some(char) = slice.chars().next() {
            left <= char && char <= right
        } else {
            false
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn empty() {
        let input = StringInput::new("");

        assert!(input.is_empty());
        assert!(input.match_string("", 0));
        assert!(!input.match_string("a", 0));
    }

    #[test]
    fn parts() {
        let input = StringInput::new("asdasdf");

        assert!(!input.is_empty());
        assert!(input.match_string("asd", 0));
        assert!(input.match_string("asdf", 3));
    }

    #[test]
    fn len() {
        assert_eq!(StringInput::new("asdasdf").len(), 7);
    }

    #[test]
    fn slice() {
        let input = StringInput::new("asdasdf");

        assert_eq!(input.slice(1, 3), "sd");
    }

    #[test]
    fn line_col() {
        let input = StringInput::new("a\rb\nc\r\nd嗨");

        assert_eq!(input.line_col(0), (1, 1));
        assert_eq!(input.line_col(1), (1, 2));
        assert_eq!(input.line_col(2), (1, 3));
        assert_eq!(input.line_col(3), (1, 4));
        assert_eq!(input.line_col(4), (2, 1));
        assert_eq!(input.line_col(5), (2, 2));
        assert_eq!(input.line_col(6), (2, 3));
        assert_eq!(input.line_col(7), (3, 1));
        assert_eq!(input.line_col(8), (3, 2));
        assert_eq!(input.line_col(11), (3, 3));
    }

    #[test]
    fn line_of() {
        let input = StringInput::new("a\rb\nc\r\nd嗨");

        assert_eq!(input.line_of(0), "a\rb");
        assert_eq!(input.line_of(1), "a\rb");
        assert_eq!(input.line_of(2), "a\rb");
        assert_eq!(input.line_of(3), "a\rb");
        assert_eq!(input.line_of(4), "c");
        assert_eq!(input.line_of(5), "c");
        assert_eq!(input.line_of(6), "c");
        assert_eq!(input.line_of(7), "d嗨");
        assert_eq!(input.line_of(8), "d嗨");
        assert_eq!(input.line_of(11), "d嗨");
    }

    #[test]
    fn match_range() {
        let input = StringInput::new("b");

        assert!(input.match_range('a', 'c', 0));
        assert!(input.match_range('b', 'b', 0));
        assert!(!input.match_range('a', 'a', 0));
        assert!(!input.match_range('c', 'c', 0));
        assert!(input.match_range('a', '嗨', 0));
    }

    #[test]
    fn match_insensitive() {
        let input = StringInput::new("AsdASdF");

        assert!(input.match_insensitive("asd", 0));
        assert!(input.match_insensitive("asdf", 3));
    }
}
<|endoftext|>


<commit_before>use std::path::Path;

use clap::{App, Arg, ArgMatches};
use ptx_linker::session::{OptLevel, Output, Session};

#[derive(Debug, PartialEq)]
pub enum CommandLineRequest {
    Link(Session),
    Print64BitTargetJson,
    Print32BitTargetJson,
}

pub fn get_cli_request() -> CommandLineRequest {
    CommandLineRequest::from(get_app().get_matches())
}

fn get_app() -> App<'static, 'static> {
    App::new("legacy-ptx-linker")
        .version(crate_version!())
        .author(crate_authors!())
        .about("Performs linking of Rust NVPTX crates")
        .args(&[
            Arg::with_name("input")
                .help("Path to input rlib or bitcode")
                .multiple(true),
            Arg::with_name("output")
                .short("o")
                .help("Sets path for assembly output")
                .takes_value(true)
                .value_name("FILE.ptx"),
            Arg::with_name("optimise")
                .short("O")
                .help("Sets optimisation level")
                .takes_value(true)
                .value_name("level"),
            Arg::with_name("__ignored_lib_start")
                .long("whole-archive")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_lib_end")
                .long("no-whole-archive")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_start_group")
                .long("start-group")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_end_group")
                .long("end-group")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_compiler_prefix")
                .short("B")
                .takes_value(true)
                .hidden(true)
                .multiple(true)
                .number_of_values(1),
            Arg::with_name("__ignored_shared_hack")
                .short("s")
                .hidden(true)
                .multiple(true)
                .takes_value(true),
            Arg::with_name("__ignored_lib_path")
                .short("L")
                .takes_value(true)
                .hidden(true)
                .multiple(true)
                .number_of_values(1),
            Arg::with_name("arch")
                .long("arch")
                .short("a")
                .help("Target CUDA architectures")
                .takes_value(true)
                .multiple(true)
                .number_of_values(1)
                .use_delimiter(true),
            Arg::with_name("emit")
                .long("emit")
                .short("e")
                .help("Output type")
                .takes_value(true)
                .possible_values(&["asm", "ptx", "llvm-ir", "llvm-bc"])
                .default_value("asm")
                .multiple(true)
                .number_of_values(1)
                .use_delimiter(true),
        ])
        .subcommand({
            App::new("print")
                .about("Prints NVPTX target definition JSON into stdout")
                .arg(
                    &Arg::with_name("TARGET")
                        .help("Specifies the target name")
                        .required(true)
                        .possible_values(&["nvptx64-nvidia-cuda", "nvptx-nvidia-cuda"]),
                )
        })
}

impl<'a> From<ArgMatches<'a>> for CommandLineRequest {
    fn from(matches: ArgMatches) -> CommandLineRequest {
        match matches.subcommand_name() {
            Some("print") => {
                let target = matches
                    .subcommand_matches("print")
                    .unwrap()
                    .value_of("TARGET");

                match target {
                    Some("nvptx64-nvidia-cuda") => CommandLineRequest::Print64BitTargetJson,
                    Some("nvptx-nvidia-cuda") => CommandLineRequest::Print32BitTargetJson,

                    other => {
                        unreachable!("Unknown target: {:?}", other);
                    }
                }
            }

            _ => {
                let mut session = Session::default();

                if let Some(inputs) = matches.values_of("input") {
                    for input in inputs {
                        if input.ends_with(".o") {
                            session.link_bitcode(Path::new(input));
                        } else if input.ends_with(".rlib") {
                            session.link_rlib(Path::new(input));
                        } else {
                            warn!("Can't recognise input type: {:?}", input);
                        }
                    }
                }

                if let Some(output) = matches.value_of("output") {
                    session.set_output(Path::new(output));
                }

                match matches.value_of("optimise") {
                    Some("0") | None => session.set_opt_level(OptLevel::None),
                    Some(_) => session.set_opt_level(OptLevel::Default),
                };

                if let Some(outputs) = matches.values_of("emit") {
                    for output in outputs {
                        session.add_output_type(match output {
                            "llvm-ir" => Output::IntermediateRepresentation,
                            "llvm-bc" => Output::Bitcode,
                            _ => Output::PTXAssembly,
                        });
                    }
                }

                if let Some(archs) = matches.values_of("arch") {
                    for arch in archs {
                        session.add_output_arch(arch);
                    }
                }

                CommandLineRequest::Link(session)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::path::PathBuf;

    use super::*;
    use ptx_linker::session::Output;

    #[test]
    fn it_should_parse_args() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "-L",
            "/rustlib/lib",
            "/kernel/target/debug/deps/kernel.0.o",
            "/kernel/target/debug/deps/kernel.crate.metadata.o",
            "-o",
            "/kernel/target/debug/deps/libkernel.ptx",
            "-L",
            "/kernel/target/debug/deps",
            "-L",
            "/kernel/target/debug/deps",
            "-L",
            "~/rustlib/nvptx64-nvidia-cuda/lib",
            "-Bstatic",
            "--whole-archive",
            "/tmp/rustc.Ew934MzC8cj0/liblib-f0faab0dbaa9f7ef.rlib",
            "--no-whole-archive",
            "/tmp/rustc.Ew934MzC8cj0/libother-6b4931ba2f43f84b.rlib",
        ]);

        let expected_session = Session {
            emit: vec![Output::PTXAssembly],
            achitectures: vec![],

            opt_level: OptLevel::None,
            debug_info: false,

            output: Some(PathBuf::from("/kernel/target/debug/deps/libkernel.ptx")),

            include_rlibs: vec![
                PathBuf::from("/tmp/rustc.Ew934MzC8cj0/liblib-f0faab0dbaa9f7ef.rlib"),
                PathBuf::from("/tmp/rustc.Ew934MzC8cj0/libother-6b4931ba2f43f84b.rlib"),
            ],

            include_bitcode_modules: vec![PathBuf::from("/kernel/target/debug/deps/kernel.0.o")],
        };

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Link(expected_session)
        );
    }

    #[test]
    fn it_should_parse_optimization() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "-o",
            "/kernel/target/debug/deps/libkernel.ptx",
            "-O1",
        ]);

        let expected_session = Session {
            emit: vec![Output::PTXAssembly],
            achitectures: vec![],

            opt_level: OptLevel::Default,
            debug_info: false,

            output: Some(PathBuf::from("/kernel/target/debug/deps/libkernel.ptx")),

            include_rlibs: vec![],
            include_bitcode_modules: vec![],
        };

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Link(expected_session)
        );
    }

    #[test]
    fn it_should_not_print_unknown_target_json() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "print",
            "another-target-triple",
        ]);

        assert!(matches.is_err());
    }

    #[test]
    fn it_should_print_64bit_target_json() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "print",
            "nvptx64-nvidia-cuda",
        ]);

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Print64BitTargetJson
        );
    }

    #[test]
    fn it_should_print_32bit_target_json() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "print",
            "nvptx-nvidia-cuda",
        ]);

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Print32BitTargetJson
        );
    }

}
<commit_msg>Legacy: support additional flags when linking `cdylib`<commit_after>use std::path::Path;

use clap::{App, Arg, ArgMatches};
use ptx_linker::session::{OptLevel, Output, Session};

#[derive(Debug, PartialEq)]
pub enum CommandLineRequest {
    Link(Session),
    Print64BitTargetJson,
    Print32BitTargetJson,
}

pub fn get_cli_request() -> CommandLineRequest {
    CommandLineRequest::from(get_app().get_matches())
}

fn get_app() -> App<'static, 'static> {
    App::new("legacy-ptx-linker")
        .version(crate_version!())
        .author(crate_authors!())
        .about("Performs linking of Rust NVPTX crates")
        .args(&[
            Arg::with_name("input")
                .help("Path to input rlib or bitcode")
                .multiple(true),
            Arg::with_name("output")
                .short("o")
                .help("Sets path for assembly output")
                .takes_value(true)
                .value_name("FILE.ptx"),
            Arg::with_name("optimise")
                .short("O")
                .help("Sets optimisation level")
                .takes_value(true)
                .value_name("level"),
            Arg::with_name("__ignored_lib_start")
                .long("whole-archive")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_lib_end")
                .long("no-whole-archive")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_start_group")
                .long("start-group")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_end_group")
                .long("end-group")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_compiler_prefix")
                .short("B")
                .takes_value(true)
                .hidden(true)
                .multiple(true)
                .number_of_values(1),
            Arg::with_name("__ignored_shared_hack")
                .short("s")
                .hidden(true)
                .multiple(true)
                .takes_value(true),
            Arg::with_name("__ignored_lib_path")
                .short("L")
                .takes_value(true)
                .hidden(true)
                .multiple(true)
                .number_of_values(1),
            Arg::with_name("__ignored_version_script")
                .long("version-script")
                .hidden(true)
                .multiple(true),
            Arg::with_name("__ignored_gc_sections")
                .long("gc-sections")
                .hidden(true)
                .multiple(true),
            Arg::with_name("arch")
                .long("arch")
                .short("a")
                .help("Target CUDA architectures")
                .takes_value(true)
                .multiple(true)
                .number_of_values(1)
                .use_delimiter(true),
            Arg::with_name("emit")
                .long("emit")
                .short("e")
                .help("Output type")
                .takes_value(true)
                .possible_values(&["asm", "ptx", "llvm-ir", "llvm-bc"])
                .default_value("asm")
                .multiple(true)
                .number_of_values(1)
                .use_delimiter(true),
        ])
        .subcommand({
            App::new("print")
                .about("Prints NVPTX target definition JSON into stdout")
                .arg(
                    &Arg::with_name("TARGET")
                        .help("Specifies the target name")
                        .required(true)
                        .possible_values(&["nvptx64-nvidia-cuda", "nvptx-nvidia-cuda"]),
                )
        })
}

impl<'a> From<ArgMatches<'a>> for CommandLineRequest {
    fn from(matches: ArgMatches) -> CommandLineRequest {
        match matches.subcommand_name() {
            Some("print") => {
                let target = matches
                    .subcommand_matches("print")
                    .unwrap()
                    .value_of("TARGET");

                match target {
                    Some("nvptx64-nvidia-cuda") => CommandLineRequest::Print64BitTargetJson,
                    Some("nvptx-nvidia-cuda") => CommandLineRequest::Print32BitTargetJson,

                    other => {
                        unreachable!("Unknown target: {:?}", other);
                    }
                }
            }

            _ => {
                let mut session = Session::default();

                if let Some(inputs) = matches.values_of("input") {
                    for input in inputs {
                        if input.ends_with(".o") {
                            session.link_bitcode(Path::new(input));
                        } else if input.ends_with(".rlib") {
                            session.link_rlib(Path::new(input));
                        } else {
                            warn!("Can't recognise input type: {:?}", input);
                        }
                    }
                }

                if let Some(output) = matches.value_of("output") {
                    session.set_output(Path::new(output));
                }

                match matches.value_of("optimise") {
                    Some("0") | None => session.set_opt_level(OptLevel::None),
                    Some(_) => session.set_opt_level(OptLevel::Default),
                };

                if let Some(outputs) = matches.values_of("emit") {
                    for output in outputs {
                        session.add_output_type(match output {
                            "llvm-ir" => Output::IntermediateRepresentation,
                            "llvm-bc" => Output::Bitcode,
                            _ => Output::PTXAssembly,
                        });
                    }
                }

                if let Some(archs) = matches.values_of("arch") {
                    for arch in archs {
                        session.add_output_arch(arch);
                    }
                }

                CommandLineRequest::Link(session)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::path::PathBuf;

    use super::*;
    use ptx_linker::session::Output;

    #[test]
    fn it_should_parse_args() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "-L",
            "/rustlib/lib",
            "/kernel/target/debug/deps/kernel.0.o",
            "/kernel/target/debug/deps/kernel.crate.metadata.o",
            "-o",
            "/kernel/target/debug/deps/libkernel.ptx",
            "-L",
            "/kernel/target/debug/deps",
            "-L",
            "/kernel/target/debug/deps",
            "-L",
            "~/rustlib/nvptx64-nvidia-cuda/lib",
            "-Bstatic",
            "--whole-archive",
            "/tmp/rustc.Ew934MzC8cj0/liblib-f0faab0dbaa9f7ef.rlib",
            "--no-whole-archive",
            "/tmp/rustc.Ew934MzC8cj0/libother-6b4931ba2f43f84b.rlib",
        ]);

        let expected_session = Session {
            emit: vec![Output::PTXAssembly],
            achitectures: vec![],

            opt_level: OptLevel::None,
            debug_info: false,

            output: Some(PathBuf::from("/kernel/target/debug/deps/libkernel.ptx")),

            include_rlibs: vec![
                PathBuf::from("/tmp/rustc.Ew934MzC8cj0/liblib-f0faab0dbaa9f7ef.rlib"),
                PathBuf::from("/tmp/rustc.Ew934MzC8cj0/libother-6b4931ba2f43f84b.rlib"),
            ],

            include_bitcode_modules: vec![PathBuf::from("/kernel/target/debug/deps/kernel.0.o")],
        };

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Link(expected_session)
        );
    }

    #[test]
    fn it_should_parse_optimization() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "-o",
            "/kernel/target/debug/deps/libkernel.ptx",
            "-O1",
        ]);

        let expected_session = Session {
            emit: vec![Output::PTXAssembly],
            achitectures: vec![],

            opt_level: OptLevel::Default,
            debug_info: false,

            output: Some(PathBuf::from("/kernel/target/debug/deps/libkernel.ptx")),

            include_rlibs: vec![],
            include_bitcode_modules: vec![],
        };

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Link(expected_session)
        );
    }

    #[test]
    fn it_should_not_print_unknown_target_json() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "print",
            "another-target-triple",
        ]);

        assert!(matches.is_err());
    }

    #[test]
    fn it_should_print_64bit_target_json() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "print",
            "nvptx64-nvidia-cuda",
        ]);

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Print64BitTargetJson
        );
    }

    #[test]
    fn it_should_print_32bit_target_json() {
        let matches = get_app().get_matches_from_safe(vec![
            "legacy-ptx-linker",
            "print",
            "nvptx-nvidia-cuda",
        ]);

        assert_eq!(
            CommandLineRequest::from(matches.expect("Unable to parse CLI arguments")),
            CommandLineRequest::Print32BitTargetJson
        );
    }

}
<|endoftext|>


<commit_before>#[ allow( unused_imports ) ]
use clone_dyn::clone_dyn;

fn main()
{

  #[ clone_dyn ]
  trait Trait1
  {
  }

  let vec = Vec::< Box< dyn Trait1 > >::new();
  let _vec2 = vec.clone(); /* <- it does not work without `clone_dyn` */

}
<commit_msg>Fix sample `clone_dyn_trivial_sample`, add condition<commit_after>#[ allow( unused_imports ) ]
use clone_dyn::clone_dyn;

fn main()
{

  #[ cfg( any( feature = "use_std", feature = "use_alloc" ) ) ]
  {
    #[ clone_dyn ]
    trait Trait1
    {
    }

    let vec = Vec::< Box< dyn Trait1 > >::new();
    let _vec2 = vec.clone(); /* <- it does not work without `clone_dyn` */
  }

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate rand;
#[allow(unused_imports)]
use glium::glutin;
use glutin::dpi::PhysicalSize;

fn main() {
    let event_loop = glium::glutin::event_loop::EventLoop::new();
    let cb = glutin::ContextBuilder::new();
    let size = PhysicalSize {
        width: 800.0,
        height: 600.0,
    };
    let context = cb.build_headless(&event_loop, size).unwrap();
    let context = unsafe {
        context.treat_as_current()
    };
    let display = glium::backend::glutin::headless::Headless::new(context).unwrap();

    let program = glium::program::ComputeShader::from_source(&display, r#"\

            #version 430
            layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

            layout(std140) buffer MyBlock {
                float power;
                vec4 values[4096/4];
            };

            void main() {
                vec4 val = values[gl_GlobalInvocationID.x];

                values[gl_GlobalInvocationID.x] = pow(val, vec4(power));
            }

        "#).unwrap();

    const NUM_VALUES: usize = 4096;

    #[derive(Clone, Copy)]
    struct Data {
        power: f32,
        _padding: [f32; 3],
        values: [[f32;4]; NUM_VALUES],
    }

    implement_uniform_block!(Data, power, values);

    let mut buffer: glium::uniforms::UniformBuffer<Data> =
              glium::uniforms::UniformBuffer::empty(&display).unwrap();

    {
        let mut mapping = buffer.map();
        mapping.power = rand::random();
        for val in mapping.values.iter_mut() {
            *val = [rand::random::<f32>(),rand::random::<f32>(),rand::random::<f32>(),rand::random::<f32>()];
        }
    }

    program.execute(uniform! { MyBlock: &*buffer }, 4096, 1, 1);

    {
        let mapping = buffer.map();
        println!("Power is: {:?}", mapping.power);
        for val in mapping.values.iter().take(3) {
            println!("{:?}", val[0]);
            println!("{:?}", val[1]);
            println!("{:?}", val[2]);
            println!("{:?}", val[3]);
        }
        println!("...");
    }
}
<commit_msg>Add repr(C) for Data struct in gpgpu-example (#1650)<commit_after>#[macro_use]
extern crate glium;
extern crate rand;
#[allow(unused_imports)]
use glium::glutin;
use glutin::dpi::PhysicalSize;

fn main() {
    let event_loop = glium::glutin::event_loop::EventLoop::new();
    let cb = glutin::ContextBuilder::new();
    let size = PhysicalSize {
        width: 800.0,
        height: 600.0,
    };
    let context = cb.build_headless(&event_loop, size).unwrap();
    let context = unsafe {
        context.treat_as_current()
    };
    let display = glium::backend::glutin::headless::Headless::new(context).unwrap();

    let program = glium::program::ComputeShader::from_source(&display, r#"\

            #version 430
            layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

            layout(std140) buffer MyBlock {
                float power;
                vec4 values[4096/4];
            };

            void main() {
                vec4 val = values[gl_GlobalInvocationID.x];

                values[gl_GlobalInvocationID.x] = pow(val, vec4(power));
            }

        "#).unwrap();

    const NUM_VALUES: usize = 4096;

    #[repr(C)]
    #[derive(Clone, Copy)]
    struct Data {
        power: f32,
        _padding: [f32; 3],
        values: [[f32;4]; NUM_VALUES],
    }

    implement_uniform_block!(Data, power, values);

    let mut buffer: glium::uniforms::UniformBuffer<Data> =
              glium::uniforms::UniformBuffer::empty(&display).unwrap();

    {
        let mut mapping = buffer.map();
        mapping.power = rand::random();
        for val in mapping.values.iter_mut() {
            *val = [rand::random::<f32>(),rand::random::<f32>(),rand::random::<f32>(),rand::random::<f32>()];
        }
    }

    program.execute(uniform! { MyBlock: &*buffer }, 4096, 1, 1);

    {
        let mapping = buffer.map();
        println!("Power is: {:?}", mapping.power);
        for val in mapping.values.iter().take(3) {
            println!("{:?}", val[0]);
            println!("{:?}", val[1]);
            println!("{:?}", val[2]);
            println!("{:?}", val[3]);
        }
        println!("...");
    }
}
<|endoftext|>


<commit_before>extern crate image;
extern crate rusttype;

use image::{DynamicImage, Rgba};
use rusttype::{point, Font, Scale};

fn main() {
    // Load the font
    let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
    // This only succeeds if collection consists of one font
    let font =
        Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");

    // Create a new rgba image
    let mut image = DynamicImage::new_rgba8(500, 100).to_rgba();

    // The font size to use
    let size = 32.0;
    let scale = Scale { x: size, y: size };

    // The text to render
    let text = "This is RustType rendered into a png!";

    // Use a dark red colour
    let colour = (150, 0, 0);

    // The starting positioning of the glyphs (top left corner)
    let start = point(20.0, 50.0);

    // Loop through the glyphs in the text, positing each one on a line
    for glyph in font.layout(text, scale, start) {
        if let Some(bounding_box) = glyph.pixel_bounding_box() {
            // Draw the glyph into the image per-pixel by using the draw closure
            glyph.draw(|x, y, v| {
                image.put_pixel(
                    // Offset the position by the glyph bounding box
                    x + bounding_box.min.x as u32,
                    y + bounding_box.min.y as u32,
                    // Turn the coverage into an alpha value
                    Rgba {
                        data: [colour.0, colour.1, colour.2, (v * 255.0) as u8],
                    },
                )
            });
        }
    }

    // Save the image to a png file
    image.save("image_example.png").unwrap();
    println!("Generated: image_example.png");
}
<commit_msg>Improve image example to work with other fonts more easily<commit_after>extern crate image;
extern crate rusttype;

use image::{DynamicImage, Rgba};
use rusttype::{point, Font, Scale};

fn main() {
    // Load the font
    let font_data = include_bytes!("../fonts/wqy-microhei/WenQuanYiMicroHei.ttf");
    // This only succeeds if collection consists of one font
    let font = Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");

    // The font size to use
    let scale = Scale::uniform(32.0);

    // The text to render
    let text = "This is RustType rendered into a png!";

    // Use a dark red colour
    let colour = (150, 0, 0);

    let v_metrics = font.v_metrics(scale);

    // layout the glyphs in a line with 20 pixels padding
    let glyphs: Vec<_> = font
        .layout(text, scale, point(20.0, 20.0 + v_metrics.ascent))
        .collect();

    // work out the layout size
    let glyphs_height = (v_metrics.ascent - v_metrics.descent).ceil() as u32;
    let glyphs_width = {
        let min_x = glyphs
            .first()
            .map(|g| g.pixel_bounding_box().unwrap().min.x)
            .unwrap();
        let max_x = glyphs
            .last()
            .map(|g| g.pixel_bounding_box().unwrap().max.x)
            .unwrap();
        (max_x - min_x) as u32
    };

    // Create a new rgba image with some padding
    let mut image = DynamicImage::new_rgba8(glyphs_width + 40, glyphs_height + 40).to_rgba();

    // Loop through the glyphs in the text, positing each one on a line
    for glyph in glyphs {
        if let Some(bounding_box) = glyph.pixel_bounding_box() {
            // Draw the glyph into the image per-pixel by using the draw closure
            glyph.draw(|x, y, v| {
                image.put_pixel(
                    // Offset the position by the glyph bounding box
                    x + bounding_box.min.x as u32,
                    y + bounding_box.min.y as u32,
                    // Turn the coverage into an alpha value
                    Rgba {
                        data: [colour.0, colour.1, colour.2, (v * 255.0) as u8],
                    },
                )
            });
        }
    }

    // Save the image to a png file
    image.save("image_example.png").unwrap();
    println!("Generated: image_example.png");
}
<|endoftext|>