<commit_before>#![allow(rustc::internal)]

extern crate serialize as rustc_serialize;

use rustc_serialize::opaque::{Decoder, Encoder};
use rustc_serialize::{Decodable, Encodable};
use std::fmt::Debug;

#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
struct Struct {
    a: (),
    b: u8,
    c: u16,
    d: u32,
    e: u64,
    f: usize,

    g: i8,
    h: i16,
    i: i32,
    j: i64,
    k: isize,

    l: char,
    m: String,
    n: f32,
    o: f64,
    p: bool,
    q: Option<u32>,
}

fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
    let mut encoder = Encoder::new(Vec::new());

    for value in &values {
        Encodable::encode(&value, &mut encoder).unwrap();
    }

    let data = encoder.into_inner();
    let mut decoder = Decoder::new(&data[..], 0);

    for value in values {
        let decoded = Decodable::decode(&mut decoder).unwrap();
        assert_eq!(value, decoded);
    }
}

#[test]
fn test_unit() {
    check_round_trip(vec![(), (), (), ()]);
}

#[test]
fn test_u8() {
    let mut vec = vec![];
    for i in ::std::u8::MIN..::std::u8::MAX {
        vec.push(i);
    }
    check_round_trip(vec);
}

#[test]
fn test_u16() {
    for i in ::std::u16::MIN..::std::u16::MAX {
        check_round_trip(vec![1, 2, 3, i, i, i]);
    }
}

#[test]
fn test_u32() {
    check_round_trip(vec![1, 2, 3, ::std::u32::MIN, 0, 1, ::std::u32::MAX, 2, 1]);
}

#[test]
fn test_u64() {
    check_round_trip(vec![1, 2, 3, ::std::u64::MIN, 0, 1, ::std::u64::MAX, 2, 1]);
}

#[test]
fn test_usize() {
    check_round_trip(vec![1, 2, 3, ::std::usize::MIN, 0, 1, ::std::usize::MAX, 2, 1]);
}

#[test]
fn test_i8() {
    let mut vec = vec![];
    for i in ::std::i8::MIN..::std::i8::MAX {
        vec.push(i);
    }
    check_round_trip(vec);
}

#[test]
fn test_i16() {
    for i in ::std::i16::MIN..::std::i16::MAX {
        check_round_trip(vec![-1, 2, -3, i, i, i, 2]);
    }
}

#[test]
fn test_i32() {
    check_round_trip(vec![-1, 2, -3, ::std::i32::MIN, 0, 1, ::std::i32::MAX, 2, 1]);
}

#[test]
fn test_i64() {
    check_round_trip(vec![-1, 2, -3, ::std::i64::MIN, 0, 1, ::std::i64::MAX, 2, 1]);
}

#[test]
fn test_isize() {
    check_round_trip(vec![-1, 2, -3, ::std::isize::MIN, 0, 1, ::std::isize::MAX, 2, 1]);
}

#[test]
fn test_bool() {
    check_round_trip(vec![false, true, true, false, false]);
}

#[test]
fn test_f32() {
    let mut vec = vec![];
    for i in -100..100 {
        vec.push((i as f32) / 3.0);
    }
    check_round_trip(vec);
}

#[test]
fn test_f64() {
    let mut vec = vec![];
    for i in -100..100 {
        vec.push((i as f64) / 3.0);
    }
    check_round_trip(vec);
}

#[test]
fn test_char() {
    let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
    check_round_trip(vec);
}

#[test]
fn test_string() {
    let vec = vec![
        "abcbuÖeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmeabpnvapeapmaebn".to_string(),
        "abcbuÖganeiÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µnvapeapmaebn".to_string(),
    ];

    check_round_trip(vec);
}

#[test]
fn test_option() {
    check_round_trip(vec![Some(-1i8)]);
    check_round_trip(vec![Some(-2i16)]);
    check_round_trip(vec![Some(-3i32)]);
    check_round_trip(vec![Some(-4i64)]);
    check_round_trip(vec![Some(-5isize)]);

    let none_i8: Option<i8> = None;
    check_round_trip(vec![none_i8]);

    let none_i16: Option<i16> = None;
    check_round_trip(vec![none_i16]);

    let none_i32: Option<i32> = None;
    check_round_trip(vec![none_i32]);

    let none_i64: Option<i64> = None;
    check_round_trip(vec![none_i64]);

    let none_isize: Option<isize> = None;
    check_round_trip(vec![none_isize]);
}

#[test]
fn test_struct() {
    check_round_trip(vec![Struct {
        a: (),
        b: 10,
        c: 11,
        d: 12,
        e: 13,
        f: 14,

        g: 15,
        h: 16,
        i: 17,
        j: 18,
        k: 19,

        l: 'x',
        m: "abc".to_string(),
        n: 20.5,
        o: 21.5,
        p: false,
        q: None,
    }]);

    check_round_trip(vec![Struct {
        a: (),
        b: 101,
        c: 111,
        d: 121,
        e: 131,
        f: 141,

        g: -15,
        h: -16,
        i: -17,
        j: -18,
        k: -19,

        l: 'y',
        m: "def".to_string(),
        n: -20.5,
        o: -21.5,
        p: true,
        q: Some(1234567),
    }]);
}

#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
enum Enum {
    Variant1,
    Variant2(usize, f32),
    Variant3 { a: i32, b: char, c: bool },
}

#[test]
fn test_enum() {
    check_round_trip(vec![
        Enum::Variant1,
        Enum::Variant2(1, 2.5),
        Enum::Variant3 { a: 3, b: 'b', c: false },
        Enum::Variant3 { a: -4, b: 'f', c: true },
    ]);
}

#[test]
fn test_sequence() {
    let mut vec = vec![];
    for i in -100i64..100i64 {
        vec.push(i * 100000);
    }

    check_round_trip(vec![vec]);
}

#[test]
fn test_hash_map() {
    use std::collections::HashMap;
    let mut map = HashMap::new();
    for i in -100i64..100i64 {
        map.insert(i * 100000, i * 10000);
    }

    check_round_trip(vec![map]);
}

#[test]
fn test_tuples() {
    check_round_trip(vec![('x', (), false, 0.5f32)]);
    check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
    check_round_trip(vec![(-12i16, 11u8, 12usize)]);
    check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
    check_round_trip(vec![(String::new(), "some string".to_string())]);
}
<commit_msg>Use assoc integer constants in libserialize<commit_after>#![allow(rustc::internal)]

extern crate serialize as rustc_serialize;

use rustc_serialize::opaque::{Decoder, Encoder};
use rustc_serialize::{Decodable, Encodable};
use std::fmt::Debug;

#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
struct Struct {
    a: (),
    b: u8,
    c: u16,
    d: u32,
    e: u64,
    f: usize,

    g: i8,
    h: i16,
    i: i32,
    j: i64,
    k: isize,

    l: char,
    m: String,
    n: f32,
    o: f64,
    p: bool,
    q: Option<u32>,
}

fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
    let mut encoder = Encoder::new(Vec::new());

    for value in &values {
        Encodable::encode(&value, &mut encoder).unwrap();
    }

    let data = encoder.into_inner();
    let mut decoder = Decoder::new(&data[..], 0);

    for value in values {
        let decoded = Decodable::decode(&mut decoder).unwrap();
        assert_eq!(value, decoded);
    }
}

#[test]
fn test_unit() {
    check_round_trip(vec![(), (), (), ()]);
}

#[test]
fn test_u8() {
    let mut vec = vec![];
    for i in u8::MIN..u8::MAX {
        vec.push(i);
    }
    check_round_trip(vec);
}

#[test]
fn test_u16() {
    for i in u16::MIN..u16::MAX {
        check_round_trip(vec![1, 2, 3, i, i, i]);
    }
}

#[test]
fn test_u32() {
    check_round_trip(vec![1, 2, 3, u32::MIN, 0, 1, u32::MAX, 2, 1]);
}

#[test]
fn test_u64() {
    check_round_trip(vec![1, 2, 3, u64::MIN, 0, 1, u64::MAX, 2, 1]);
}

#[test]
fn test_usize() {
    check_round_trip(vec![1, 2, 3, usize::MIN, 0, 1, usize::MAX, 2, 1]);
}

#[test]
fn test_i8() {
    let mut vec = vec![];
    for i in i8::MIN..i8::MAX {
        vec.push(i);
    }
    check_round_trip(vec);
}

#[test]
fn test_i16() {
    for i in i16::MIN..i16::MAX {
        check_round_trip(vec![-1, 2, -3, i, i, i, 2]);
    }
}

#[test]
fn test_i32() {
    check_round_trip(vec![-1, 2, -3, i32::MIN, 0, 1, i32::MAX, 2, 1]);
}

#[test]
fn test_i64() {
    check_round_trip(vec![-1, 2, -3, i64::MIN, 0, 1, i64::MAX, 2, 1]);
}

#[test]
fn test_isize() {
    check_round_trip(vec![-1, 2, -3, isize::MIN, 0, 1, isize::MAX, 2, 1]);
}

#[test]
fn test_bool() {
    check_round_trip(vec![false, true, true, false, false]);
}

#[test]
fn test_f32() {
    let mut vec = vec![];
    for i in -100..100 {
        vec.push((i as f32) / 3.0);
    }
    check_round_trip(vec);
}

#[test]
fn test_f64() {
    let mut vec = vec![];
    for i in -100..100 {
        vec.push((i as f64) / 3.0);
    }
    check_round_trip(vec);
}

#[test]
fn test_char() {
    let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
    check_round_trip(vec);
}

#[test]
fn test_string() {
    let vec = vec![
        "abcbuÖeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmeabpnvapeapmaebn".to_string(),
        "abcbuÖganeiÄnameÜavmpßvmea€µsbpnvapeapmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µsbpmaebn".to_string(),
        "abcbuÖganeiovÄnameÜavmpßvmea€µnvapeapmaebn".to_string(),
    ];

    check_round_trip(vec);
}

#[test]
fn test_option() {
    check_round_trip(vec![Some(-1i8)]);
    check_round_trip(vec![Some(-2i16)]);
    check_round_trip(vec![Some(-3i32)]);
    check_round_trip(vec![Some(-4i64)]);
    check_round_trip(vec![Some(-5isize)]);

    let none_i8: Option<i8> = None;
    check_round_trip(vec![none_i8]);

    let none_i16: Option<i16> = None;
    check_round_trip(vec![none_i16]);

    let none_i32: Option<i32> = None;
    check_round_trip(vec![none_i32]);

    let none_i64: Option<i64> = None;
    check_round_trip(vec![none_i64]);

    let none_isize: Option<isize> = None;
    check_round_trip(vec![none_isize]);
}

#[test]
fn test_struct() {
    check_round_trip(vec![Struct {
        a: (),
        b: 10,
        c: 11,
        d: 12,
        e: 13,
        f: 14,

        g: 15,
        h: 16,
        i: 17,
        j: 18,
        k: 19,

        l: 'x',
        m: "abc".to_string(),
        n: 20.5,
        o: 21.5,
        p: false,
        q: None,
    }]);

    check_round_trip(vec![Struct {
        a: (),
        b: 101,
        c: 111,
        d: 121,
        e: 131,
        f: 141,

        g: -15,
        h: -16,
        i: -17,
        j: -18,
        k: -19,

        l: 'y',
        m: "def".to_string(),
        n: -20.5,
        o: -21.5,
        p: true,
        q: Some(1234567),
    }]);
}

#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
enum Enum {
    Variant1,
    Variant2(usize, f32),
    Variant3 { a: i32, b: char, c: bool },
}

#[test]
fn test_enum() {
    check_round_trip(vec![
        Enum::Variant1,
        Enum::Variant2(1, 2.5),
        Enum::Variant3 { a: 3, b: 'b', c: false },
        Enum::Variant3 { a: -4, b: 'f', c: true },
    ]);
}

#[test]
fn test_sequence() {
    let mut vec = vec![];
    for i in -100i64..100i64 {
        vec.push(i * 100000);
    }

    check_round_trip(vec![vec]);
}

#[test]
fn test_hash_map() {
    use std::collections::HashMap;
    let mut map = HashMap::new();
    for i in -100i64..100i64 {
        map.insert(i * 100000, i * 10000);
    }

    check_round_trip(vec![map]);
}

#[test]
fn test_tuples() {
    check_round_trip(vec![('x', (), false, 0.5f32)]);
    check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
    check_round_trip(vec![(-12i16, 11u8, 12usize)]);
    check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
    check_round_trip(vec![(String::new(), "some string".to_string())]);
}
<|endoftext|>


<commit_before>// Copyright 2015 Keegan McAllister.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// See `LICENSE` in this repository.

// Fuzz me with AFL_DEFER_FORKSRV=1 for a huge speedup.

#![feature(plugin)]

#![plugin(afl_plugin)]

extern crate afl;

use std::io::{self, Read};
use std::thread;

fn main() {
    println!("An eternity in...");
    thread::sleep_ms(500);

    unsafe {
        afl::init();
    }

    println!("the blink of an eye.");

    let mut input = String::new();
    io::stdin().read_to_string(&mut input).unwrap();

    if input.starts_with("x") {
        println!("going...");
        if input.starts_with("xy") {
            println!("going...");
            if input.starts_with("xyz") {
                println!("gone!");
                unsafe {
                    let x: *mut usize = 0 as *mut usize;
                    *x = 0xBEEF;
                }
            }
        }
    }
}
<commit_msg>Fix warning on deferred-init example.<commit_after>// Copyright 2015 Keegan McAllister.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// See `LICENSE` in this repository.

// Fuzz me with AFL_DEFER_FORKSRV=1 for a huge speedup.

#![feature(plugin)]

#![plugin(afl_plugin)]

extern crate afl;

use std::io::{self, Read};
use std::thread;
use std::time::Duration;

fn main() {
    println!("An eternity in...");
    thread::sleep(Duration::from_secs(1));

    unsafe {
        afl::init();
    }

    println!("the blink of an eye.");

    let mut input = String::new();
    io::stdin().read_to_string(&mut input).unwrap();

    if input.starts_with("x") {
        println!("going...");
        if input.starts_with("xy") {
            println!("going...");
            if input.starts_with("xyz") {
                println!("gone!");
                unsafe {
                    let x: *mut usize = 0 as *mut usize;
                    *x = 0xBEEF;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use self::ll::{AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S8, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8};
use self::ll::{SDL_CloseAudio, SDL_LockAudio, SDL_MixAudio, SDL_OpenAudio, SDL_PauseAudio};
use self::ll::{SDL_UnlockAudio};

use core::cast::{forget, transmute};
use core::libc::{c_int, c_void, uint16_t};
use core::ptr::null;

pub mod ll {
    use core::libc::{c_int, c_void, uint16_t};

    pub const AUDIO_U8: uint16_t = 0x0008;
    pub const AUDIO_S8: uint16_t = 0x8008;
    pub const AUDIO_U16LSB: uint16_t = 0x0010;
    pub const AUDIO_S16LSB: uint16_t = 0x8010;
    pub const AUDIO_U16MSB: uint16_t = 0x1010;
    pub const AUDIO_S16MSB: uint16_t = 0x9010;
    pub const AUDIO_U16: uint16_t = AUDIO_U16LSB;
    pub const AUDIO_S16: uint16_t = AUDIO_S16LSB;

    pub struct SDL_AudioSpec {
        freq: c_int,
        format: u16,
        channels: u8,
        silence: u8,
        samples: u16,
        padding: u16,
        size: u32,
        callback: *u8,
        userdata: *c_void,
    }

    extern {
        pub fn SDL_OpenAudio(desired: *mut SDL_AudioSpec, obtained: *mut SDL_AudioSpec) -> c_int;
        pub fn SDL_PauseAudio(pause_on: c_int);
        pub fn SDL_MixAudio(dst: *mut u8, src: *u8, len: u32, volume: c_int);
        pub fn SDL_LockAudio();
        pub fn SDL_UnlockAudio();
        pub fn SDL_CloseAudio();
    }
}

pub enum AudioFormat {
    U8AudioFormat = AUDIO_U8 as int,
    S8AudioFormat = AUDIO_S8 as int,
    U16LsbAudioFormat = AUDIO_U16LSB as int,
    S16LsbAudioFormat = AUDIO_S16LSB as int,
    U16MsbAudioFormat = AUDIO_U16MSB as int,
    S16MsbAudioFormat = AUDIO_S16MSB as int
}

pub const U16AudioFormat: AudioFormat = U16LsbAudioFormat;
pub const S16AudioFormat: AudioFormat = S16LsbAudioFormat;

impl AudioFormat {
    fn to_ll_format(self) -> uint16_t {
        match self {
            U8AudioFormat => AUDIO_U8,
            S8AudioFormat => AUDIO_S8,
            U16LsbAudioFormat => AUDIO_U16LSB,
            S16LsbAudioFormat => AUDIO_S16LSB,
            U16MsbAudioFormat => AUDIO_U16MSB,
            S16MsbAudioFormat => AUDIO_S16MSB,
        }
    }
    static fn from_ll_format(x: uint16_t) -> AudioFormat {
        match x {
            AUDIO_U8 => U8AudioFormat,
            AUDIO_S8 => S8AudioFormat,
            AUDIO_U16LSB => U16LsbAudioFormat,
            AUDIO_S16LSB => S16LsbAudioFormat,
            AUDIO_U16MSB => U16MsbAudioFormat,
            AUDIO_S16MSB => S16MsbAudioFormat,
            _ => fail!(~"unexpected format")
        }
    }
}

#[deriving_eq]
pub enum Channels {
    Mono,
    Stereo,
}

impl Channels {
    static pub fn new(count: c_int) -> Channels { if count == 1 { Mono } else { Stereo } }
    pub fn count(self) -> c_int                 { match self { Mono => 1, Stereo => 2 } }
}

pub type AudioCallback = ~fn(&mut [u8]);

pub struct DesiredAudioSpec {
    freq: c_int,
    format: AudioFormat,
    channels: Channels,
    samples: u16,
    callback: AudioCallback,
}

impl DesiredAudioSpec {
    fn to_ll_spec(self) -> ll::SDL_AudioSpec {
        unsafe {
            let DesiredAudioSpec { freq, format, channels, samples, callback } = self;
            ll::SDL_AudioSpec {
                freq: freq,
                format: format.to_ll_format(),
                channels: channels.count() as u8,
                silence: 0,
                samples: samples,
                padding: 0,
                size: 0,
                callback: native_callback,
                userdata: transmute(~callback),
            }
        }
    }
}

pub struct ObtainedAudioSpec {
    freq: c_int,
    format: AudioFormat,
    channels: Channels,
    silence: u8,
    samples: u16,
    size: u32,
}

impl ObtainedAudioSpec {
    static fn from_ll_spec(spec: &ll::SDL_AudioSpec) -> ObtainedAudioSpec {
        ObtainedAudioSpec {
            freq: spec.freq,
            format: AudioFormat::from_ll_format(spec.format),
            channels: Channels::new(spec.channels as c_int),
            silence: spec.silence,
            samples: spec.samples,
            size: spec.size,
        }
    }
}

extern fn native_callback(userdata: *c_void, stream: *mut u8, len: c_int) {
    unsafe {
        let callback: ~AudioCallback = transmute(userdata);
        let buffer = transmute((stream, len as uint));
        (*callback)(buffer);
        forget(callback);   // Don't free the callback!
    }
}

pub fn open(desired: DesiredAudioSpec) -> Result<ObtainedAudioSpec,()> {
    unsafe {
        let mut ll_desired = desired.to_ll_spec();
        let mut ll_obtained = ll::SDL_AudioSpec {
            freq: 0,
            format: 0,
            channels: 0,
            silence: 0,
            samples: 0,
            padding: 0,
            size: 0,
            callback: null(),
            userdata: null(),
        };

        if SDL_OpenAudio(&mut ll_desired, &mut ll_obtained) < 0 {
            Err(())
        } else {
            Ok(ObtainedAudioSpec::from_ll_spec(&ll_obtained))
        }
    }
}

pub fn pause(paused: bool) {
    unsafe {
        ll::SDL_PauseAudio(paused as c_int);
    }
}

pub fn close() {
    unsafe {
        ll::SDL_CloseAudio();
    }
}

pub fn mix(dest: &mut [u8], src: &[u8], volume: c_int) {
    unsafe {
        fail_unless!(dest.len() == src.len());
        SDL_MixAudio(&mut dest[0], &src[0], dest.len() as u32, volume);
    }
}

pub fn with_lock<R>(f: &fn() -> R) -> R {
    unsafe {
        SDL_LockAudio();
        let result = f();
        SDL_UnlockAudio();
        result
    }
}

<commit_msg>updated audio.rs for recent visibility changes in Rust.<commit_after>use self::ll::{AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S8, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8};
use self::ll::{SDL_CloseAudio, SDL_LockAudio, SDL_MixAudio, SDL_OpenAudio, SDL_PauseAudio};
use self::ll::{SDL_UnlockAudio};

use core::cast::{forget, transmute};
use core::libc::{c_int, c_void, uint16_t};
use core::ptr::null;

pub mod ll {
    use core::libc::{c_int, c_void, uint16_t};

    pub const AUDIO_U8: uint16_t = 0x0008;
    pub const AUDIO_S8: uint16_t = 0x8008;
    pub const AUDIO_U16LSB: uint16_t = 0x0010;
    pub const AUDIO_S16LSB: uint16_t = 0x8010;
    pub const AUDIO_U16MSB: uint16_t = 0x1010;
    pub const AUDIO_S16MSB: uint16_t = 0x9010;
    pub const AUDIO_U16: uint16_t = AUDIO_U16LSB;
    pub const AUDIO_S16: uint16_t = AUDIO_S16LSB;

    pub struct SDL_AudioSpec {
        freq: c_int,
        format: u16,
        channels: u8,
        silence: u8,
        samples: u16,
        padding: u16,
        size: u32,
        callback: *u8,
        userdata: *c_void,
    }

    pub extern {
        pub fn SDL_OpenAudio(desired: *mut SDL_AudioSpec, obtained: *mut SDL_AudioSpec) -> c_int;
        pub fn SDL_PauseAudio(pause_on: c_int);
        pub fn SDL_MixAudio(dst: *mut u8, src: *u8, len: u32, volume: c_int);
        pub fn SDL_LockAudio();
        pub fn SDL_UnlockAudio();
        pub fn SDL_CloseAudio();
    }
}

pub enum AudioFormat {
    U8AudioFormat = AUDIO_U8 as int,
    S8AudioFormat = AUDIO_S8 as int,
    U16LsbAudioFormat = AUDIO_U16LSB as int,
    S16LsbAudioFormat = AUDIO_S16LSB as int,
    U16MsbAudioFormat = AUDIO_U16MSB as int,
    S16MsbAudioFormat = AUDIO_S16MSB as int
}

pub const U16AudioFormat: AudioFormat = U16LsbAudioFormat;
pub const S16AudioFormat: AudioFormat = S16LsbAudioFormat;

pub impl AudioFormat {
    fn to_ll_format(self) -> uint16_t {
        match self {
            U8AudioFormat => AUDIO_U8,
            S8AudioFormat => AUDIO_S8,
            U16LsbAudioFormat => AUDIO_U16LSB,
            S16LsbAudioFormat => AUDIO_S16LSB,
            U16MsbAudioFormat => AUDIO_U16MSB,
            S16MsbAudioFormat => AUDIO_S16MSB,
        }
    }
    static fn from_ll_format(x: uint16_t) -> AudioFormat {
        match x {
            AUDIO_U8 => U8AudioFormat,
            AUDIO_S8 => S8AudioFormat,
            AUDIO_U16LSB => U16LsbAudioFormat,
            AUDIO_S16LSB => S16LsbAudioFormat,
            AUDIO_U16MSB => U16MsbAudioFormat,
            AUDIO_S16MSB => S16MsbAudioFormat,
            _ => fail!(~"unexpected format")
        }
    }
}

#[deriving_eq]
pub enum Channels {
    Mono,
    Stereo,
}

impl Channels {
    static pub fn new(count: c_int) -> Channels { if count == 1 { Mono } else { Stereo } }
    pub fn count(self) -> c_int                 { match self { Mono => 1, Stereo => 2 } }
}

pub type AudioCallback = ~fn(&mut [u8]);

pub struct DesiredAudioSpec {
    freq: c_int,
    format: AudioFormat,
    channels: Channels,
    samples: u16,
    callback: AudioCallback,
}

impl DesiredAudioSpec {
    fn to_ll_spec(self) -> ll::SDL_AudioSpec {
        unsafe {
            let DesiredAudioSpec { freq, format, channels, samples, callback } = self;
            ll::SDL_AudioSpec {
                freq: freq,
                format: format.to_ll_format(),
                channels: channels.count() as u8,
                silence: 0,
                samples: samples,
                padding: 0,
                size: 0,
                callback: native_callback,
                userdata: transmute(~callback),
            }
        }
    }
}

pub struct ObtainedAudioSpec {
    freq: c_int,
    format: AudioFormat,
    channels: Channels,
    silence: u8,
    samples: u16,
    size: u32,
}

impl ObtainedAudioSpec {
    static fn from_ll_spec(spec: &ll::SDL_AudioSpec) -> ObtainedAudioSpec {
        ObtainedAudioSpec {
            freq: spec.freq,
            format: AudioFormat::from_ll_format(spec.format),
            channels: Channels::new(spec.channels as c_int),
            silence: spec.silence,
            samples: spec.samples,
            size: spec.size,
        }
    }
}

extern fn native_callback(userdata: *c_void, stream: *mut u8, len: c_int) {
    unsafe {
        let callback: ~AudioCallback = transmute(userdata);
        let buffer = transmute((stream, len as uint));
        (*callback)(buffer);
        forget(callback);   // Don't free the callback!
    }
}

pub fn open(desired: DesiredAudioSpec) -> Result<ObtainedAudioSpec,()> {
    unsafe {
        let mut ll_desired = desired.to_ll_spec();
        let mut ll_obtained = ll::SDL_AudioSpec {
            freq: 0,
            format: 0,
            channels: 0,
            silence: 0,
            samples: 0,
            padding: 0,
            size: 0,
            callback: null(),
            userdata: null(),
        };

        if SDL_OpenAudio(&mut ll_desired, &mut ll_obtained) < 0 {
            Err(())
        } else {
            Ok(ObtainedAudioSpec::from_ll_spec(&ll_obtained))
        }
    }
}

pub fn pause(paused: bool) {
    unsafe {
        ll::SDL_PauseAudio(paused as c_int);
    }
}

pub fn close() {
    unsafe {
        ll::SDL_CloseAudio();
    }
}

pub fn mix(dest: &mut [u8], src: &[u8], volume: c_int) {
    unsafe {
        fail_unless!(dest.len() == src.len());
        SDL_MixAudio(&mut dest[0], &src[0], dest.len() as u32, volume);
    }
}

pub fn with_lock<R>(f: &fn() -> R) -> R {
    unsafe {
        SDL_LockAudio();
        let result = f();
        SDL_UnlockAudio();
        result
    }
}

<|endoftext|>


<commit_before>use hyper::server::Request;
use hyper::uri::RequestUri;

use std::collections::HashMap;

use common::*;

pub fn announce(req: &Request) -> Result<Vec<u8>, String>
{
    // Parse query pairs out of URL path and store in a HashMap
    let path = match req.uri {
        RequestUri::AbsolutePath(ref i) => i,
        _ => return Err("Problem retrieving path".to_string()),
    };

    let mut query_hashmap: HashMap<&str, &str> = HashMap::new();

    let query = match path.find('?') {
        Some(i) => &path[i+1..],
        None => "",
    };

    for component in query.split('&') {
        match component.find('=') {
            Some(position) => {
                query_hashmap.insert(&component[..position], &component[position + 1..]);
            }
            None => {},
        }
    }

    // Check we have everything we need
    let info_hash = match query_hashmap.get("info_hash")
        .ok_or_else(|| "No info_hash specified".to_string())
        .and_then(|i| parse_info_hash(i)) {
            Ok(j) => j,
            Err(j) => return Err(j),
    };
    let port = match query_hashmap.get("port") {
        Some(i) => i,
        None => return Err("No port specified".to_string()),
    };

    return Ok("worked".to_string().into_bytes());
}
<commit_msg>Announce: port parsing<commit_after>use hyper::server::Request;
use hyper::uri::RequestUri;

use std::collections::HashMap;

use common::*;

pub fn announce(req: &Request) -> Result<Vec<u8>, String>
{
    // Parse query pairs out of URL path and store in a HashMap
    let path = match req.uri {
        RequestUri::AbsolutePath(ref i) => i,
        _ => return Err("Problem retrieving path".to_string()),
    };

    let mut query_hashmap: HashMap<&str, &str> = HashMap::new();

    let query = match path.find('?') {
        Some(i) => &path[i+1..],
        None => "",
    };

    for component in query.split('&') {
        match component.find('=') {
            Some(position) => {
                query_hashmap.insert(&component[..position], &component[position + 1..]);
            }
            None => {},
        }
    }

    // Check we have everything we need
    let info_hash = match query_hashmap.get("info_hash")
        .ok_or_else(|| "No info_hash specified".to_string())
        .and_then(|i| parse_info_hash(i)) {
            Ok(j) => j,
            Err(j) => return Err(j),
    };
    let port = match query_hashmap.get("port")
        .ok_or_else(|| "No port specified".to_string())
        .and_then(|i| i.parse::<u16>().map_err(|_| "Invalid port specified".to_string())) {
            Ok(i) => i,
            Err(j) => return Err(j),
    };

    return Ok("worked".to_string().into_bytes());
}
<|endoftext|>


<commit_before>use std::{
    env,
    fs::File,
    io,
    path::{Path, PathBuf},
};

use anyhow::Result;
use flate2::{write::GzEncoder, Compression};
use xshell::{cmd, cp, mkdir_p, pushd, pushenv, read_file, rm_rf, write_file};

use crate::{date_iso, flags, project_root};

impl flags::Dist {
    pub(crate) fn run(self) -> Result<()> {
        let stable =
            std::env::var("GITHUB_REF").unwrap_or_default().as_str() == "refs/heads/release";

        let dist = project_root().join("dist");
        rm_rf(&dist)?;
        mkdir_p(&dist)?;

        if let Some(patch_version) = self.client_patch_version {
            let version = if stable {
                format!("0.2.{}", patch_version)
            } else {
                // A hack to make VS Code prefer nightly over stable.
                format!("0.3.{}", patch_version)
            };
            let release_tag = if stable { date_iso()? } else { "nightly".to_string() };
            dist_client(&version, &release_tag)?;
        }
        let release_channel = if stable { "stable" } else { "nightly" };
        dist_server(release_channel)?;
        Ok(())
    }
}

fn dist_client(version: &str, release_tag: &str) -> Result<()> {
    let _d = pushd("./editors/code")?;
    let nightly = release_tag == "nightly";

    let mut patch = Patch::new("./package.json")?;

    patch
        .replace(r#""version": "0.4.0-dev""#, &format!(r#""version": "{}""#, version))
        .replace(r#""releaseTag": null"#, &format!(r#""releaseTag": "{}""#, release_tag))
        .replace(r#""$generated-start": false,"#, "")
        .replace(",\n                \"$generated-end\": false", "");

    if nightly {
        patch.replace(
            r#""displayName": "rust-analyzer""#,
            r#""displayName": "rust-analyzer (nightly)""#,
        );
    }
    if !nightly {
        patch.replace(r#""enableProposedApi": true,"#, r#""#);
    }
    patch.commit()?;

    cmd!("npm ci").run()?;
    cmd!("npx vsce package -o ../../dist/rust-analyzer.vsix").run()?;
    Ok(())
}

fn dist_server(release_channel: &str) -> Result<()> {
    let _e = pushenv("RUST_ANALYZER_CHANNEL", release_channel);
    let _e = pushenv("CARGO_PROFILE_RELEASE_LTO", "true");
    let target = get_target();
    if target.contains("-linux-gnu") || target.contains("-linux-musl") {
        env::set_var("CC", "clang");
    }

    cmd!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target} --release").run()?;

    let suffix = exe_suffix(&target);
    let src =
        Path::new("target").join(&target).join("release").join(format!("rust-analyzer{}", suffix));
    let dst = Path::new("dist").join(format!("rust-analyzer-{}{}", target, suffix));
    gzip(&src, &dst.with_extension("gz"))?;

    // FIXME: the old names are temporarily kept for client compatibility, but they should be removed
    // Remove this block after a couple of releases
    match target.as_ref() {
        "x86_64-unknown-linux-gnu" => {
            cp(&src, "dist/rust-analyzer-linux")?;
            gzip(&src, Path::new("dist/rust-analyzer-linux.gz"))?;
        }
        "x86_64-pc-windows-msvc" => {
            cp(&src, "dist/rust-analyzer-windows.exe")?;
            gzip(&src, Path::new("dist/rust-analyzer-windows.gz"))?;
        }
        "x86_64-apple-darwin" => {
            cp(&src, "dist/rust-analyzer-mac")?;
            gzip(&src, Path::new("dist/rust-analyzer-mac.gz"))?;
        }
        _ => {}
    }

    Ok(())
}

fn get_target() -> String {
    match env::var("RA_TARGET") {
        Ok(target) => target,
        _ => {
            if cfg!(target_os = "linux") {
                "x86_64-unknown-linux-gnu".to_string()
            } else if cfg!(target_os = "windows") {
                "x86_64-pc-windows-msvc".to_string()
            } else if cfg!(target_os = "macos") {
                "x86_64-apple-darwin".to_string()
            } else {
                panic!("Unsupported OS, maybe try setting RA_TARGET")
            }
        }
    }
}

fn exe_suffix(target: &str) -> String {
    if target.contains("-windows-") {
        ".exe".into()
    } else {
        "".into()
    }
}

fn gzip(src_path: &Path, dest_path: &Path) -> Result<()> {
    let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best());
    let mut input = io::BufReader::new(File::open(src_path)?);
    io::copy(&mut input, &mut encoder)?;
    encoder.finish()?;
    Ok(())
}

struct Patch {
    path: PathBuf,
    original_contents: String,
    contents: String,
}

impl Patch {
    fn new(path: impl Into<PathBuf>) -> Result<Patch> {
        let path = path.into();
        let contents = read_file(&path)?;
        Ok(Patch { path, original_contents: contents.clone(), contents })
    }

    fn replace(&mut self, from: &str, to: &str) -> &mut Patch {
        assert!(self.contents.contains(from));
        self.contents = self.contents.replace(from, to);
        self
    }

    fn commit(&self) -> Result<()> {
        write_file(&self.path, &self.contents)?;
        Ok(())
    }
}

impl Drop for Patch {
    fn drop(&mut self) {
        write_file(&self.path, &self.original_contents).unwrap();
    }
}
<commit_msg>Drop uncompressed release artifacts and those following the old naming convention<commit_after>use std::{
    env,
    fs::File,
    io,
    path::{Path, PathBuf},
};

use anyhow::Result;
use flate2::{write::GzEncoder, Compression};
use xshell::{cmd, mkdir_p, pushd, pushenv, read_file, rm_rf, write_file};

use crate::{date_iso, flags, project_root};

impl flags::Dist {
    pub(crate) fn run(self) -> Result<()> {
        let stable =
            std::env::var("GITHUB_REF").unwrap_or_default().as_str() == "refs/heads/release";

        let dist = project_root().join("dist");
        rm_rf(&dist)?;
        mkdir_p(&dist)?;

        if let Some(patch_version) = self.client_patch_version {
            let version = if stable {
                format!("0.2.{}", patch_version)
            } else {
                // A hack to make VS Code prefer nightly over stable.
                format!("0.3.{}", patch_version)
            };
            let release_tag = if stable { date_iso()? } else { "nightly".to_string() };
            dist_client(&version, &release_tag)?;
        }
        let release_channel = if stable { "stable" } else { "nightly" };
        dist_server(release_channel)?;
        Ok(())
    }
}

fn dist_client(version: &str, release_tag: &str) -> Result<()> {
    let _d = pushd("./editors/code")?;
    let nightly = release_tag == "nightly";

    let mut patch = Patch::new("./package.json")?;

    patch
        .replace(r#""version": "0.4.0-dev""#, &format!(r#""version": "{}""#, version))
        .replace(r#""releaseTag": null"#, &format!(r#""releaseTag": "{}""#, release_tag))
        .replace(r#""$generated-start": false,"#, "")
        .replace(",\n                \"$generated-end\": false", "");

    if nightly {
        patch.replace(
            r#""displayName": "rust-analyzer""#,
            r#""displayName": "rust-analyzer (nightly)""#,
        );
    }
    if !nightly {
        patch.replace(r#""enableProposedApi": true,"#, r#""#);
    }
    patch.commit()?;

    cmd!("npm ci").run()?;
    cmd!("npx vsce package -o ../../dist/rust-analyzer.vsix").run()?;
    Ok(())
}

fn dist_server(release_channel: &str) -> Result<()> {
    let _e = pushenv("RUST_ANALYZER_CHANNEL", release_channel);
    let _e = pushenv("CARGO_PROFILE_RELEASE_LTO", "true");
    let target = get_target();
    if target.contains("-linux-gnu") || target.contains("-linux-musl") {
        env::set_var("CC", "clang");
    }

    cmd!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target} --release").run()?;

    let suffix = exe_suffix(&target);
    let src =
        Path::new("target").join(&target).join("release").join(format!("rust-analyzer{}", suffix));
    let dst = Path::new("dist").join(format!("rust-analyzer-{}{}", target, suffix));
    gzip(&src, &dst.with_extension("gz"))?;

    Ok(())
}

fn get_target() -> String {
    match env::var("RA_TARGET") {
        Ok(target) => target,
        _ => {
            if cfg!(target_os = "linux") {
                "x86_64-unknown-linux-gnu".to_string()
            } else if cfg!(target_os = "windows") {
                "x86_64-pc-windows-msvc".to_string()
            } else if cfg!(target_os = "macos") {
                "x86_64-apple-darwin".to_string()
            } else {
                panic!("Unsupported OS, maybe try setting RA_TARGET")
            }
        }
    }
}

fn exe_suffix(target: &str) -> String {
    if target.contains("-windows-") {
        ".exe".into()
    } else {
        "".into()
    }
}

fn gzip(src_path: &Path, dest_path: &Path) -> Result<()> {
    let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best());
    let mut input = io::BufReader::new(File::open(src_path)?);
    io::copy(&mut input, &mut encoder)?;
    encoder.finish()?;
    Ok(())
}

struct Patch {
    path: PathBuf,
    original_contents: String,
    contents: String,
}

impl Patch {
    fn new(path: impl Into<PathBuf>) -> Result<Patch> {
        let path = path.into();
        let contents = read_file(&path)?;
        Ok(Patch { path, original_contents: contents.clone(), contents })
    }

    fn replace(&mut self, from: &str, to: &str) -> &mut Patch {
        assert!(self.contents.contains(from));
        self.contents = self.contents.replace(from, to);
        self
    }

    fn commit(&self) -> Result<()> {
        write_file(&self.path, &self.contents)?;
        Ok(())
    }
}

impl Drop for Patch {
    fn drop(&mut self) {
        write_file(&self.path, &self.original_contents).unwrap();
    }
}
<|endoftext|>


<commit_before>//! See https://github.com/matklad/cargo-xtask/.
//!
//! This binary defines various auxiliary build commands, which are not
//! expressible with just `cargo`. Notably, it provides `cargo xtask codegen`
//! for code generation and `cargo xtask install` for installation of
//! rust-analyzer server and client.
//!
//! This binary is integrated into the `cargo` command line by using an alias in
//! `.cargo/config`.
mod flags;

mod codegen;
mod ast_src;
#[cfg(test)]
mod tidy;

mod install;
mod release;
mod dist;
mod metrics;
mod pre_cache;

use anyhow::{bail, Result};
use std::{
    env,
    path::{Path, PathBuf},
};
use walkdir::{DirEntry, WalkDir};
use xshell::{cmd, cp, pushd, pushenv};

use crate::{
    codegen::Mode,
    dist::DistCmd,
    install::{InstallCmd, Malloc, ServerOpt},
};

fn main() -> Result<()> {
    let _d = pushd(project_root())?;

    let flags = flags::Xtask::from_env()?;
    match flags.subcommand {
        flags::XtaskCmd::Help(_) => {
            println!("{}", flags::Xtask::HELP);
            return Ok(());
        }
        flags::XtaskCmd::Install(flags) => {
            if flags.server && flags.client {
                eprintln!(
                    "error: The argument `--server` cannot be used with `--client`\n\n\
                     For more information try --help"
                );
                return Ok(());
            }

            let malloc = if flags.mimalloc {
                Malloc::Mimalloc
            } else if flags.jemalloc {
                Malloc::Jemalloc
            } else {
                Malloc::System
            };

            let client_bin = flags.code_bin.map(|it| it.parse()).transpose()?;

            InstallCmd {
                client: if flags.server { None } else { client_bin },
                server: if flags.client { None } else { Some(ServerOpt { malloc }) },
            }
            .run()
        }
        flags::XtaskCmd::Codegen(cmd) => cmd.run(),
        flags::XtaskCmd::Lint(_) => run_clippy(),
        flags::XtaskCmd::FuzzTests(_) => run_fuzzer(),
        flags::XtaskCmd::PreCache(cmd) => cmd.run(),
        flags::XtaskCmd::Release(cmd) => cmd.run(),
        flags::XtaskCmd::Promote(cmd) => cmd.run(),
        flags::XtaskCmd::Dist(flags) => {
            DistCmd { nightly: flags.nightly, client_version: flags.client }.run()
        }
        flags::XtaskCmd::Metrics(cmd) => cmd.run(),
        flags::XtaskCmd::Bb(cmd) => {
            {
                let _d = pushd("./crates/rust-analyzer")?;
                cmd!("cargo build --release --features jemalloc").run()?;
            }
            cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", cmd.suffix))?;
            Ok(())
        }
    }
}

fn project_root() -> PathBuf {
    Path::new(
        &env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
    )
    .ancestors()
    .nth(1)
    .unwrap()
    .to_path_buf()
}

fn rust_files() -> impl Iterator<Item = PathBuf> {
    rust_files_in(&project_root().join("crates"))
}

#[cfg(test)]
fn cargo_files() -> impl Iterator<Item = PathBuf> {
    files_in(&project_root(), "toml")
        .filter(|path| path.file_name().map(|it| it == "Cargo.toml").unwrap_or(false))
}

fn rust_files_in(path: &Path) -> impl Iterator<Item = PathBuf> {
    files_in(path, "rs")
}

fn run_rustfmt(mode: Mode) -> Result<()> {
    let _dir = pushd(project_root())?;
    let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
    ensure_rustfmt()?;
    let check = match mode {
        Mode::Overwrite => &[][..],
        Mode::Verify => &["--", "--check"],
    };
    cmd!("cargo fmt {check...}").run()?;
    Ok(())
}

fn ensure_rustfmt() -> Result<()> {
    let out = cmd!("rustfmt --version").read()?;
    if !out.contains("stable") {
        bail!(
            "Failed to run rustfmt from toolchain 'stable'. \
             Please run `rustup component add rustfmt --toolchain stable` to install it.",
        )
    }
    Ok(())
}

fn run_clippy() -> Result<()> {
    if cmd!("cargo clippy --version").read().is_err() {
        bail!(
            "Failed run cargo clippy. \
            Please run `rustup component add clippy` to install it.",
        )
    }

    let allowed_lints = "
        -A clippy::collapsible_if
        -A clippy::needless_pass_by_value
        -A clippy::nonminimal_bool
        -A clippy::redundant_pattern_matching
    "
    .split_ascii_whitespace();
    cmd!("cargo clippy --all-features --all-targets -- {allowed_lints...}").run()?;
    Ok(())
}

fn run_fuzzer() -> Result<()> {
    let _d = pushd("./crates/syntax")?;
    let _e = pushenv("RUSTUP_TOOLCHAIN", "nightly");
    if cmd!("cargo fuzz --help").read().is_err() {
        cmd!("cargo install cargo-fuzz").run()?;
    };

    // Expecting nightly rustc
    let out = cmd!("rustc --version").read()?;
    if !out.contains("nightly") {
        bail!("fuzz tests require nightly rustc")
    }

    cmd!("cargo fuzz run parser").run()?;
    Ok(())
}

fn date_iso() -> Result<String> {
    let res = cmd!("date --iso --utc").read()?;
    Ok(res)
}

fn is_release_tag(tag: &str) -> bool {
    tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())
}

fn files_in(path: &Path, ext: &'static str) -> impl Iterator<Item = PathBuf> {
    let iter = WalkDir::new(path);
    return iter
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .map(|e| e.unwrap())
        .filter(|e| !e.file_type().is_dir())
        .map(|e| e.into_path())
        .filter(move |path| path.extension().map(|it| it == ext).unwrap_or(false));

    fn is_hidden(entry: &DirEntry) -> bool {
        entry.file_name().to_str().map(|s| s.starts_with('.')).unwrap_or(false)
    }
}
<commit_msg>Fix regression where the client was not installed<commit_after>//! See https://github.com/matklad/cargo-xtask/.
//!
//! This binary defines various auxiliary build commands, which are not
//! expressible with just `cargo`. Notably, it provides `cargo xtask codegen`
//! for code generation and `cargo xtask install` for installation of
//! rust-analyzer server and client.
//!
//! This binary is integrated into the `cargo` command line by using an alias in
//! `.cargo/config`.
mod flags;

mod codegen;
mod ast_src;
#[cfg(test)]
mod tidy;

mod install;
mod release;
mod dist;
mod metrics;
mod pre_cache;

use anyhow::{bail, Result};
use std::{
    env,
    path::{Path, PathBuf},
};
use walkdir::{DirEntry, WalkDir};
use xshell::{cmd, cp, pushd, pushenv};

use crate::{
    codegen::Mode,
    dist::DistCmd,
    install::{InstallCmd, Malloc, ServerOpt},
};

fn main() -> Result<()> {
    let _d = pushd(project_root())?;

    let flags = flags::Xtask::from_env()?;
    match flags.subcommand {
        flags::XtaskCmd::Help(_) => {
            println!("{}", flags::Xtask::HELP);
            return Ok(());
        }
        flags::XtaskCmd::Install(flags) => {
            if flags.server && flags.client {
                eprintln!(
                    "error: The argument `--server` cannot be used with `--client`\n\n\
                     For more information try --help"
                );
                return Ok(());
            }

            let malloc = if flags.mimalloc {
                Malloc::Mimalloc
            } else if flags.jemalloc {
                Malloc::Jemalloc
            } else {
                Malloc::System
            };

            let client_bin = flags.code_bin.map(|it| it.parse()).transpose()?;

            InstallCmd {
                client: if flags.server { None } else { Some(client_bin).unwrap_or_default() },
                server: if flags.client { None } else { Some(ServerOpt { malloc }) },
            }
            .run()
        }
        flags::XtaskCmd::Codegen(cmd) => cmd.run(),
        flags::XtaskCmd::Lint(_) => run_clippy(),
        flags::XtaskCmd::FuzzTests(_) => run_fuzzer(),
        flags::XtaskCmd::PreCache(cmd) => cmd.run(),
        flags::XtaskCmd::Release(cmd) => cmd.run(),
        flags::XtaskCmd::Promote(cmd) => cmd.run(),
        flags::XtaskCmd::Dist(flags) => {
            DistCmd { nightly: flags.nightly, client_version: flags.client }.run()
        }
        flags::XtaskCmd::Metrics(cmd) => cmd.run(),
        flags::XtaskCmd::Bb(cmd) => {
            {
                let _d = pushd("./crates/rust-analyzer")?;
                cmd!("cargo build --release --features jemalloc").run()?;
            }
            cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", cmd.suffix))?;
            Ok(())
        }
    }
}

fn project_root() -> PathBuf {
    Path::new(
        &env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
    )
    .ancestors()
    .nth(1)
    .unwrap()
    .to_path_buf()
}

fn rust_files() -> impl Iterator<Item = PathBuf> {
    rust_files_in(&project_root().join("crates"))
}

#[cfg(test)]
fn cargo_files() -> impl Iterator<Item = PathBuf> {
    files_in(&project_root(), "toml")
        .filter(|path| path.file_name().map(|it| it == "Cargo.toml").unwrap_or(false))
}

fn rust_files_in(path: &Path) -> impl Iterator<Item = PathBuf> {
    files_in(path, "rs")
}

fn run_rustfmt(mode: Mode) -> Result<()> {
    let _dir = pushd(project_root())?;
    let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
    ensure_rustfmt()?;
    let check = match mode {
        Mode::Overwrite => &[][..],
        Mode::Verify => &["--", "--check"],
    };
    cmd!("cargo fmt {check...}").run()?;
    Ok(())
}

fn ensure_rustfmt() -> Result<()> {
    let out = cmd!("rustfmt --version").read()?;
    if !out.contains("stable") {
        bail!(
            "Failed to run rustfmt from toolchain 'stable'. \
             Please run `rustup component add rustfmt --toolchain stable` to install it.",
        )
    }
    Ok(())
}

fn run_clippy() -> Result<()> {
    if cmd!("cargo clippy --version").read().is_err() {
        bail!(
            "Failed run cargo clippy. \
            Please run `rustup component add clippy` to install it.",
        )
    }

    let allowed_lints = "
        -A clippy::collapsible_if
        -A clippy::needless_pass_by_value
        -A clippy::nonminimal_bool
        -A clippy::redundant_pattern_matching
    "
    .split_ascii_whitespace();
    cmd!("cargo clippy --all-features --all-targets -- {allowed_lints...}").run()?;
    Ok(())
}

fn run_fuzzer() -> Result<()> {
    let _d = pushd("./crates/syntax")?;
    let _e = pushenv("RUSTUP_TOOLCHAIN", "nightly");
    if cmd!("cargo fuzz --help").read().is_err() {
        cmd!("cargo install cargo-fuzz").run()?;
    };

    // Expecting nightly rustc
    let out = cmd!("rustc --version").read()?;
    if !out.contains("nightly") {
        bail!("fuzz tests require nightly rustc")
    }

    cmd!("cargo fuzz run parser").run()?;
    Ok(())
}

fn date_iso() -> Result<String> {
    let res = cmd!("date --iso --utc").read()?;
    Ok(res)
}

fn is_release_tag(tag: &str) -> bool {
    tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())
}

fn files_in(path: &Path, ext: &'static str) -> impl Iterator<Item = PathBuf> {
    let iter = WalkDir::new(path);
    return iter
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .map(|e| e.unwrap())
        .filter(|e| !e.file_type().is_dir())
        .map(|e| e.into_path())
        .filter(move |path| path.extension().map(|it| it == ext).unwrap_or(false));

    fn is_hidden(entry: &DirEntry) -> bool {
        entry.file_name().to_str().map(|s| s.starts_with('.')).unwrap_or(false)
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers.
// Copyright 2015 Guillaume Gomez
//
// 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.

//! Library to interface with chunks of memory allocated in C.
//!
//! It is often desirable to safely interface with memory allocated from C,
//! encapsulating the unsafety into allocation and destruction time.  Indeed,
//! allocating memory externally is currently the only way to give Rust shared
//! mut state with C programs that keep their own references; vectors are
//! unsuitable because they could be reallocated or moved at any time, and
//! importing C memory into a vector takes a one-time snapshot of the memory.
//!
//! This module simplifies the usage of such external blocks of memory.  Memory
//! is encapsulated into an opaque object after creation; the lifecycle of the
//! memory can be optionally managed by Rust, if an appropriate destructor
//! closure is provided.  Safety is ensured by bounds-checking accesses, which
//! are marshalled through get and set functions.
//!
//! There are three unsafe functions: the two constructors, and the
//! unwrap method. The constructors are unsafe for the
//! obvious reason (they act on a pointer that cannot be checked inside the
//! method), but `unwrap()` is somewhat more subtle in its unsafety.
//! It returns the contained pointer, but at the same time destroys the CVec
//! without running its destructor. This can be used to pass memory back to
//! C, but care must be taken that the ownership of underlying resources are
//! handled correctly, i.e. that allocated memory is eventually freed
//! if necessary.

#![feature(unsafe_destructor, core, std_misc)]

use std::mem;
use std::ops::{Drop, FnOnce};
use std::option::Option;
use std::option::Option::{Some, None};
use std::ptr::PtrExt;
use std::ptr;
use std::raw;
use std::slice::AsSlice;
use std::thunk::{Thunk};

/// The type representing a foreign chunk of memory
pub struct CVec<'b, T> {
    base: *mut T,
    len: usize,
    dtor: Option<Thunk<'b>>
}

#[unsafe_destructor]
impl<'b, T> Drop for CVec<'b T> {
    fn drop(&mut self) {
        match self.dtor.take() {
            None => (),
            Some(f) => f.invoke(())
        }
    }
}

impl<'b, T> CVec<'b, T> {
    /// Create a `CVec` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A raw pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: *mut T, len: usize) -> CVec<'b, T> {
        assert!(base != ptr::null_mut());
        CVec {
            base: base,
            len: len,
            dtor: None,
        }
    }

    /// Create a `CVec` from a foreign buffer, with a given length,
    /// and a function to run upon destruction.
    ///
    /// Panics if the given pointer is null.
    ///
    /// # Arguments
    ///
    /// * base - A foreign pointer to a buffer
    /// * len - The number of elements in the buffer
    /// * dtor - A fn to run when the value is destructed, useful
    ///          for freeing the buffer, etc.
    pub unsafe fn new_with_dtor<F>(base: *mut T,
                                   len: usize,
                                   dtor: F)
                                   -> CVec<'b, T>
        where F : FnOnce(), F : Send, F : 'b
    {
        assert!(base != ptr::null_mut());
        let dtor: Thunk = Thunk::new(dtor);
        CVec {
            base: base,
            len: len,
            dtor: Some(dtor)
        }
    }

    /// View the stored data as a mutable slice.
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {
            mem::transmute(raw::Slice { data: self.base as *const T, len: self.len })
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Unwrap the pointer without running the destructor
    ///
    /// This method retrieves the underlying pointer, and in the process
    /// destroys the CVec but without running the destructor. A use case
    /// would be transferring ownership of the buffer to a C function, as
    /// in this case you would not want to run the destructor.
    ///
    /// Note that if you want to access the underlying pointer without
    /// cancelling the destructor, you can simply call `transmute` on the return
    /// value of `get(0)`.
    pub unsafe fn into_inner(mut self) -> *mut T {
        self.dtor = None;
        self.base
    }

    /// Deprecated, use into_inner() instead
    #[deprecated = "renamed to into_inner()"]
    pub unsafe fn unwrap(self) -> *mut T { self.into_inner() }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<'b, T> AsSlice<T> for CVec<'b, T> {
    /// View the stored data as a slice.
    fn as_slice<'a>(&'a self) -> &'a [T] {
        unsafe {
            mem::transmute(raw::Slice { data: self.base as *const T, len: self.len })
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate libc;

    use super::CVec;
    use std::ptr;

    fn malloc(n: usize) -> CVec<'static, u8> {
        unsafe {
            let mem = ptr::Unique::new(libc::malloc(n as libc::size_t));
            if (*mem).is_null() { alloc::oom() }

            CVec::new_with_dtor(*mem as *mut u8,
                                n,
                                move|| { libc::free((*mem) as *mut libc::c_void); })
        }
    }

    #[test]
    fn test_basic() {
        let mut cv = malloc(16);

        *cv.get_mut(3).unwrap() = 8;
        *cv.get_mut(4).unwrap() = 9;
        assert_eq!(*cv.get(3).unwrap(), 8);
        assert_eq!(*cv.get(4).unwrap(), 9);
        assert_eq!(cv.len(), 16);
    }

    #[test]
    #[should_fail]
    fn test_panic_at_null() {
        unsafe {
            CVec::new(ptr::null_mut::<u8>(), 9);
        }
    }

    #[test]
    fn test_overrun_get() {
        let cv = malloc(16);

        assert!(cv.get(17).is_none());
    }

    #[test]
    fn test_overrun_set() {
        let mut cv = malloc(16);

        assert!(cv.get_mut(17).is_none());
    }

    #[test]
    fn test_unwrap() {
        unsafe {
            let cv = CVec::new_with_dtor(1 as *mut isize,
                                         0,
                                         move|| panic!("Don't run this destructor!"));
            let p = cv.into_inner();
            assert_eq!(p, 1 as *mut isize);
        }
    }

}
<commit_msg>Improve CVec API<commit_after>// Copyright 2012 The Rust Project Developers.
// Copyright 2015 Guillaume Gomez
//
// 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.

//! Library to interface with chunks of memory allocated in C.
//!
//! It is often desirable to safely interface with memory allocated from C,
//! encapsulating the unsafety into allocation and destruction time.  Indeed,
//! allocating memory externally is currently the only way to give Rust shared
//! mut state with C programs that keep their own references; vectors are
//! unsuitable because they could be reallocated or moved at any time, and
//! importing C memory into a vector takes a one-time snapshot of the memory.
//!
//! This module simplifies the usage of such external blocks of memory.  Memory
//! is encapsulated into an opaque object after creation; the lifecycle of the
//! memory can be optionally managed by Rust, if an appropriate destructor
//! closure is provided.  Safety is ensured by bounds-checking accesses, which
//! are marshalled through get and set functions.
//!
//! There are three unsafe functions: the two constructors, and the
//! unwrapping method. The constructors are unsafe for the
//! obvious reason (they act on a pointer that cannot be checked inside the
//! method), but `into_inner()` is somewhat more subtle in its unsafety.
//! It returns the contained pointer, but at the same time destroys the CVec
//! without running its destructor. This can be used to pass memory back to
//! C, but care must be taken that the ownership of underlying resources are
//! handled correctly, i.e. that allocated memory is eventually freed
//! if necessary.

#![feature(unsafe_destructor, core, std_misc, unique)]

use std::mem;
use std::ptr;
use std::raw;
use std::ptr::Unique;
use std::thunk::Invoke;

/// The type representing a foreign chunk of memory
pub struct CVec<T> {
    base: Unique<T>,
    len: usize,
    dtor: Option<Box<Invoke<*mut T> + 'static>>
}

#[unsafe_destructor]
impl<T> Drop for CVec<T> {
    fn drop(&mut self) {
        match self.dtor.take() {
            None => (),
            Some(f) => f.invoke(*self.base),
        }
    }
}

impl<T> CVec<T> {
    /// Create a `CVec` from a raw pointer to a buffer with a given length.
    ///
    /// Panics if the given pointer is null. The returned vector will not attempt
    /// to deallocate the vector when dropped.
    ///
    /// # Arguments
    ///
    /// * base - A raw pointer to a buffer
    /// * len - The number of elements in the buffer
    pub unsafe fn new(base: Unique<T>, len: usize) -> CVec<T> {
        assert!(*base != ptr::null_mut());
        CVec {
            base: base,
            len: len,
            dtor: None,
        }
    }

    /// Create a `CVec` from a foreign buffer, with a given length,
    /// and a function to run upon destruction.
    ///
    /// Panics if the given pointer is null.
    ///
    /// # Arguments
    ///
    /// * base - A unique pointer to a buffer
    /// * len - The number of elements in the buffer
    /// * dtor - A fn to run when the value is destructed, useful
    ///          for freeing the buffer, etc. `base` will be passed
    ///          to it as an argument.
    pub unsafe fn new_with_dtor<F>(base: Unique<T>,
                                   len: usize,
                                   dtor: F)
                                   -> CVec<T>
        where F : FnOnce(*mut T) + 'static
    {
        assert!(*base != ptr::null_mut());
        let dtor = Box::new(dtor);
        CVec {
            base: base,
            len: len,
            dtor: Some(dtor)
        }
    }

    /// View the stored data as a mutable slice.
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {
            mem::transmute(raw::Slice { data: *self.base as *const T, len: self.len })
        }
    }

    /// Retrieves an element at a given index, returning `None` if the requested
    /// index is greater than the length of the vector.
    pub fn get<'a>(&'a self, ofs: usize) -> Option<&'a T> {
        if ofs < self.len {
            Some(unsafe { &*self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Retrieves a mutable element at a given index, returning `None` if the
    /// requested index is greater than the length of the vector.
    pub fn get_mut<'a>(&'a mut self, ofs: usize) -> Option<&'a mut T> {
        if ofs < self.len {
            Some(unsafe { &mut *self.base.offset(ofs as isize) })
        } else {
            None
        }
    }

    /// Unwrap the pointer without running the destructor
    ///
    /// This method retrieves the underlying pointer, and in the process
    /// destroys the CVec but without running the destructor. A use case
    /// would be transferring ownership of the buffer to a C function, as
    /// in this case you would not want to run the destructor.
    ///
    /// Note that if you want to access the underlying pointer without
    /// cancelling the destructor, you can simply call `transmute` on the return
    /// value of `get(0)`.
    pub unsafe fn into_inner(mut self) -> *mut T {
        self.dtor = None;
        *self.base
    }

    /// Returns the number of items in this vector.
    pub fn len(&self) -> usize { self.len }

    /// Returns whether this vector is empty.
    pub fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> AsSlice<T> for CVec<T> {
    /// View the stored data as a slice.
    fn as_slice<'a>(&'a self) -> &'a [T] {
        unsafe {
            mem::transmute(raw::Slice { data: *self.base as *const T, len: self.len })
        }
    }
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate libc;

    use super::CVec;
    use std::ptr::{self, Unique};

    fn malloc(n: usize) -> CVec<u8> {
        unsafe {
            let mem: Unique<u8> = Unique::new(
                libc::malloc(n as libc::size_t) as *mut _);
            if (*mem).is_null() { alloc::oom() }

            CVec::new_with_dtor(mem, n,
                                |mem| { libc::free((mem) as *mut _); })
        }
    }

    #[test]
    fn test_basic() {
        let mut cv = malloc(16);

        *cv.get_mut(3).unwrap() = 8;
        *cv.get_mut(4).unwrap() = 9;
        assert_eq!(*cv.get(3).unwrap(), 8);
        assert_eq!(*cv.get(4).unwrap(), 9);
        assert_eq!(cv.len(), 16);
    }

    #[test]
    #[should_fail]
    fn test_panic_at_null() {
        unsafe {
            CVec::new(Unique::new(ptr::null_mut::<u8>()), 9);
        }
    }

    #[test]
    fn test_overrun_get() {
        let cv = malloc(16);

        assert!(cv.get(17).is_none());
    }

    #[test]
    fn test_overrun_set() {
        let mut cv = malloc(16);

        assert!(cv.get_mut(17).is_none());
    }

    #[test]
    fn test_unwrap() {
        unsafe {
            let cv = CVec::new_with_dtor(Unique::new(1 as *mut isize),
                                         0,
                                         |_| panic!("Don't run this destructor!"));
            let p = cv.into_inner();
            assert_eq!(p, 1 as *mut isize);
        }
    }

}
<|endoftext|>


<commit_before>use sdl::{event, render, pixels, video, keycode};
use sdl::rect::Point;
use std::default::Default;

type Renderer = render::Renderer<video::Window>;

static TURN_SPEED: f32 = 0.1;
static ACCELERATION: f32 = 0.1;

pub struct Loop {
    renderer: Renderer,
    state: State,
}

impl Loop {
    pub fn new(renderer: Renderer) -> Loop {
        let output_size = renderer.get_output_size().unwrap();
        Loop {
            renderer: renderer,
            state: State::new(output_size)
        }
    }

    pub fn handlekey(&mut self, keyDown: bool, key: keycode::KeyCode) {
        // I'm feeling a bit iffy about this. Ideally, no dummy variable
        // should be needed.
        let mut dummy = false;
        let keys = &mut self.state.keys;
        let oldkeys = *keys;
        *match key {
            keycode::UpKey => &mut keys.up,
            keycode::DownKey => &mut keys.down,
            keycode::LeftKey => &mut keys.left,
            keycode::RightKey => &mut keys.right,
            keycode::SpaceKey => &mut keys.space,
            _ => &mut dummy // Ignore any other keys
        } = keyDown;
        if *keys != oldkeys {
            println!("{}", *keys);
        }
    }

    pub fn update(&mut self) {
        {
            let keys = self.state.keys;
            let player = &mut self.state.player1;
            if keys.up { player.accelerate() }
            if keys.down { player.decelerate() }
            if keys.left { player.turn_left() }
            if keys.right { player.turn_right() }
        }
        self.draw();
    }

    pub fn draw(&self) {
        let renderer = &self.renderer;
        renderer.set_draw_color(pixels::RGB(0, 0, 0)).unwrap();
        renderer.clear().unwrap();
        self.state.player1.draw(renderer);
        renderer.present();
    }
}

struct State {
    keys: KeyState,
    player1: PlayerShip
}

impl State {
    fn new(dims: (int, int)) -> State {
        let midpoint = {
        };
        State {
            keys: Default::default(),
            player1: PlayerShip::new(dims)
        }
    }
}

#[deriving(Default, PartialEq, Eq, Show)]
struct KeyState {
    down: bool,
    left: bool,
    right: bool,
    up: bool,
    space: bool,
}

// For smoother movement, everything is stored to 64th of a pixel accuracy
struct PlayerShip {
    pos: Point,
    vel: Point,
    angle: f32, // Zero points upwards.
    dimensions: (int, int),
}

impl PlayerShip {
    fn new((xmax, ymax): (int, int)) -> PlayerShip {
        PlayerShip {
            pos: Point::new(0, 0),
            vel: Point::new(0, 0),
            angle: 0.0,
            dimensions: (xmax*64, ymax*64)
        }
    }

    fn accelerate(&mut self) {
    }
    fn decelerate(&mut self) {
    }
    fn turn_left(&mut self) {
    }
    fn turn_right(&mut self) {
    }

    fn update(&mut self) {
    }

    fn draw(&self, renderer: &Renderer) {
        renderer.set_draw_color(pixels::RGB(255, 255, 255)).unwrap();
    }
}
<commit_msg>Draw the ship on the screen.<commit_after>use sdl::{event, render, pixels, video, keycode};
use sdl::rect::Point;
use std::default::Default;

type Renderer = render::Renderer<video::Window>;

static TURN_SPEED: f32 = 0.001;
static ACCELERATION: f32 = 0.1;

pub struct Loop {
    renderer: Renderer,
    state: State,
}

impl Loop {
    pub fn new(renderer: Renderer) -> Loop {
        let output_size = renderer.get_output_size().unwrap();
        Loop {
            renderer: renderer,
            state: State::new(output_size)
        }
    }

    pub fn handlekey(&mut self, keyDown: bool, key: keycode::KeyCode) {
        // I'm feeling a bit iffy about this. Ideally, no dummy variable
        // should be needed.
        let mut dummy = false;
        let keys = &mut self.state.keys;
        let oldkeys = *keys;
        *match key {
            keycode::UpKey => &mut keys.up,
            keycode::DownKey => &mut keys.down,
            keycode::LeftKey => &mut keys.left,
            keycode::RightKey => &mut keys.right,
            keycode::SpaceKey => &mut keys.space,
            _ => &mut dummy // Ignore any other keys
        } = keyDown;
        if *keys != oldkeys {
            println!("{}", *keys);
        }
    }

    pub fn update(&mut self) {
        {
            let keys = self.state.keys;
            let player = &mut self.state.player1;
            if keys.up { player.accelerate() }
            if keys.down { player.decelerate() }
            if keys.left { player.turn_left() }
            if keys.right { player.turn_right() }
        }
        self.draw();
    }

    pub fn draw(&self) {
        let renderer = &self.renderer;
        renderer.set_draw_color(pixels::RGB(0, 0, 0)).unwrap();
        renderer.clear().unwrap();
        self.state.player1.draw(renderer);
        renderer.present();
    }
}

struct State {
    keys: KeyState,
    player1: PlayerShip
}

impl State {
    fn new(dims: (int, int)) -> State {
        let midpoint = {
        };
        State {
            keys: Default::default(),
            player1: PlayerShip::new(dims)
        }
    }
}

#[deriving(Default, PartialEq, Eq, Show)]
struct KeyState {
    down: bool,
    left: bool,
    right: bool,
    up: bool,
    space: bool,
}

// For smoother movement, everything is stored to 64th of a pixel accuracy
struct PlayerShip {
    pos: Point,
    vel: Point,
    angle: f32, // Zero points upwards.
    shape: Vec<(f32,f32)>,
}

impl PlayerShip {
    fn new((xmax, ymax): (int, int)) -> PlayerShip {
        let mut shape = Vec::new();
        shape.push_all([(0.0,-10.0),(-5.0,10.0),(0.0,3.0),(5.0,10.0),(0.0,-10.0)]);

        PlayerShip {
            pos: Point::new(0, 0),
            vel: Point::new(0, 0),
            angle: 0.0,
            shape: shape,
        }
    }

    fn accelerate(&mut self) {
    }
    fn decelerate(&mut self) {
    }
    fn turn_left(&mut self) {
        self.angle = self.angle - TURN_SPEED;
    }
    fn turn_right(&mut self) {
        self.angle = self.angle + TURN_SPEED;
    }

    fn update(&mut self) {
    }

    fn draw(&self, renderer: &Renderer) {
        let midpoint = { let (x,y) = renderer.get_output_size().unwrap();
            Point::new((x/2) as i32,(y/2) as i32)
        };
        let rotated_shape = self.shape
            .iter()
            .map(|&point| rotate(point, self.angle))
            .map(|(x,y)| translate(Point::new(x as i32, y as i32),midpoint))
            .collect::<Vec<Point>>();
        renderer.set_draw_color(pixels::RGB(255, 255, 255)).unwrap();
        renderer.draw_lines(rotated_shape.as_slice());
    }
}

fn rotate((x,y): (f32,f32), angle: f32) -> (f32,f32) {
    (x * angle.cos() + y * angle.sin(), x * angle.sin() - y * angle.cos())
}

fn translate(point: Point, by: Point) -> Point {
    Point::new(point.x + by.x, point.y + by.y)
}
<|endoftext|>


<commit_before>extern crate rand;
use game::rand::prelude::*;
use std::collections::HashMap;

use table::Table;
use player::Player;
use player::PlayerKind;

pub enum GameState {
    XWon,
    OWon,
    HumanWon,
    ComputerWon,
    Tie
}

pub struct Game {
    player: Player,
    table: Table,
    available_moves: HashMap<usize, usize>,
    ref_available_moves: Vec<usize>,
    against_computer: bool,
    over: bool,
    running: bool,
    steps: u32
}

fn game_template() -> Game {
    // Generating HashMap for available moves.
    let mut moves = HashMap::new();
    for i in 1..10 {
        moves.insert(i, i);
    }

    /*
     * Vector will work as a reference to the
     * HashMap with available moves which will
     * allow us to implement random access for
     * game with computer.
     */
    let mut references: Vec<usize> = vec![];
    for i in 1..10 {
        references.push(i);
    }

    Game {
        player: Player::new(PlayerKind::X),
        table: Table::new(),
        available_moves: moves,
        ref_available_moves: references,
        against_computer: false,
        over: false,
        running: true,
        steps: 1
    }
}

impl Game {
    pub fn new_against_human() -> Game {
        game_template()
    }

    pub fn new_against_computer() -> Game {
        Game {
            against_computer: true,
            ..game_template()
        }
    }

    pub fn change_player(&mut self) {
        self.player.change();
        self.steps += 1;
    }

    pub fn current_player(&self) -> String {
        self.player.print()
    }

    fn remove_from_available_moves(&mut self, _move: usize) -> bool {
        if self.mark_table(_move) {
            if let Some(_) = self.available_moves.get(&_move) {
                self.available_moves.remove(&_move);
                self.ref_available_moves.retain(|&x| x != _move);
                return true;
            }
        }
        false
    }

    pub fn players_turn(&self) -> bool {
        !self.against_computer || self.steps % 2 != 0
    }

    pub fn play_player(&mut self, _move: Option<usize>) -> bool {
        match _move {
            Some(n) => {
                if self.remove_from_available_moves(n) {
                    self.change_player();
                    self.check_table();
                    return true;
                }
                return false;
            },
            None => return false
        }
        /*
        if self.remove_from_available_moves(_move) {
            self.change_player();
            self.check_table();
            return true;
        }
        false
        */
    }

    pub fn play_computer(&mut self) -> bool {
        if self.against_computer && self.steps % 2 == 0 {
            let mut rng = thread_rng();
            let _move: usize = rng.gen_range(1, self.ref_available_moves.len());
            if self.remove_from_available_moves(_move) {
                self.change_player();
                self.check_table();
                return true;
            }
        }
        false
    }

    pub fn print_table(&self) {
        self.table.print();
    }

    fn mark_table(&mut self, field: usize) -> bool {
        self.table.mark(&self.player, field)
    }

    pub fn check_table(&mut self) {
        if self.table.is_full() || self.table.ends_game()  {
            self.over = true;
        }
    }

    pub fn is_over(&self) -> bool {
        self.over
    }

    pub fn is_running(&self) -> bool {
        self.running
    }

    /*
     * As players are changed after every step
     * we just have to show opposite player
     * than the current one as a winner.
     */
    pub fn check_status(&self) -> GameState {
        if self.table.is_full() {
            return GameState::Tie;
        }

        if self.against_computer {
            match self.player.kind {
                PlayerKind::X => return GameState::ComputerWon,
                PlayerKind::O => return GameState::HumanWon
            };
        } else {
            match self.player.kind {
                PlayerKind::X => return GameState::OWon,
                PlayerKind::O => return GameState::XWon
            };
        }
    }

    pub fn quit(&mut self) {
        self.running = false;
    }
}<commit_msg>Minor changes<commit_after>extern crate rand;
use game::rand::prelude::*;
use std::collections::HashMap;

use table::Table;
use player::Player;
use player::PlayerKind;

pub enum GameState {
    XWon,
    OWon,
    HumanWon,
    ComputerWon,
    Tie
}

pub struct Game {
    player: Player,
    table: Table,
    available_moves: HashMap<usize, usize>,
    ref_available_moves: Vec<usize>,
    against_computer: bool,
    over: bool,
    running: bool,
    steps: u32
}

fn game_template() -> Game {
    // Generating HashMap for available moves.
    let mut moves = HashMap::new();
    for i in 1..10 {
        moves.insert(i, i);
    }

    /*
     * Vector will work as a reference to the
     * HashMap with available moves which will
     * allow us to implement random access for
     * game with computer.
     */
    let mut references: Vec<usize> = vec![];
    for i in 1..10 {
        references.push(i);
    }

    Game {
        player: Player::new(PlayerKind::X),
        table: Table::new(),
        available_moves: moves,
        ref_available_moves: references,
        against_computer: false,
        over: false,
        running: true,
        steps: 1
    }
}

impl Game {
    pub fn new_against_human() -> Game {
        game_template()
    }

    pub fn new_against_computer() -> Game {
        Game {
            against_computer: true,
            ..game_template()
        }
    }

    pub fn change_player(&mut self) {
        self.player.change();
        self.steps += 1;
    }

    pub fn current_player(&self) -> String {
        self.player.print()
    }

    fn remove_from_available_moves(&mut self, _move: usize) -> bool {
        if self.mark_table(_move) {
            if let Some(_) = self.available_moves.get(&_move) {
                self.available_moves.remove(&_move);
                self.ref_available_moves.retain(|&x| x != _move);
                return true;
            }
        }
        false
    }

    pub fn players_turn(&self) -> bool {
        !self.against_computer || self.steps % 2 != 0
    }

    pub fn play_player(&mut self, _move: Option<usize>) -> bool {
        match _move {
            Some(n) => {
                if self.remove_from_available_moves(n) {
                    self.change_player();
                    self.check_table();
                    return true;
                }
                return false;
            },
            None => return false
        }
    }

    pub fn play_computer(&mut self) -> bool {
        if self.against_computer && self.steps % 2 == 0 {
            let mut rng = thread_rng();
            let _move: usize = rng.gen_range(1, self.ref_available_moves.len());
            if self.remove_from_available_moves(_move) {
                self.change_player();
                self.check_table();
                return true;
            }
        }
        false
    }

    pub fn print_table(&self) {
        self.table.print();
    }

    fn mark_table(&mut self, field: usize) -> bool {
        self.table.mark(&self.player, field)
    }

    pub fn check_table(&mut self) {
        if self.table.is_full() || self.table.ends_game()  {
            self.over = true;
        }
    }

    pub fn is_over(&self) -> bool {
        self.over
    }

    pub fn is_running(&self) -> bool {
        self.running
    }

    /*
     * As players are changed after every step
     * we just have to show opposite player
     * than the current one as a winner.
     */
    pub fn check_status(&self) -> GameState {
        if self.table.is_full() {
            return GameState::Tie;
        }

        if self.against_computer {
            match self.player.kind {
                PlayerKind::X => return GameState::ComputerWon,
                PlayerKind::O => return GameState::HumanWon
            };
        } else {
            match self.player.kind {
                PlayerKind::X => return GameState::OWon,
                PlayerKind::O => return GameState::XWon
            };
        }
    }

    pub fn quit(&mut self) {
        self.running = false;
    }
}<|endoftext|>