<commit_before><commit_msg>cleanup and add documentation<commit_after><|endoftext|>


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

use std::io;
use std::collections::BTreeSet;
use std::collections::HashMap;
use std::fs::File;
use std::io::ErrorKind;
use std::io::{Seek, Write, SeekFrom};
use std::fs::{OpenOptions, read_dir};
use std::os::unix::prelude::AsRawFd;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::thread;
use std::time::Duration;

use devicemapper::Device;
use devicemapper::types::{Bytes, Sectors};
use devicemapper::consts::SECTOR_SIZE;
use time::Timespec;
use uuid::Uuid;

use consts::IEC;
use engine::{DevUuid, EngineResult, EngineError, ErrorEnum, PoolUuid};
use super::metadata::{StaticHeader, BDA, validate_mda_size};
use super::engine::DevOwnership;
pub use super::BlockDevSave;

const MIN_DEV_SIZE: Bytes = Bytes(IEC::Gi as u64);

ioctl!(read blkgetsize64 with 0x12, 114; u64);

pub fn blkdev_size(file: &File) -> EngineResult<Bytes> {
    let mut val: u64 = 0;

    match unsafe { blkgetsize64(file.as_raw_fd(), &mut val) } {
        Err(x) => Err(EngineError::Nix(x)),
        Ok(_) => Ok(Bytes(val)),
    }
}

/// Resolve a list of Paths of some sort to a set of unique Devices.
/// Return an IOError if there was a problem resolving any particular device.
// FIXME: BTreeSet -> HashSet once Device is hashable
pub fn resolve_devices(paths: &[&Path]) -> io::Result<BTreeSet<Device>> {
    let mut devices = BTreeSet::new();
    for path in paths {
        let dev = try!(Device::from_str(&path.to_string_lossy()));
        devices.insert(dev);
    }
    Ok(devices)
}

/// Find all Stratis Blockdevs.
///
/// Returns a map of pool uuids to maps of blockdev uuids to blockdevs.
pub fn find_all() -> EngineResult<HashMap<PoolUuid, HashMap<DevUuid, BlockDev>>> {

    /// If a Path refers to a valid Stratis blockdev, return a BlockDev
    /// struct. Otherwise, return None. Return an error if there was
    /// a problem inspecting the device.
    fn setup(devnode: &Path) -> EngineResult<Option<BlockDev>> {
        let dev = try!(Device::from_str(&devnode.to_string_lossy()));

        let mut f = try!(OpenOptions::new()
            .read(true)
            .open(devnode));

        let bda = try!(BDA::load(&mut f));

        Ok(Some(BlockDev {
            dev: dev,
            devnode: devnode.to_owned(),
            bda: bda,
        }))
    }

    let mut pool_map = HashMap::new();
    for dir_e in try!(read_dir("/dev")) {
        let devnode = match dir_e {
            Ok(d) => d.path(),
            Err(_) => continue,
        };

        match setup(&devnode) {
            Ok(Some(blockdev)) => {
                pool_map.entry(blockdev.pool_uuid().clone())
                    .or_insert_with(HashMap::new)
                    .insert(blockdev.uuid().clone(), blockdev);
            }
            _ => continue,
        };
    }

    Ok(pool_map)
}

/// Zero sectors at the given offset
pub fn wipe_sectors(path: &Path, offset: Sectors, sector_count: Sectors) -> EngineResult<()> {
    let mut f = try!(OpenOptions::new()
        .write(true)
        .open(path));

    let zeroed = [0u8; SECTOR_SIZE];

    // set the start point to the offset
    try!(f.seek(SeekFrom::Start(*offset)));
    for _ in 0..*sector_count {
        try!(f.write_all(&zeroed));
    }
    try!(f.flush());
    Ok(())
}

/// Initialize multiple blockdevs at once. This allows all of them
/// to be checked for usability before writing to any of them.
// FIXME: BTreeSet -> HashSet once Device is hashable
pub fn initialize(pool_uuid: &PoolUuid,
                  devices: BTreeSet<Device>,
                  mda_size: Sectors,
                  force: bool)
                  -> EngineResult<Vec<BlockDev>> {
    /// Gets device information, returns an error if problem with obtaining
    /// that information.
    /// Returns a tuple with the blockdev's path, its size in bytes,
    /// its ownership as determined by calling determine_ownership(),
    /// and an open File handle, all of which are needed later.
    fn dev_info(dev: &Device) -> EngineResult<(PathBuf, Bytes, DevOwnership, File)> {
        let devnode = try!(dev.path().ok_or_else(|| {
            io::Error::new(ErrorKind::InvalidInput,
                           format!("could not get device node from dev {}", dev.dstr()))
        }));
        let mut f = try!(OpenOptions::new()
            .read(true)
            .write(true)
            .open(&devnode)
            .map_err(|_| {
                io::Error::new(ErrorKind::PermissionDenied,
                               format!("Could not open {}", devnode.display()))
            }));

        let dev_size = try!(blkdev_size(&f));

        let ownership = match StaticHeader::determine_ownership(&mut f) {
            Ok(ownership) => ownership,
            Err(err) => {
                let error_message = format!("{} for device {}", err, devnode.display());
                return Err(EngineError::Engine(ErrorEnum::Invalid, error_message));
            }
        };

        Ok((devnode, dev_size, ownership, f))
    }

    /// Filter devices for admission to pool based on dev_infos.
    /// If there is an error finding out the info, return that error.
    /// Also, return an error if a device is not appropriate for this pool.
    fn filter_devs<I>(dev_infos: I,
                      pool_uuid: &PoolUuid,
                      force: bool)
                      -> EngineResult<Vec<(Device, (PathBuf, Bytes, File))>>
        where I: Iterator<Item = (Device, EngineResult<(PathBuf, Bytes, DevOwnership, File)>)>
    {
        let mut add_devs = Vec::new();
        for (dev, dev_result) in dev_infos {
            let (devnode, dev_size, ownership, f) = try!(dev_result);
            if dev_size < MIN_DEV_SIZE {
                let error_message = format!("{} too small, minimum {} bytes",
                                            devnode.display(),
                                            MIN_DEV_SIZE);
                return Err(EngineError::Engine(ErrorEnum::Invalid, error_message));
            };
            match ownership {
                DevOwnership::Unowned => add_devs.push((dev, (devnode, dev_size, f))),
                DevOwnership::Theirs => {
                    if !force {
                        let error_str = format!("First 8K of {} not zeroed", devnode.display());
                        return Err(EngineError::Engine(ErrorEnum::Invalid, error_str));
                    } else {
                        add_devs.push((dev, (devnode, dev_size, f)))
                    }
                }
                DevOwnership::Ours(uuid) => {
                    if *pool_uuid != uuid {
                        let error_str = format!("Device {} already belongs to Stratis pool {}",
                                                devnode.display(),
                                                uuid);
                        return Err(EngineError::Engine(ErrorEnum::Invalid, error_str));
                    }
                }
            }
        }
        Ok(add_devs)
    }

    try!(validate_mda_size(mda_size));

    let dev_infos = devices.into_iter().map(|d: Device| (d, dev_info(&d)));

    let add_devs = try!(filter_devs(dev_infos, pool_uuid, force));

    // TODO: Fix this code.  We should deal with any number of blockdevs
    //
    if add_devs.len() < 2 {
        return Err(EngineError::Engine(ErrorEnum::Error,
                                       "Need at least 2 blockdevs to create a pool".into()));
    }

    let mut bds = Vec::new();
    for (dev, (devnode, dev_size, mut f)) in add_devs {

        let bda = try!(BDA::initialize(&mut f,
                                       pool_uuid,
                                       &Uuid::new_v4(),
                                       mda_size,
                                       dev_size.sectors()));

        let bd = BlockDev {
            dev: dev,
            devnode: devnode.clone(),
            bda: bda,
        };
        bds.push(bd);
    }
    Ok(bds)
}

#[derive(Debug)]
pub struct BlockDev {
    dev: Device,
    pub devnode: PathBuf,
    bda: BDA,
}

impl BlockDev {
    pub fn to_save(&self) -> BlockDevSave {
        BlockDevSave {
            devnode: self.devnode.clone(),
            total_size: self.size(),
        }
    }

    pub fn wipe_metadata(&self) -> EngineResult<()> {
        let mut f = try!(OpenOptions::new().write(true).open(&self.devnode));
        BDA::wipe(&mut f)
    }

    /// Get the "x:y" device string for this blockdev
    pub fn dstr(&self) -> String {
        self.dev.dstr()
    }

    pub fn save_state(&mut self, time: &Timespec, metadata: &[u8]) -> EngineResult<()> {
        let mut f = try!(OpenOptions::new().write(true).open(&self.devnode));
        self.bda.save_state(time, metadata, &mut f)
    }

    pub fn load_state(&self) -> EngineResult<Option<Vec<u8>>> {
        let mut f = try!(OpenOptions::new().read(true).open(&self.devnode));
        self.bda.load_state(&mut f)
    }

    /// List the available-for-upper-layer-use range in this blockdev.
    pub fn avail_range(&self) -> (Sectors, Sectors) {
        let start = self.bda.size();
        let size = self.size();
        // Blockdev size is at least MIN_DEV_SIZE, so this can fail only if
        // size of metadata area exceeds 1 GiB. Initial metadata area size
        // is 4 MiB.
        assert!(start <= size);
        (start, size - start)
    }

    /// The /dev/mapper/<name> device is not immediately available for use.
    /// TODO: Implement wait for event or poll.
    pub fn wait_for_dm() {
        thread::sleep(Duration::from_millis(500))
    }

    /// The device's UUID.
    pub fn uuid(&self) -> &DevUuid {
        self.bda.dev_uuid()
    }

    /// The device's pool's UUID.
    pub fn pool_uuid(&self) -> &PoolUuid {
        self.bda.pool_uuid()
    }

    /// The device's size.
    pub fn size(&self) -> Sectors {
        self.bda.dev_size()
    }

    /// Last time metadata was written to this device.
    pub fn last_update_time(&self) -> &Option<Timespec> {
        self.bda.last_update_time()
    }
}
<commit_msg>Change BTreeSet to HashSet<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::io;
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::ErrorKind;
use std::io::{Seek, Write, SeekFrom};
use std::fs::{OpenOptions, read_dir};
use std::os::unix::prelude::AsRawFd;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::thread;
use std::time::Duration;

use devicemapper::Device;
use devicemapper::types::{Bytes, Sectors};
use devicemapper::consts::SECTOR_SIZE;
use time::Timespec;
use uuid::Uuid;

use consts::IEC;
use engine::{DevUuid, EngineResult, EngineError, ErrorEnum, PoolUuid};
use super::metadata::{StaticHeader, BDA, validate_mda_size};
use super::engine::DevOwnership;
pub use super::BlockDevSave;

const MIN_DEV_SIZE: Bytes = Bytes(IEC::Gi as u64);

ioctl!(read blkgetsize64 with 0x12, 114; u64);

pub fn blkdev_size(file: &File) -> EngineResult<Bytes> {
    let mut val: u64 = 0;

    match unsafe { blkgetsize64(file.as_raw_fd(), &mut val) } {
        Err(x) => Err(EngineError::Nix(x)),
        Ok(_) => Ok(Bytes(val)),
    }
}

/// Resolve a list of Paths of some sort to a set of unique Devices.
/// Return an IOError if there was a problem resolving any particular device.
pub fn resolve_devices(paths: &[&Path]) -> io::Result<HashSet<Device>> {
    let mut devices = HashSet::new();
    for path in paths {
        let dev = try!(Device::from_str(&path.to_string_lossy()));
        devices.insert(dev);
    }
    Ok(devices)
}

/// Find all Stratis Blockdevs.
///
/// Returns a map of pool uuids to maps of blockdev uuids to blockdevs.
pub fn find_all() -> EngineResult<HashMap<PoolUuid, HashMap<DevUuid, BlockDev>>> {

    /// If a Path refers to a valid Stratis blockdev, return a BlockDev
    /// struct. Otherwise, return None. Return an error if there was
    /// a problem inspecting the device.
    fn setup(devnode: &Path) -> EngineResult<Option<BlockDev>> {
        let dev = try!(Device::from_str(&devnode.to_string_lossy()));

        let mut f = try!(OpenOptions::new()
            .read(true)
            .open(devnode));

        let bda = try!(BDA::load(&mut f));

        Ok(Some(BlockDev {
            dev: dev,
            devnode: devnode.to_owned(),
            bda: bda,
        }))
    }

    let mut pool_map = HashMap::new();
    for dir_e in try!(read_dir("/dev")) {
        let devnode = match dir_e {
            Ok(d) => d.path(),
            Err(_) => continue,
        };

        match setup(&devnode) {
            Ok(Some(blockdev)) => {
                pool_map.entry(blockdev.pool_uuid().clone())
                    .or_insert_with(HashMap::new)
                    .insert(blockdev.uuid().clone(), blockdev);
            }
            _ => continue,
        };
    }

    Ok(pool_map)
}

/// Zero sectors at the given offset
pub fn wipe_sectors(path: &Path, offset: Sectors, sector_count: Sectors) -> EngineResult<()> {
    let mut f = try!(OpenOptions::new()
        .write(true)
        .open(path));

    let zeroed = [0u8; SECTOR_SIZE];

    // set the start point to the offset
    try!(f.seek(SeekFrom::Start(*offset)));
    for _ in 0..*sector_count {
        try!(f.write_all(&zeroed));
    }
    try!(f.flush());
    Ok(())
}

/// Initialize multiple blockdevs at once. This allows all of them
/// to be checked for usability before writing to any of them.
pub fn initialize(pool_uuid: &PoolUuid,
                  devices: HashSet<Device>,
                  mda_size: Sectors,
                  force: bool)
                  -> EngineResult<Vec<BlockDev>> {
    /// Gets device information, returns an error if problem with obtaining
    /// that information.
    /// Returns a tuple with the blockdev's path, its size in bytes,
    /// its ownership as determined by calling determine_ownership(),
    /// and an open File handle, all of which are needed later.
    fn dev_info(dev: &Device) -> EngineResult<(PathBuf, Bytes, DevOwnership, File)> {
        let devnode = try!(dev.path().ok_or_else(|| {
            io::Error::new(ErrorKind::InvalidInput,
                           format!("could not get device node from dev {}", dev.dstr()))
        }));
        let mut f = try!(OpenOptions::new()
            .read(true)
            .write(true)
            .open(&devnode)
            .map_err(|_| {
                io::Error::new(ErrorKind::PermissionDenied,
                               format!("Could not open {}", devnode.display()))
            }));

        let dev_size = try!(blkdev_size(&f));

        let ownership = match StaticHeader::determine_ownership(&mut f) {
            Ok(ownership) => ownership,
            Err(err) => {
                let error_message = format!("{} for device {}", err, devnode.display());
                return Err(EngineError::Engine(ErrorEnum::Invalid, error_message));
            }
        };

        Ok((devnode, dev_size, ownership, f))
    }

    /// Filter devices for admission to pool based on dev_infos.
    /// If there is an error finding out the info, return that error.
    /// Also, return an error if a device is not appropriate for this pool.
    fn filter_devs<I>(dev_infos: I,
                      pool_uuid: &PoolUuid,
                      force: bool)
                      -> EngineResult<Vec<(Device, (PathBuf, Bytes, File))>>
        where I: Iterator<Item = (Device, EngineResult<(PathBuf, Bytes, DevOwnership, File)>)>
    {
        let mut add_devs = Vec::new();
        for (dev, dev_result) in dev_infos {
            let (devnode, dev_size, ownership, f) = try!(dev_result);
            if dev_size < MIN_DEV_SIZE {
                let error_message = format!("{} too small, minimum {} bytes",
                                            devnode.display(),
                                            MIN_DEV_SIZE);
                return Err(EngineError::Engine(ErrorEnum::Invalid, error_message));
            };
            match ownership {
                DevOwnership::Unowned => add_devs.push((dev, (devnode, dev_size, f))),
                DevOwnership::Theirs => {
                    if !force {
                        let error_str = format!("First 8K of {} not zeroed", devnode.display());
                        return Err(EngineError::Engine(ErrorEnum::Invalid, error_str));
                    } else {
                        add_devs.push((dev, (devnode, dev_size, f)))
                    }
                }
                DevOwnership::Ours(uuid) => {
                    if *pool_uuid != uuid {
                        let error_str = format!("Device {} already belongs to Stratis pool {}",
                                                devnode.display(),
                                                uuid);
                        return Err(EngineError::Engine(ErrorEnum::Invalid, error_str));
                    }
                }
            }
        }
        Ok(add_devs)
    }

    try!(validate_mda_size(mda_size));

    let dev_infos = devices.into_iter().map(|d: Device| (d, dev_info(&d)));

    let add_devs = try!(filter_devs(dev_infos, pool_uuid, force));

    // TODO: Fix this code.  We should deal with any number of blockdevs
    //
    if add_devs.len() < 2 {
        return Err(EngineError::Engine(ErrorEnum::Error,
                                       "Need at least 2 blockdevs to create a pool".into()));
    }

    let mut bds = Vec::new();
    for (dev, (devnode, dev_size, mut f)) in add_devs {

        let bda = try!(BDA::initialize(&mut f,
                                       pool_uuid,
                                       &Uuid::new_v4(),
                                       mda_size,
                                       dev_size.sectors()));

        let bd = BlockDev {
            dev: dev,
            devnode: devnode.clone(),
            bda: bda,
        };
        bds.push(bd);
    }
    Ok(bds)
}

#[derive(Debug)]
pub struct BlockDev {
    dev: Device,
    pub devnode: PathBuf,
    bda: BDA,
}

impl BlockDev {
    pub fn to_save(&self) -> BlockDevSave {
        BlockDevSave {
            devnode: self.devnode.clone(),
            total_size: self.size(),
        }
    }

    pub fn wipe_metadata(&self) -> EngineResult<()> {
        let mut f = try!(OpenOptions::new().write(true).open(&self.devnode));
        BDA::wipe(&mut f)
    }

    /// Get the "x:y" device string for this blockdev
    pub fn dstr(&self) -> String {
        self.dev.dstr()
    }

    pub fn save_state(&mut self, time: &Timespec, metadata: &[u8]) -> EngineResult<()> {
        let mut f = try!(OpenOptions::new().write(true).open(&self.devnode));
        self.bda.save_state(time, metadata, &mut f)
    }

    pub fn load_state(&self) -> EngineResult<Option<Vec<u8>>> {
        let mut f = try!(OpenOptions::new().read(true).open(&self.devnode));
        self.bda.load_state(&mut f)
    }

    /// List the available-for-upper-layer-use range in this blockdev.
    pub fn avail_range(&self) -> (Sectors, Sectors) {
        let start = self.bda.size();
        let size = self.size();
        // Blockdev size is at least MIN_DEV_SIZE, so this can fail only if
        // size of metadata area exceeds 1 GiB. Initial metadata area size
        // is 4 MiB.
        assert!(start <= size);
        (start, size - start)
    }

    /// The /dev/mapper/<name> device is not immediately available for use.
    /// TODO: Implement wait for event or poll.
    pub fn wait_for_dm() {
        thread::sleep(Duration::from_millis(500))
    }

    /// The device's UUID.
    pub fn uuid(&self) -> &DevUuid {
        self.bda.dev_uuid()
    }

    /// The device's pool's UUID.
    pub fn pool_uuid(&self) -> &PoolUuid {
        self.bda.pool_uuid()
    }

    /// The device's size.
    pub fn size(&self) -> Sectors {
        self.bda.dev_size()
    }

    /// Last time metadata was written to this device.
    pub fn last_update_time(&self) -> &Option<Timespec> {
        self.bda.last_update_time()
    }
}
<|endoftext|>


<commit_before>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) Nathan Zadoks <nathan@nathan7.eu>,
//               whitequark <whitequark@whitequark.org>
// See the LICENSE file included in this distribution.

//! To understand the code in this file, keep in mind these two facts:
//! * x86_64 SysV C ABI has a "red zone": 128 bytes under the top of the stack
//!   that is defined to be unmolested by signal handlers, interrupts, etc.
//!   Leaf functions can use the red zone without adjusting rsp or rbp.
//! * x86_64 SysV C ABI requires the stack to be aligned at function entry,
//!   so that (%rsp+8) is a multiple of 16. Aligned operands are a requirement
//!   of SIMD instructions, and making this the responsibility of the caller
//!   avoids having to maintain a frame pointer, which is necessary when
//!   a function has to realign the stack from an unknown state.
//! * x86_64 SysV C ABI passes the first argument in %rdi. We also use %rdi
//!   to pass a value while swapping context; this is an arbitrary choice
//!   (we clobber all registers and could use any of them) but this allows us
//!   to reuse the swap function to perform the initial call.

use stack::Stack;

#[derive(Debug)]
pub struct StackPointer(*mut usize);

impl StackPointer {
  unsafe fn new(stack: &Stack) -> StackPointer {
    StackPointer(stack.top() as *mut usize)
  }

  unsafe fn push(&mut self, val: usize) {
    self.0 = self.0.offset(-1);
    *self.0 = val
  }
}

pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
  let mut sp = StackPointer::new(stack);
  sp.push(0); // alignment
  sp.push(f as usize);
  sp
}

#[inline(always)]
pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer) -> usize {
  let ret: usize;
  asm!(
    r#"
      # Save frame pointer explicitly; LLVM doesn't spill it even if it is
      # marked as clobbered.
      pushq   %rbp
      # Push instruction pointer of the old context and switch to
      # the new context.
      call    1f
      # Restore frame pointer.
      popq    %rbp
      # Continue executing old context.
      jmp     2f

    1:
      # Remember stack pointer of the old context, in case %rdx==%rsi.
      movq    %rsp, %rbx
      # Load stack pointer of the new context.
      movq    (%rdx), %rsp
      # Save stack pointer of the old context.
      movq    %rbx, (%rsi)

      # Pop instruction pointer of the new context (placed onto stack by
      # the call above) and jump there; don't use `ret` to avoid return
      # address mispredictions (~8ns on Ivy Bridge).
      popq    %rbx
      jmpq    *%rbx
    2:
    "#
    : "={rdi}" (ret)
    : "{rdi}" (arg)
      "{rsi}" (old_sp)
      "{rdx}" (new_sp)
    : "rax",   "rbx",   "rcx",   "rdx",   "rsi",   "rdi", //"rbp",   "rsp",
      "r8",    "r9",    "r10",   "r11",   "r12",   "r13",   "r14",   "r15",
      "xmm0",  "xmm1",  "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",  "xmm7",
      "xmm8",  "xmm9",  "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
      "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23",
      "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31"
      "cc", "fpsr", "flags", "memory"
      // Ideally, we would set the LLVM "noredzone" attribute on this function
      // (and it would be propagated to the call site). Unfortunately, rustc
      // provides no such functionality. Fortunately, by a lucky coincidence,
      // the "alignstack" LLVM inline assembly option does exactly the same
      // thing on x86_64.
    : "volatile", "alignstack");
  ret
}
<commit_msg>Fix Windows x64 ABI<commit_after>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) Nathan Zadoks <nathan@nathan7.eu>,
//               whitequark <whitequark@whitequark.org>
// See the LICENSE file included in this distribution.

//! To understand the code in this file, keep in mind these two facts:
//! * x86_64 SysV C ABI has a "red zone": 128 bytes under the top of the stack
//!   that is defined to be unmolested by signal handlers, interrupts, etc.
//!   Leaf functions can use the red zone without adjusting rsp or rbp.
//! * x86_64 SysV C ABI requires the stack to be aligned at function entry,
//!   so that (%rsp+8) is a multiple of 16. Aligned operands are a requirement
//!   of SIMD instructions, and making this the responsibility of the caller
//!   avoids having to maintain a frame pointer, which is necessary when
//!   a function has to realign the stack from an unknown state.
//! * x86_64 SysV C ABI passes the first argument in %rdi. We also use %rdi
//!   to pass a value while swapping context; this is an arbitrary choice
//!   (we clobber all registers and could use any of them) but this allows us
//!   to reuse the swap function to perform the initial call.

use stack::Stack;

#[derive(Debug)]
pub struct StackPointer(*mut usize);

impl StackPointer {
  unsafe fn new(stack: &Stack) -> StackPointer {
    StackPointer(stack.top() as *mut usize)
  }

  unsafe fn push(&mut self, val: usize) {
    self.0 = self.0.offset(-1);
    *self.0 = val
  }
}

pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
  let mut sp = StackPointer::new(stack);
  sp.push(0); // alignment
  sp.push(f as usize);
  sp
}

#[inline(always)]
pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer) -> usize {
  macro_rules! swap_body {
    () => {
      r#"
        # Save frame pointer explicitly; LLVM doesn't spill it even if it is
        # marked as clobbered.
        pushq   %rbp
        # Push instruction pointer of the old context and switch to
        # the new context.
        call    1f
        # Restore frame pointer.
        popq    %rbp
        # Continue executing old context.
        jmp     2f

      1:
        # Remember stack pointer of the old context, in case %rdx==%rsi.
        movq    %rsp, %rbx
        # Load stack pointer of the new context.
        movq    (%rdx), %rsp
        # Save stack pointer of the old context.
        movq    %rbx, (%rsi)

        # Pop instruction pointer of the new context (placed onto stack by
        # the call above) and jump there; don't use `ret` to avoid return
        # address mispredictions (~8ns on Ivy Bridge).
        popq    %rbx
        jmpq    *%rbx
      2:
      "#
    }
  }

  #[cfg(not(windows))]
  #[inline(always)]
  unsafe fn swap_impl(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer) -> usize {
    let ret: usize;
    asm!(swap_body!()
      : "={rdi}" (ret)
      : "{rdi}" (arg)
        "{rsi}" (old_sp)
        "{rdx}" (new_sp)
      : "rax",   "rbx",   "rcx",   "rdx",   "rsi",   "rdi", //"rbp",   "rsp",
        "r8",    "r9",    "r10",   "r11",   "r12",   "r13",   "r14",   "r15",
        "xmm0",  "xmm1",  "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",  "xmm7",
        "xmm8",  "xmm9",  "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
        "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23",
        "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31"
        "cc", "fpsr", "flags", "memory"
        // Ideally, we would set the LLVM "noredzone" attribute on this function
        // (and it would be propagated to the call site). Unfortunately, rustc
        // provides no such functionality. Fortunately, by a lucky coincidence,
        // the "alignstack" LLVM inline assembly option does exactly the same
        // thing on x86_64.
      : "volatile", "alignstack");
    ret
  }

  #[cfg(windows)]
  #[inline(always)]
  unsafe fn swap_impl(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer) -> usize {
    let ret: usize;
    asm!(swap_body!()
      : "={rcx}" (ret)
      : "{rcx}" (arg)
        "{rsi}" (old_sp)
        "{rdx}" (new_sp)
      : "rax",   "rbx",   "rcx",   "rdx",   "rsi",   "rdi", //"rbp",   "rsp",
        "r8",    "r9",    "r10",   "r11",   "r12",   "r13",   "r14",   "r15",
        "xmm0",  "xmm1",  "xmm2",  "xmm3",  "xmm4",  "xmm5",  "xmm6",  "xmm7",
        "xmm8",  "xmm9",  "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
        "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23",
        "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31"
        "cc", "fpsr", "flags", "memory"
        // Ideally, we would set the LLVM "noredzone" attribute on this function
        // (and it would be propagated to the call site). Unfortunately, rustc
        // provides no such functionality. Fortunately, by a lucky coincidence,
        // the "alignstack" LLVM inline assembly option does exactly the same
        // thing on x86_64.
      : "volatile", "alignstack");
    ret
  }

  swap_impl(arg, old_sp, new_sp)
}
<|endoftext|>


<commit_before><commit_msg>forgot to add config reader...<commit_after>extern crate std;

use std::io::{BufReader, BufRead};
use state::ShellState;
use std::path::Path;

impl ShellState {
    pub fn read_config(&mut self) {
        let config_path = Path::new(self.variables.get("HOME").unwrap()).join(Path::new(".rshrc"));
        if let Ok(f) =  std::fs::File::open(config_path) {
            let reader = BufReader::new(f);
            for line in reader.lines().filter_map(|l| l.ok()).filter(|l| l.contains('=')) {
                let mut split = line.as_str().split('=');
                let key = split.next().unwrap();
                let value = split.next().unwrap_or("").to_owned();
                let real_value = value.replace("\\n", "\n");
                self.variables.insert(key, real_value.as_ref());
            }
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Add missing `build.rs` in benchmarks<commit_after>extern crate rustc_version;

use rustc_version::{version_meta, Channel};

fn main() {
    if version_meta().unwrap().channel == Channel::Nightly {
        println!( "cargo:rustc-cfg=nightly" );
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example that intentionally generates unused functions' outputs<commit_after>
extern crate uom;

use uom::Conversion;
use uom::fmt::DisplayStyle::Abbreviation;
use uom::si ::Unit;
use uom::si ::length      ::{meter , millimeter , micrometer };
use uom::si ::time        ::{second, millisecond, microsecond};
use uom::si ::velocity    ::{self, meter_per_second};
use uom::si ::acceleration::meter_per_second_squared;
use uom::si ::area        ::square_meter;
use uom::si ::frequency   ::hertz;

// use uom::si ::mass        ::gram;
// use uom::si ::momentum    ::gram_meter_per_second;
use uom::si ::angle                    ::radian;
use uom::si ::ratio                    ::ratio;
// use uom::si ::thermodynamic_temperature::degree_celsius;
// use uom::si ::temperature_interval     ::degree_fahrenheit;

use uom::si ::f64::{ Length
                   , Time
                   , Area
                   , Velocity
                   // , Mass
                   , Angle
                   // , Ratio
                   // , ThermodynamicTemperature
                   // , TemperatureInterval
                   };

use typenum::{P2, P3};

macro_rules! check_n_print {
    ($id:literal, $value:expr) => {
        $value;
        println!("{} => {:?}", $id, $value);
    };
}

macro_rules! check_n_print_unit {
    ($id:literal, $value:expr, $unit:expr) => {
        $value;
        println!("{} => {:>10.4?} => {:>10.4?}", $id, $value, $value.into_format_args($unit, Abbreviation));
    };
}

fn sep(tag: &str) {
    let line = "=".repeat(25);
    println!("");
    println!("{} {} {}", line, tag, line);
    println!("");
}

fn main() {
    sep("new values");

    check_n_print_unit!("new length", Length::new::<meter> (1.0), millimeter );
    check_n_print_unit!("new time  ", Time  ::new::<second>(2.0), microsecond);

    sep("Accessing/Transforming values");

    let l1  = Length::new::<micrometer  >(3.0);
    let l2  = Area  ::new::<square_meter>(4.0);
    let t1  = Time  ::new::<millisecond >(5.0);
    let t2  = t1.powi(P2::new());
    let t3  = t1.powi(P3::new());
    let v1  = l1 / t1;
    // let m1  = Mass  ::new::<gram       >(5.0);
    let fmt = Velocity::format_args(meter_per_second, Abbreviation);

    check_n_print!("get       ", l1.get::<millimeter>());
    check_n_print!("conversion", l1.get::<millimeter>().conversion());

    sep("Formatting");

    check_n_print!("with            ", fmt.with(v1));
    check_n_print!("into_format_args", v1.into_format_args(meter_per_second, Abbreviation));

    sep("Values checks");

    // Arithmetic operations already throw a warning
    // check_n_print_unit!("+", t1 + t1, microsecond);
    // check_n_print_unit!("+", t1 - t1, microsecond);
    // check_n_print_unit!("+", m1 * l1 / t1, gram_meter_per_second);
    // check_n_print_unit!("+", l1 / t2, meter_per_second_squared);

    check_n_print!("is_nan          ", t1.is_nan          ());
    check_n_print!("is_finite       ", l1.is_finite       ());
    check_n_print!("is_infinite     ", t1.is_infinite     ());
    check_n_print!("is_normal       ", l1.is_normal       ());
    check_n_print!("classify        ", t1.classify        ());
    check_n_print!("is_sign_negative", l1.is_sign_negative());
    check_n_print!("is_sign_positive", t1.is_sign_positive());

    sep("Operations on any value");

    check_n_print_unit!("signum ", l2.signum              (         ), square_meter);
    check_n_print_unit!("hypot  ", t1.hypot               (t1 + t1  ), microsecond );
    check_n_print_unit!("powi   ", l1.powi                (P2::new()), square_meter);
    check_n_print_unit!("mul_add", l1.mul_add             (l1, l2   ), square_meter);
    check_n_print_unit!("recip  ", t1.recip               (         ), hertz       );
    check_n_print_unit!("max    ", l1.max                 (l1       ), millimeter  );
    check_n_print_unit!("min    ", t1.min                 (t1       ), microsecond );
    check_n_print_unit!("floor  ", t1.floor::<microsecond>(         ), microsecond );
    check_n_print_unit!("ceil   ", l1.ceil ::<millimeter >(         ), millimeter  );
    check_n_print_unit!("round  ", t1.round::<microsecond>(         ), microsecond );
    check_n_print_unit!("trunc  ", l1.trunc::<millimeter >(         ), millimeter  );
    check_n_print_unit!("fract  ", t1.fract::<microsecond>(         ), microsecond );
    check_n_print_unit!("abs    ", l1.abs                 (         ), millimeter  );
    check_n_print_unit!("sqrt   ", t2.sqrt                (         ), microsecond );
    check_n_print_unit!("cbrt   ", t3.cbrt                (         ), microsecond );

    sep("String representations");

    check_n_print!("description ", velocity                ::description ());
    check_n_print!("abbreviation", meter_per_second_squared::abbreviation());
    check_n_print!("singular    ", second                  ::singular    ());
    check_n_print!("plural      ", meter                   ::plural      ());

    sep("Angle-specific functions");

    let a = Angle::new::<radian>(6.0);

    check_n_print_unit!("sin   ", a.sin    ( ), ratio );
    check_n_print_unit!("sinh  ", a.sinh   ( ), ratio );
    check_n_print_unit!("cos   ", a.cos    ( ), ratio );
    check_n_print_unit!("cosh  ", a.cosh   ( ), ratio );
    check_n_print_unit!("tan   ", a.tan    ( ), ratio );
    check_n_print_unit!("tanh  ", a.tanh   ( ), ratio );
    check_n_print_unit!("atan2 ", a.atan2  (a), radian);
    check_n_print!     ("sincos", a.sin_cos( ));

    sep("Ratio-specific functions");

    // Ratio has the must_use attribute already
    // let r = Ratio::new::<ratio>(0.5);
    //
    // check_n_print_unit!("sin   ", r.asin  (  ), radian );
    // check_n_print_unit!("sinh  ", r.asinh (  ), radian );
    // check_n_print_unit!("cos   ", r.acos  (  ), radian );
    // check_n_print_unit!("cosh  ", r.acosh (  ), radian );
    // check_n_print_unit!("tan   ", r.atan  (  ), radian );
    // check_n_print_unit!("tanh  ", r.atanh (  ), radian );
    // check_n_print_unit!("exp   ", r.exp   (  ), ratio  );
    // check_n_print_unit!("exp2  ", r.exp2  (  ), ratio  );
    // check_n_print_unit!("ln    ", r.ln    (  ), ratio  );
    // check_n_print_unit!("log   ", r.log   (2.), ratio  );
    // check_n_print_unit!("log2  ", r.log2  (  ), ratio  );
    // check_n_print_unit!("log10 ", r.log10 (  ), ratio  );
    // check_n_print_unit!("exp_m1", r.exp_m1(  ), ratio  );
    // check_n_print_unit!("ln_1p ", r.ln_1p (  ), ratio  );

}
<|endoftext|>


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

// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no
fn main() -> i32 {
    0
}
<commit_msg>Use NOTE instead of error-pattern directive<commit_after>// Copyright 2017 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.

fn main() -> i32 {
//~^ ERROR `i32: std::process::Termination` is not satisfied
//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32`
    0
}
<|endoftext|>


<commit_before><commit_msg>Fix mouse button bindings and saving.<commit_after><|endoftext|>


<commit_before>///! Basic CSS block layout.

use style::{StyledNode, Inline, Block, DisplayNone};
use css::{Keyword, Length, Px};
use std::default::Default;
use std::iter::AdditiveIterator; // for `sum`

// CSS box model. All sizes are in px.

#[deriving(Default, Show)]
pub struct Rect {
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
}

#[deriving(Default, Show)]
pub struct Dimensions {
    /// Position of the content area relative to the document origin:
    pub content: Rect,
    // Surrounding edges:
    pub padding: EdgeSizes,
    pub border: EdgeSizes,
    pub margin: EdgeSizes,
}

#[deriving(Default, Show)]
pub struct EdgeSizes {
    pub left: f32,
    pub right: f32,
    pub top: f32,
    pub bottom: f32,
}

/// A node in the layout tree.
pub struct LayoutBox<'a> {
    pub dimensions: Dimensions,
    pub box_type: BoxType<'a>,
    pub children: Vec<LayoutBox<'a>>,
}

pub enum BoxType<'a> {
    BlockNode(&'a StyledNode<'a>),
    InlineNode(&'a StyledNode<'a>),
    AnonymousBlock,
}

impl<'a> LayoutBox<'a> {
    fn new(box_type: BoxType) -> LayoutBox {
        LayoutBox {
            box_type: box_type,
            dimensions: Default::default(),
            children: Vec::new(),
        }
    }

    fn get_style_node(&self) -> &'a StyledNode<'a> {
        match self.box_type {
            BlockNode(node) => node,
            InlineNode(node) => node,
            AnonymousBlock => panic!("Anonymous block box has no style node")
        }
    }
}

/// Transform a style tree into a layout tree.
pub fn layout_tree<'a>(node: &'a StyledNode<'a>, mut containing_block: Dimensions) -> LayoutBox<'a> {
    // The layout algorithm expects the container height to start at 0.
    // TODO: Save the initial containing block height, for calculating percent heights.
    containing_block.content.height = 0.0;

    let mut root_box = build_layout_tree(node);
    root_box.layout(containing_block);
    return root_box;
}

/// Build the tree of LayoutBoxes, but don't perform any layout calculations yet.
fn build_layout_tree<'a>(style_node: &'a StyledNode<'a>) -> LayoutBox<'a> {
    // Create the root box.
    let mut root = LayoutBox::new(match style_node.display() {
        Block => BlockNode(style_node),
        Inline => InlineNode(style_node),
        DisplayNone => panic!("Root node has display: none.")
    });

    // Create the descendant boxes.
    for child in style_node.children.iter() {
        match child.display() {
            Block => root.children.push(build_layout_tree(child)),
            Inline => root.get_inline_container().children.push(build_layout_tree(child)),
            DisplayNone => {} // Don't lay out nodes with `display: none;`
        }
    }
    return root;
}

impl<'a> LayoutBox<'a> {
    /// Lay out a box and its descendants.
    fn layout(&mut self, containing_block: Dimensions) {
        match self.box_type {
            BlockNode(_) => self.layout_block(containing_block),
            InlineNode(_) => {} // TODO
            AnonymousBlock => {} // TODO
        }
    }

    /// Lay out a block-level element and its descendants.
    fn layout_block(&mut self, containing_block: Dimensions) {
        // Child width can depend on parent width, so we need to calculate this box's width before
        // laying out its children.
        self.calculate_block_width(containing_block);

        // Determine where the box is located within its container.
        self.calculate_block_position(containing_block);

        // Recursively lay out the children of this box.
        self.layout_block_children();

        // Parent height can depend on child height, so `calculate_height` must be called after the
        // children are laid out.
        self.calculate_block_height();
    }

    /// Calculate the width of a block-level non-replaced element in normal flow.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#blockwidth
    ///
    /// Sets the horizontal margin/padding/border dimensions, and the `width`.
    fn calculate_block_width(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();

        // `width` has initial value `auto`.
        let auto = Keyword("auto".to_string());
        let mut width = style.value("width").unwrap_or(auto.clone());

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        let mut margin_left = style.lookup("margin-left", "margin", &zero);
        let mut margin_right = style.lookup("margin-right", "margin", &zero);

        let border_left = style.lookup("border-left-width", "border-width", &zero);
        let border_right = style.lookup("border-right-width", "border-width", &zero);

        let padding_left = style.lookup("padding-left", "padding", &zero);
        let padding_right = style.lookup("padding-right", "padding", &zero);

        let total = [&margin_left, &margin_right, &border_left, &border_right,
                     &padding_left, &padding_right, &width].iter().map(|v| v.to_px()).sum();

        // If width is not auto and the total is wider than the container, treat auto margins as 0.
        if width != auto && total > containing_block.content.width {
            if margin_left == auto {
                margin_left = Length(0.0, Px);
            }
            if margin_right == auto {
                margin_right = Length(0.0, Px);
            }
        }

        // Adjust used values so that the above sum equals `containing_block.width`.
        // Each arm of the `match` should increase the total width by exactly `underflow`,
        // and afterward all values should be absolute lengths in px.
        let underflow = containing_block.content.width - total;

        match (width == auto, margin_left == auto, margin_right == auto) {
            // If the values are overconstrained, calculate margin_right.
            (false, false, false) => {
                margin_right = Length(margin_right.to_px() + underflow, Px);
            }

            // If exactly one size is auto, its used value follows from the equality.
            (false, false, true) => { margin_right = Length(underflow, Px); }
            (false, true, false) => { margin_left  = Length(underflow, Px); }

            // If width is set to auto, any other auto values become 0.
            (true, _, _) => {
                if margin_left == auto { margin_left = Length(0.0, Px); }
                if margin_right == auto { margin_right = Length(0.0, Px); }

                if underflow >= 0.0 {
                    // Expand width to fill the underflow.
                    width = Length(underflow, Px);
                } else {
                    // Width can't be negative. Adjust the right margin instead.
                    width = Length(0.0, Px);
                    margin_right = Length(margin_right.to_px() + underflow, Px);
                }
            }

            // If margin-left and margin-right are both auto, their used values are equal.
            (false, true, true) => {
                margin_left = Length(underflow / 2.0, Px);
                margin_right = Length(underflow / 2.0, Px);
            }
        }

        let d = &mut self.dimensions;
        d.content.width = width.to_px();

        d.padding.left = padding_left.to_px();
        d.padding.right = padding_right.to_px();

        d.border.left = border_left.to_px();
        d.border.right = border_right.to_px();

        d.margin.left = margin_left.to_px();
        d.margin.right = margin_right.to_px();
    }

    /// Finish calculating the block's edge sizes, and position it within its containing block.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#normal-block
    ///
    /// Sets the vertical margin/padding/border dimensions, and the `x`, `y` values.
    fn calculate_block_position(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();
        let d = &mut self.dimensions;

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        // If margin-top or margin-bottom is `auto`, the used value is zero.
        d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
        d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

        d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
        d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

        d.padding.top = style.lookup("padding-top", "padding", &zero).to_px();
        d.padding.bottom = style.lookup("padding-bottom", "padding", &zero).to_px();

        // Position the box below all the previous boxes in the container.
        d.content.x = containing_block.content.x +
                      d.margin.left + d.border.left + d.padding.left;
        d.content.y = containing_block.content.y + containing_block.content.height +
                      d.margin.top + d.border.top + d.padding.top;
    }

    /// Lay out the block's children within its content area.
    ///
    /// Sets `self.dimensions.height` to the total content height.
    fn layout_block_children(&mut self) {
        let d = &mut self.dimensions;
        for child in self.children.iter_mut() {
            child.layout(*d);
            // Increment the height so each child is laid out below the previous one.
            d.content.height = d.content.height + child.dimensions.margin_box().height;
        }
    }

    /// Height of a block-level non-replaced element in normal flow with overflow visible.
    fn calculate_block_height(&mut self) {
        // If the height is set to an explicit length, use that exact length.
        // Otherwise, just keep the value set by `layout_block_children`.
        match self.get_style_node().value("height") {
            Some(Length(h, Px)) => { self.dimensions.content.height = h; }
            _ => {}
        }
    }

    /// Where a new inline child should go.
    fn get_inline_container(&mut self) -> &mut LayoutBox<'a> {
        match self.box_type {
            InlineNode(_) | AnonymousBlock => self,
            BlockNode(_) => {
                // If we've just generated an anonymous block box, keep using it.
                // Otherwise, create a new one.
                match self.children.last() {
                    Some(&LayoutBox { box_type: AnonymousBlock,..}) => {}
                    _ => self.children.push(LayoutBox::new(AnonymousBlock))
                }
                self.children.last_mut().unwrap()
            }
        }
    }
}

impl Rect {
    pub fn expanded_by(self, edge: EdgeSizes) -> Rect {
        Rect {
            x: self.x - edge.left,
            y: self.y - edge.top,
            width: self.width + edge.left + edge.right,
            height: self.height + edge.top + edge.bottom,
        }
    }
}

impl Dimensions {
    /// The area covered by the content area plus its padding.
    pub fn padding_box(&self) -> Rect {
        self.content.expanded_by(self.padding)
    }
    /// The area covered by the content area plus padding and borders.
    pub fn border_box(&self) -> Rect {
        self.padding_box().expanded_by(self.border)
    }
    /// The area covered by the content area plus padding, borders, and margin.
    pub fn margin_box(&self) -> Rect {
        self.border_box().expanded_by(self.margin)
    }
}
<commit_msg>Remove unnecessary borrows<commit_after>///! Basic CSS block layout.

use style::{StyledNode, Inline, Block, DisplayNone};
use css::{Keyword, Length, Px};
use std::default::Default;
use std::iter::AdditiveIterator; // for `sum`

// CSS box model. All sizes are in px.

#[deriving(Default, Show)]
pub struct Rect {
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
}

#[deriving(Default, Show)]
pub struct Dimensions {
    /// Position of the content area relative to the document origin:
    pub content: Rect,
    // Surrounding edges:
    pub padding: EdgeSizes,
    pub border: EdgeSizes,
    pub margin: EdgeSizes,
}

#[deriving(Default, Show)]
pub struct EdgeSizes {
    pub left: f32,
    pub right: f32,
    pub top: f32,
    pub bottom: f32,
}

/// A node in the layout tree.
pub struct LayoutBox<'a> {
    pub dimensions: Dimensions,
    pub box_type: BoxType<'a>,
    pub children: Vec<LayoutBox<'a>>,
}

pub enum BoxType<'a> {
    BlockNode(&'a StyledNode<'a>),
    InlineNode(&'a StyledNode<'a>),
    AnonymousBlock,
}

impl<'a> LayoutBox<'a> {
    fn new(box_type: BoxType) -> LayoutBox {
        LayoutBox {
            box_type: box_type,
            dimensions: Default::default(),
            children: Vec::new(),
        }
    }

    fn get_style_node(&self) -> &'a StyledNode<'a> {
        match self.box_type {
            BlockNode(node) => node,
            InlineNode(node) => node,
            AnonymousBlock => panic!("Anonymous block box has no style node")
        }
    }
}

/// Transform a style tree into a layout tree.
pub fn layout_tree<'a>(node: &'a StyledNode<'a>, mut containing_block: Dimensions) -> LayoutBox<'a> {
    // The layout algorithm expects the container height to start at 0.
    // TODO: Save the initial containing block height, for calculating percent heights.
    containing_block.content.height = 0.0;

    let mut root_box = build_layout_tree(node);
    root_box.layout(containing_block);
    return root_box;
}

/// Build the tree of LayoutBoxes, but don't perform any layout calculations yet.
fn build_layout_tree<'a>(style_node: &'a StyledNode<'a>) -> LayoutBox<'a> {
    // Create the root box.
    let mut root = LayoutBox::new(match style_node.display() {
        Block => BlockNode(style_node),
        Inline => InlineNode(style_node),
        DisplayNone => panic!("Root node has display: none.")
    });

    // Create the descendant boxes.
    for child in style_node.children.iter() {
        match child.display() {
            Block => root.children.push(build_layout_tree(child)),
            Inline => root.get_inline_container().children.push(build_layout_tree(child)),
            DisplayNone => {} // Don't lay out nodes with `display: none;`
        }
    }
    return root;
}

impl<'a> LayoutBox<'a> {
    /// Lay out a box and its descendants.
    fn layout(&mut self, containing_block: Dimensions) {
        match self.box_type {
            BlockNode(_) => self.layout_block(containing_block),
            InlineNode(_) => {} // TODO
            AnonymousBlock => {} // TODO
        }
    }

    /// Lay out a block-level element and its descendants.
    fn layout_block(&mut self, containing_block: Dimensions) {
        // Child width can depend on parent width, so we need to calculate this box's width before
        // laying out its children.
        self.calculate_block_width(containing_block);

        // Determine where the box is located within its container.
        self.calculate_block_position(containing_block);

        // Recursively lay out the children of this box.
        self.layout_block_children();

        // Parent height can depend on child height, so `calculate_height` must be called after the
        // children are laid out.
        self.calculate_block_height();
    }

    /// Calculate the width of a block-level non-replaced element in normal flow.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#blockwidth
    ///
    /// Sets the horizontal margin/padding/border dimensions, and the `width`.
    fn calculate_block_width(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();

        // `width` has initial value `auto`.
        let auto = Keyword("auto".to_string());
        let mut width = style.value("width").unwrap_or(auto.clone());

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        let mut margin_left = style.lookup("margin-left", "margin", &zero);
        let mut margin_right = style.lookup("margin-right", "margin", &zero);

        let border_left = style.lookup("border-left-width", "border-width", &zero);
        let border_right = style.lookup("border-right-width", "border-width", &zero);

        let padding_left = style.lookup("padding-left", "padding", &zero);
        let padding_right = style.lookup("padding-right", "padding", &zero);

        let total = [&margin_left, &margin_right, &border_left, &border_right,
                     &padding_left, &padding_right, &width].iter().map(|v| v.to_px()).sum();

        // If width is not auto and the total is wider than the container, treat auto margins as 0.
        if width != auto && total > containing_block.content.width {
            if margin_left == auto {
                margin_left = Length(0.0, Px);
            }
            if margin_right == auto {
                margin_right = Length(0.0, Px);
            }
        }

        // Adjust used values so that the above sum equals `containing_block.width`.
        // Each arm of the `match` should increase the total width by exactly `underflow`,
        // and afterward all values should be absolute lengths in px.
        let underflow = containing_block.content.width - total;

        match (width == auto, margin_left == auto, margin_right == auto) {
            // If the values are overconstrained, calculate margin_right.
            (false, false, false) => {
                margin_right = Length(margin_right.to_px() + underflow, Px);
            }

            // If exactly one size is auto, its used value follows from the equality.
            (false, false, true) => { margin_right = Length(underflow, Px); }
            (false, true, false) => { margin_left  = Length(underflow, Px); }

            // If width is set to auto, any other auto values become 0.
            (true, _, _) => {
                if margin_left == auto { margin_left = Length(0.0, Px); }
                if margin_right == auto { margin_right = Length(0.0, Px); }

                if underflow >= 0.0 {
                    // Expand width to fill the underflow.
                    width = Length(underflow, Px);
                } else {
                    // Width can't be negative. Adjust the right margin instead.
                    width = Length(0.0, Px);
                    margin_right = Length(margin_right.to_px() + underflow, Px);
                }
            }

            // If margin-left and margin-right are both auto, their used values are equal.
            (false, true, true) => {
                margin_left = Length(underflow / 2.0, Px);
                margin_right = Length(underflow / 2.0, Px);
            }
        }

        let d = &mut self.dimensions;
        d.content.width = width.to_px();

        d.padding.left = padding_left.to_px();
        d.padding.right = padding_right.to_px();

        d.border.left = border_left.to_px();
        d.border.right = border_right.to_px();

        d.margin.left = margin_left.to_px();
        d.margin.right = margin_right.to_px();
    }

    /// Finish calculating the block's edge sizes, and position it within its containing block.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#normal-block
    ///
    /// Sets the vertical margin/padding/border dimensions, and the `x`, `y` values.
    fn calculate_block_position(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();
        let d = &mut self.dimensions;

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        // If margin-top or margin-bottom is `auto`, the used value is zero.
        d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
        d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

        d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
        d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

        d.padding.top = style.lookup("padding-top", "padding", &zero).to_px();
        d.padding.bottom = style.lookup("padding-bottom", "padding", &zero).to_px();

        // Position the box below all the previous boxes in the container.
        d.content.x = containing_block.content.x +
                      d.margin.left + d.border.left + d.padding.left;
        d.content.y = containing_block.content.y + containing_block.content.height +
                      d.margin.top + d.border.top + d.padding.top;
    }

    /// Lay out the block's children within its content area.
    ///
    /// Sets `self.dimensions.height` to the total content height.
    fn layout_block_children(&mut self) {
        let d = &mut self.dimensions;
        for child in self.children.iter_mut() {
            child.layout(*d);
            // Increment the height so each child is laid out below the previous one.
            d.content.height = d.content.height + child.dimensions.margin_box().height;
        }
    }

    /// Height of a block-level non-replaced element in normal flow with overflow visible.
    fn calculate_block_height(&mut self) {
        // If the height is set to an explicit length, use that exact length.
        // Otherwise, just keep the value set by `layout_block_children`.
        match self.get_style_node().value("height") {
            Some(Length(h, Px)) => { self.dimensions.content.height = h; }
            _ => {}
        }
    }

    /// Where a new inline child should go.
    fn get_inline_container(&mut self) -> &mut LayoutBox<'a> {
        match self.box_type {
            InlineNode(_) | AnonymousBlock => self,
            BlockNode(_) => {
                // If we've just generated an anonymous block box, keep using it.
                // Otherwise, create a new one.
                match self.children.last() {
                    Some(&LayoutBox { box_type: AnonymousBlock,..}) => {}
                    _ => self.children.push(LayoutBox::new(AnonymousBlock))
                }
                self.children.last_mut().unwrap()
            }
        }
    }
}

impl Rect {
    pub fn expanded_by(self, edge: EdgeSizes) -> Rect {
        Rect {
            x: self.x - edge.left,
            y: self.y - edge.top,
            width: self.width + edge.left + edge.right,
            height: self.height + edge.top + edge.bottom,
        }
    }
}

impl Dimensions {
    /// The area covered by the content area plus its padding.
    pub fn padding_box(self) -> Rect {
        self.content.expanded_by(self.padding)
    }
    /// The area covered by the content area plus padding and borders.
    pub fn border_box(self) -> Rect {
        self.padding_box().expanded_by(self.border)
    }
    /// The area covered by the content area plus padding, borders, and margin.
    pub fn margin_box(self) -> Rect {
        self.border_box().expanded_by(self.margin)
    }
}
<|endoftext|>


<commit_before><commit_msg>removed macros<commit_after><|endoftext|>


<commit_before><commit_msg>palyer struct<commit_after>

pub struct Player
{
    pos : (f64, f64)
}

impl Player
{
    pub fn new() -> Player {
        App {
            pos: (50.0f32, 50.0f32)
        }
    }
}
<|endoftext|>


<commit_before>extern crate orbclient;

#[derive(Clone, Copy)]
pub struct Color {
    r: u8,
    g: u8,
    b: u8,
}

impl Color {
    pub fn new(r: u8, g: u8, b: u8) -> Color {
        Color {
            r: r,
            g: g,
            b: b,
        }
    }

    pub fn as_orbclient(&self) -> orbclient::color::Color {
        orbclient::color::Color::rgb(self.r, self.g, self.b)
    }
}

pub struct Framebuffer {
    pub width: usize,
    pub height: usize,
    frame: Vec<Color>,
}

impl Framebuffer {
    pub fn new(w: usize, h: usize) -> Framebuffer {
        let mut frame: Vec<Color> = Vec::new();

        for _ in 0..w*h {
            frame.push(Color::new(0, 0, 0));
        }

        Framebuffer {
            width: w,
            height: h,
            frame: frame,
        }
    }

    pub fn get_pixel(&self, x: u32, y: u32) -> Option<&Color> {
        self.frame.get(y as usize*self.width + x as usize)
    }

    pub fn set_pixel(&mut self, x: u32, y: u32, color: &Color) {
        self.frame[y as usize*self.width + x as usize] = color.clone();
    }

    pub fn render_triangles(&mut self, triangles: Vec<super::geometry::Triangle>) {

    }
}
<commit_msg>Added textures<commit_after>extern crate orbclient;

#[derive(Clone, Copy)]
pub struct Color {
    r: u8,
    g: u8,
    b: u8,
}

impl Color {
    pub fn new(r: u8, g: u8, b: u8) -> Color {
        Color {
            r: r,
            g: g,
            b: b,
        }
    }

    pub fn as_orbclient(&self) -> orbclient::color::Color {
        orbclient::color::Color::rgb(self.r, self.g, self.b)
    }

    pub fn from_orbclient(color: orbclient::color::Color) -> Color {
        let r = (color.data & 0x00FF0000) >> 16;
        let g = (color.data & 0x0000FF00) >> 8;
        let b = color.data & 0x000000FF;

        Color::new(r as u8, g as u8, b as u8)
    }
}

pub struct Texture {
    pub width: usize,
    pub height: usize,
    frame: Vec<Color>,
}

impl Texture {
    pub fn new(w: usize, h: usize) -> Texture {
        let mut tex: Vec<Color> = Vec::new();

        for _ in 0..w*h {
            tex.push(Color::new(0, 0, 0));
        }

        Texture {
            width: w,
            height: h,
            frame: tex,
        }
    }

    pub fn load(path: &str) -> Texture {
        use std::ops::Deref;

        let bmp = orbclient::bmp::BmpFile::from_path(path);
        let w = bmp.width();
        let h = bmp.height();

        let orb_color_vec = bmp.deref();

        let mut color_vec: Vec<Color> = Vec::new();

        for i in 0..orb_color_vec.len() {
            color_vec.push(Color::from_orbclient(orb_color_vec[i]));
        }

        Texture {
            width: w,
            height: h,
            frame: color_vec,
        }
    }
}

pub struct Framebuffer {
    pub width: usize,
    pub height: usize,
    frame: Vec<Color>,
}

impl Framebuffer {
    pub fn new(w: usize, h: usize) -> Framebuffer {
        let mut frame: Vec<Color> = Vec::new();

        for _ in 0..w*h {
            frame.push(Color::new(0, 0, 0));
        }

        Framebuffer {
            width: w,
            height: h,
            frame: frame,
        }
    }

    pub fn get_pixel(&self, x: u32, y: u32) -> Option<&Color> {
        self.frame.get(y as usize*self.width + x as usize)
    }

    pub fn set_pixel(&mut self, x: u32, y: u32, color: &Color) {
        self.frame[y as usize*self.width + x as usize] = color.clone();
    }

    pub fn render_triangles(&mut self, triangles: Vec<super::geometry::Triangle>) {

    }
}
<|endoftext|>


<commit_before><commit_msg>test file with sha1 implemented<commit_after>use bloomfilter;
use std;
import sha1 = std::sha1;

#[doc = "an example hashing function using the standard library sha1"]
fn sha1(elem: str) -> [u8] {
    let sha1 = sha1::sha1();
    sha1.input_str(elem);
    let hashstr = sha1.result();
    sha1.reset();
    hashstr
}

#[doc = "A variety of test cases"]
fn main(){

    test1();
    test2();
    test3();
    test4();
    io::println("bloomin!");
}
fn test1() {
    let bfilter = bloomfilter::bloomfilter(10000u, [sha1]);
    bloomfilter::add(bfilter, "a");
    assert bloomfilter::contains(bfilter,"a");
    bloomfilter::add(bfilter, "variety");
    assert bloomfilter::contains(bfilter,"variety");
    bloomfilter::add(bfilter, "of test");
    assert bloomfilter::contains(bfilter,"of test");
    bloomfilter::add(bfilter, "in");
    assert bloomfilter::contains(bfilter,"in");
    bloomfilter::add(bfilter, "Rust!");
    assert bloomfilter::contains(bfilter,"Rust!");
    assert (bloomfilter::contains(bfilter,"randomstuff") == false);
}

fn test2() {
    let bfilter = bloomfilter::bloomfilter(10u, [sha1]);
    bloomfilter::add(bfilter, "a collision test");
    assert bloomfilter::contains(bfilter,"a col test");
    assert bloomfilter::contains(bfilter,"test");
}

fn test3() {
    let bfilter = bloomfilter::bloomfilter(100u, [sha1]);
    let bfilter2 = bloomfilter::bloomfilter(100u, [sha1]);
    bloomfilter::add(bfilter, "a merge test");
    assert bloomfilter::contains(bfilter,"a merge test");
    assert (bloomfilter::contains(bfilter,"Rust!") == false);
    assert (bloomfilter::contains(bfilter,"not in there!") == false);
    bloomfilter::add(bfilter2, "Rust!");
    assert bloomfilter::contains(bfilter2,"Rust!");
    assert (bloomfilter::contains(bfilter2,"a merge test") == false);
    assert (bloomfilter::contains(bfilter2,"not in there!") == false);
    let bfilter3 = bloomfilter::union(bfilter, bfilter2);
    assert bloomfilter::contains(bfilter3,"Rust!");
    assert bloomfilter::contains(bfilter3,"a merge test") ;
    assert (bloomfilter::contains(bfilter3,"not in there!") == false);

}

fn test4() {
    fn psuedosha1(elem: str) -> [u8] {
        let sha1 = sha1::sha1();
        sha1.input_str(elem);
        let hashstr = sha1.result();
        sha1.reset();
        let mut newhash: [u8] = [];
        for vec::each(hashstr) {|elm|
            newhash = newhash + [elm + 3 as u8];
        }
        newhash
    }

    let bfilter = bloomfilter::bloomfilter(10000u, [psuedosha1,sha1]);
    bloomfilter::add(bfilter, "a");
    assert bloomfilter::contains(bfilter,"a");
    bloomfilter::add(bfilter, "variety");
    assert bloomfilter::contains(bfilter,"variety");
    bloomfilter::add(bfilter, "of test");
    assert bloomfilter::contains(bfilter,"of test");
    bloomfilter::add(bfilter, "in");
    assert bloomfilter::contains(bfilter,"in");
    bloomfilter::add(bfilter, "Rust!");
    assert bloomfilter::contains(bfilter,"Rust!");
    assert (bloomfilter::contains(bfilter,"randomstuff") == false);
}

<|endoftext|>


<commit_before>extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate shader_version;
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
#[cfg(feature = "include_glfw")]
extern crate glfw_window;
#[cfg(feature = "include_glutin")]
extern crate glutin_window;

use opengl_graphics::GlGraphics;
use graphics::{ Context, Graphics };
use std::cell::RefCell;
use piston::quack::Set;
use piston::window::{ WindowSettings, CaptureCursor };
use piston::input::Button;
use piston::input::keyboard::Key;
use piston::event::{
    PressEvent,
    ReleaseEvent,
    MouseCursorEvent,
    MouseScrollEvent,
    MouseRelativeEvent,
    TextEvent,
    ResizeEvent,
    FocusEvent,
    RenderEvent,
    UpdateEvent
};
use shader_version::OpenGL;
#[cfg(feature = "include_sdl2")]
use sdl2_window::Sdl2Window as Window;
#[cfg(feature = "include_glfw")]
use glfw_window::GlfwWindow as Window;
#[cfg(feature = "include_glutin")]
use glutin_window::GlutinWindow as Window;

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Window::new(
        opengl,
        WindowSettings {
            title: "piston-examples/user_input".to_string(),
            size: [600, 600],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    println!("Press C to turn capture cursor on/off");

    let mut capture_cursor = false;
    let ref window = RefCell::new(window);
    let ref mut gl = GlGraphics::new(opengl);
    for e in piston::events(window) {
        if let Some(Button::Mouse(button)) = e.press_args() {
            println!("Pressed mouse button '{:?}'", button);
        }
        if let Some(Button::Keyboard(key)) = e.press_args() {
            if key == Key::C {
                println!("Turned capture cursor on");
                capture_cursor = !capture_cursor;
                window.set(CaptureCursor(capture_cursor));
            }

            println!("Pressed keyboard key '{:?}'", key);
        };
        if let Some(button) = e.release_args() {
            match button {
                Button::Keyboard(key) => println!("Released keyboard key '{:?}'", key),
                Button::Mouse(button) => println!("Released mouse button '{:?}'", button),
            }
        };
        e.mouse_cursor(|x, y| println!("Mouse moved '{} {}'", x, y));
        e.mouse_scroll(|dx, dy| println!("Scrolled mouse '{}, {}'", dx, dy));
        e.mouse_relative(|dx, dy| println!("Relative mouse moved '{} {}'", dx, dy));
        e.text(|text| println!("Typed '{}'", text));
        e.resize(|w, h| println!("Resized '{}, {}'", w, h));
        if let Some(focused) = e.focus_args() {
            if focused { println!("Gained focus"); }
            else { println!("Lost focus"); }
        };
        if let Some(args) = e.render_args() {
            gl.draw(
                [0, 0, args.width as i32, args.height as i32],
                |c, g| {
                    graphics::clear([1.0; 4], g);
                    draw_rectangles(&c, g);
                }
            );
        }
        e.update(|_| {});
    }
}

fn draw_rectangles<G: Graphics>(
    c: &Context,
    g: &mut G
) {
    let rect_border = graphics::Rectangle::border([1.0, 0.0, 0.0, 1.0], 1.0);
    // Desktop.
    rect_border.draw([0.0, 0.0, 100.0, 100.0], c, g);
    // Outer window.
    rect_border.draw([0.0, 0.0, 50.0, 50.0], c, g);
    // Inner window.
    rect_border.draw([2.0, 5.0, 46.0, 43.0], c, g);

    // User coordinates.
    rect_border.draw([0.0, 120.0, 100.0, 100.0], c, g);
    let rect_border = graphics::Rectangle::border([0.0, 0.0, 1.0, 1.0], 1.0);
    rect_border.draw([0.0, 120.0, 200.0, 200.0], c, g);
}
<commit_msg>Draw window size and window draw-size beside each other<commit_after>extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate shader_version;
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
#[cfg(feature = "include_glfw")]
extern crate glfw_window;
#[cfg(feature = "include_glutin")]
extern crate glutin_window;

use opengl_graphics::GlGraphics;
use graphics::{ Context, Graphics };
use std::cell::RefCell;
use piston::quack::Set;
use piston::window::{ WindowSettings, CaptureCursor };
use piston::input::Button;
use piston::input::keyboard::Key;
use piston::event::{
    PressEvent,
    ReleaseEvent,
    MouseCursorEvent,
    MouseScrollEvent,
    MouseRelativeEvent,
    TextEvent,
    ResizeEvent,
    FocusEvent,
    RenderEvent,
    UpdateEvent
};
use shader_version::OpenGL;
#[cfg(feature = "include_sdl2")]
use sdl2_window::Sdl2Window as Window;
#[cfg(feature = "include_glfw")]
use glfw_window::GlfwWindow as Window;
#[cfg(feature = "include_glutin")]
use glutin_window::GlutinWindow as Window;

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Window::new(
        opengl,
        WindowSettings {
            title: "piston-examples/user_input".to_string(),
            size: [600, 600],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    println!("Press C to turn capture cursor on/off");

    let mut capture_cursor = false;
    let ref window = RefCell::new(window);
    let ref mut gl = GlGraphics::new(opengl);
    for e in piston::events(window) {
        if let Some(Button::Mouse(button)) = e.press_args() {
            println!("Pressed mouse button '{:?}'", button);
        }
        if let Some(Button::Keyboard(key)) = e.press_args() {
            if key == Key::C {
                println!("Turned capture cursor on");
                capture_cursor = !capture_cursor;
                window.set(CaptureCursor(capture_cursor));
            }

            println!("Pressed keyboard key '{:?}'", key);
        };
        if let Some(button) = e.release_args() {
            match button {
                Button::Keyboard(key) => println!("Released keyboard key '{:?}'", key),
                Button::Mouse(button) => println!("Released mouse button '{:?}'", button),
            }
        };
        e.mouse_cursor(|x, y| println!("Mouse moved '{} {}'", x, y));
        e.mouse_scroll(|dx, dy| println!("Scrolled mouse '{}, {}'", dx, dy));
        e.mouse_relative(|dx, dy| println!("Relative mouse moved '{} {}'", dx, dy));
        e.text(|text| println!("Typed '{}'", text));
        e.resize(|w, h| println!("Resized '{}, {}'", w, h));
        if let Some(focused) = e.focus_args() {
            if focused { println!("Gained focus"); }
            else { println!("Lost focus"); }
        };
        if let Some(args) = e.render_args() {
            gl.draw(
                [0, 0, args.width as i32, args.height as i32],
                |c, g| {
                    graphics::clear([1.0; 4], g);
                    draw_rectangles(&window, &c, g);
                }
            );
        }
        e.update(|_| {});
    }
}

fn draw_rectangles<G: Graphics>(
    window: &RefCell<Window>,
    c: &Context,
    g: &mut G,
) {
    use piston::window::{ Size, DrawSize };
    use piston::quack::Get;

    let rect_border = graphics::Rectangle::border([1.0, 0.0, 0.0, 1.0], 1.0);

    let Size([w, h]) = window.get();
    let DrawSize([dw, dh]) = window.get();
    let zoom = 0.2;

    // User coordinates.
    rect_border.draw([0.0, 0.0, w as f64 * zoom, h as f64 * zoom], c, g);
    let rect_border = graphics::Rectangle::border([0.0, 0.0, 1.0, 1.0], 1.0);
    rect_border.draw([w as f64 * zoom, 0.0, dw as f64 * zoom, dh as f64 * zoom], c, g);
}
<|endoftext|>


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

#![feature(std_misc)]

extern crate rustfmt;

use std::collections::HashMap;
use std::fs;
use std::io::Read;
use rustfmt::*;

// For now, the only supported regression tests are idempotent tests - the input and
// output must match exactly.
// FIXME(#28) would be good to check for error messages and fail on them, or at least report.
#[test]
fn idempotent_tests() {
    println!("Idempotent tests:");

    // Get all files in the tests/idem directory
    let files = fs::read_dir("tests/idem").unwrap();
    let files2 = fs::read_dir("tests").unwrap();
    let files3 = fs::read_dir("src/bin").unwrap();
    // For each file, run rustfmt and collect the output

    let mut count = 0;
    let mut fails = 0;
    for entry in files.chain(files2).chain(files3) {
        let path = entry.unwrap().path();
        let file_name = path.to_str().unwrap();
        if !file_name.ends_with(".rs") {
            continue;
        }
        println!("Testing '{}'...", file_name);
        match idempotent_check(file_name.to_owned()) {
            Ok(()) => {},
            Err(m) => {
                print_mismatches(m);
                fails += 1;
            },
        }
        count += 1;
    }
    // And also dogfood rustfmt!
    println!("Testing 'src/lib.rs'...");
    match idempotent_check("src/lib.rs".to_owned()) {
        Ok(()) => {},
        Err(m) => {
            print_mismatches(m);
            fails += 1;
        },
    }
    count += 1;

    // Display results
    println!("Ran {} idempotent tests; {} failures.", count, fails);
    assert!(fails == 0, "{} idempotent tests failed", fails);
}

// Compare output to input.
fn print_mismatches(result: HashMap<String, String>) {
    for (file_name, fmt_text) in result {
        println!("Mismatch in {}.", file_name);
        println!("{}", fmt_text);
    }
}

// Ick, just needed to get a &'static to handle_result.
static HANDLE_RESULT: &'static Fn(HashMap<String, String>) = &handle_result;

pub fn idempotent_check(filename: String) -> Result<(), HashMap<String, String>> {
    use std::thread;
    use std::fs;
    use std::io::Read;
	let args = vec!["rustfmt".to_owned(), filename];
    thread::spawn(move || {
        run(args, WriteMode::Return(HANDLE_RESULT));
    }).join().map_err(|mut any|
        any.downcast_mut::<HashMap<String, String>>()
           .unwrap() // i know it is a hashmap
           .drain() // i only get a reference :(
           .collect() // so i need to turn it into an iter and then back
    )
}

// Compare output to input.
fn handle_result(result: HashMap<String, String>) {
    let mut failures = HashMap::new();

    for (file_name, fmt_text) in result {
        let mut f = fs::File::open(&file_name).unwrap();
        let mut text = String::new();
        // TODO: speedup by running through bytes iterator
        f.read_to_string(&mut text).unwrap();
        if fmt_text != text {
            failures.insert(file_name, fmt_text);
        }
    }
    if !failures.is_empty() {
        panic!(failures);
    }
}
<commit_msg>rustfmt dislikes tabs and some newlines<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(std_misc)]
extern crate rustfmt;

use std::collections::HashMap;
use std::fs;
use std::io::Read;
use rustfmt::*;

// For now, the only supported regression tests are idempotent tests - the input and
// output must match exactly.
// FIXME(#28) would be good to check for error messages and fail on them, or at least report.
#[test]
fn idempotent_tests() {
    println!("Idempotent tests:");

    // Get all files in the tests/idem directory
    let files = fs::read_dir("tests/idem").unwrap();
    let files2 = fs::read_dir("tests").unwrap();
    let files3 = fs::read_dir("src/bin").unwrap();
    // For each file, run rustfmt and collect the output

    let mut count = 0;
    let mut fails = 0;
    for entry in files.chain(files2).chain(files3) {
        let path = entry.unwrap().path();
        let file_name = path.to_str().unwrap();
        if !file_name.ends_with(".rs") {
            continue;
        }
        println!("Testing '{}'...", file_name);
        match idempotent_check(file_name.to_owned()) {
            Ok(()) => {},
            Err(m) => {
                print_mismatches(m);
                fails += 1;
            },
        }
        count += 1;
    }
    // And also dogfood rustfmt!
    println!("Testing 'src/lib.rs'...");
    match idempotent_check("src/lib.rs".to_owned()) {
        Ok(()) => {},
        Err(m) => {
            print_mismatches(m);
            fails += 1;
        },
    }
    count += 1;

    // Display results
    println!("Ran {} idempotent tests; {} failures.", count, fails);
    assert!(fails == 0, "{} idempotent tests failed", fails);
}

// Compare output to input.
fn print_mismatches(result: HashMap<String, String>) {
    for (file_name, fmt_text) in result {
        println!("Mismatch in {}.", file_name);
        println!("{}", fmt_text);
    }
}

// Ick, just needed to get a &'static to handle_result.
static HANDLE_RESULT: &'static Fn(HashMap<String, String>) = &handle_result;

pub fn idempotent_check(filename: String) -> Result<(), HashMap<String, String>> {
    use std::thread;
    use std::fs;
    use std::io::Read;
    let args = vec!["rustfmt".to_owned(), filename];
    thread::spawn(move || {
        run(args, WriteMode::Return(HANDLE_RESULT));
    }).join().map_err(|mut any|
        any.downcast_mut::<HashMap<String, String>>()
           .unwrap() // i know it is a hashmap
           .drain() // i only get a reference :(
           .collect() // so i need to turn it into an iter and then back
    )
}

// Compare output to input.
fn handle_result(result: HashMap<String, String>) {
    let mut failures = HashMap::new();

    for (file_name, fmt_text) in result {
        let mut f = fs::File::open(&file_name).unwrap();
        let mut text = String::new();
        // TODO: speedup by running through bytes iterator
        f.read_to_string(&mut text).unwrap();
        if fmt_text != text {
            failures.insert(file_name, fmt_text);
        }
    }
    if !failures.is_empty() {
        panic!(failures);
    }
}
<|endoftext|>


<commit_before><commit_msg>#1 Added 7_type_inference.rs<commit_after>#[derive(Debug)]
enum Position {
    Zero,
    One,
    Two
}

fn main() {
    let position = Position::One;
    let mut positions = Vec::new();
    // infers here
    positions.push(position);
    println!("positions = {:?}", positions);
}<|endoftext|>


<commit_before><commit_msg>Add 7 segment display example<commit_after>#![no_std]

extern crate tock;

const DATA_PIN: u32 = 0;
const CLOCK_PIN: u32 = 1;
const LATCH_PIN: u32 = 2;
const SPEED: u32 = 2;

use tock::{led, timer};

fn push_one_bit(value: bool) {
    if value {
        led::on(DATA_PIN)
    } else {
        led::off(DATA_PIN)
    }
    led::on(CLOCK_PIN);
    timer::delay_ms(SPEED);
    led::off(CLOCK_PIN);
    timer::delay_ms(SPEED);
}

fn push_bits(values: &[bool]) {
    for i in values {
        push_one_bit(*i);
    }
    display();
    timer::delay_ms(200);
}

fn display() {
    led::on(LATCH_PIN);
    timer::delay_ms(SPEED);
    led::off(LATCH_PIN);
}

fn number_to_bits(n: u8) -> [bool; 8] {
    match n {
        1 => [true, true, true, false, true, false, true, true],
        2 => [false, true, false, false, true, true, false, false],
        3 => [false, true, false, false, true, false, false, true],
        4 => [false, false, true, false, true, false, true, true],
        5 => [false, false, false, true, true, false, false, true],
        6 => [false, false, false, true, true, false, false, false],
        7 => [true, true, false, false, true, false, true, true],
        8 => [false, false, false, false, true, false, false, false],
        9 => [false, false, false, false, true, false, false, true],
        0 => [true, false, false, false, true, false, false, false],
        _ => [true, true, true, true, false, true, true, true],
    }
}

fn main() {
    let mut i = 0;
    loop {
        i = (i + 1) % 11;
        push_bits(&number_to_bits(i));
    }
}
<|endoftext|>


<commit_before><commit_msg>Stress test<commit_after>extern crate bytes;
extern crate httpbis;
extern crate futures;
extern crate regex;

use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;

use std::thread;
use std::time::Duration;

use regex::Regex;

use bytes::Bytes;

use futures::future::Future;
use futures::stream::Stream;
use futures::stream;
use futures::sink::Sink;
use futures::sync::mpsc;

use httpbis::*;

fn new_server() -> Server {
    let mut server = ServerBuilder::new_plain();
    server.service.set_service_fn("/200", |_, _| {
        Response::headers(Headers::ok_200())
    });
    server.service.set_service_fn("/inf", |headers, _| {
        let re = Regex::new("/inf/(\\d+)").expect("regex");
        let captures = re.captures(headers.path()).expect("captures");
        let size: u32 = captures.get(1).expect("1").as_str().parse().expect("parse");

        Response::headers_and_bytes_stream(
            Headers::ok_200(),
            stream::repeat(Bytes::from(vec![17; size as usize])))
    });
    server.service.set_service_fn("/bq", |headers, _| {
        let re = Regex::new("/bq/(\\d+)").expect("regex");
        let captures = re.captures(headers.path()).expect("captures");
        let size: u32 = captures.get(1).expect("1").as_str().parse().expect("parse");

        let (tx, rx) = mpsc::channel(1);

        thread::spawn(move || {
            let mut tx = tx;

            let b = Bytes::from(vec![17; size as usize]);
            loop {
                tx = tx.send(b.clone()).wait().expect("send");
            }
        });

        Response::headers_and_bytes_stream(
            Headers::ok_200(),
            rx.map_err(|_| unreachable!()))
    });
    server.set_port(0);
    server.build().expect("server")
}

fn spawn<F : FnOnce(Client, Arc<AtomicBool>) + Send + 'static>(port: u16, f: F) -> Arc<AtomicBool> {
    let still_alive = Arc::new(AtomicBool::new(false));
    let still_alive_copy = still_alive.clone();
    thread::spawn(move || {
        let client = Client::new_plain("::1", port, ClientConf::new()).expect("client");

        f(client, still_alive_copy)
    });
    still_alive
}

fn get_200(client: Client, still_alive: Arc<AtomicBool>) {
    loop {
        still_alive.store(true, Ordering::SeqCst);
        let r = client.start_get("/200", "localhost").collect().wait().expect("get");
        assert_eq!(200, r.headers.status());
    }
}

fn inf_impl(client: Client, still_alive: Arc<AtomicBool>, path: &str, size: usize) {
    let (headers, resp) = client.start_get(path, "localhost").0.wait().expect("get");

    assert_eq!(200, headers.status());

    let mut resp = resp.filter_data().wait();

    let exp = vec![17; size as usize];

    loop {
        still_alive.store(true, Ordering::SeqCst);

        let mut v = Vec::new();
        while v.len() < size as usize {
            still_alive.store(true, Ordering::SeqCst);
            v.extend(resp.next().unwrap().unwrap());
        }
        assert_eq!(&exp[..], &v[..size]);
        v.drain(..size);
    }
}

fn inf_100(client: Client, still_alive: Arc<AtomicBool>) {
    inf_impl(client, still_alive, "/inf/100", 100);
}

fn inf_10m(client: Client, still_alive: Arc<AtomicBool>) {
    inf_impl(client, still_alive, "/inf/10000000", 10000000);
}

fn bq_100(client: Client, still_alive: Arc<AtomicBool>) {
    inf_impl(client, still_alive, "/bq/100", 100);
}

fn bq_10m(client: Client, still_alive: Arc<AtomicBool>) {
    inf_impl(client, still_alive, "/bq/10000000", 10000000);
}

fn main() {
    let server = new_server();

    let get_200 = spawn(server.local_addr().port(), get_200);
    let inf_100 = spawn(server.local_addr().port(), inf_100);
    let inf_10m = spawn(server.local_addr().port(), inf_10m);
    let bq_100 = spawn(server.local_addr().port(), bq_100);
    let bq_10m = spawn(server.local_addr().port(), bq_10m);

    let all = vec![
        ("get_200", get_200),
        ("inf_100", inf_100),
        ("inf_10m", inf_10m),
        ("bq_100", bq_100),
        ("bq_10m", bq_10m),
    ];

    loop {
        thread::sleep(Duration::from_secs(1));

        let mut any_dead = false;
        for &(n, ref a) in &all {
            if !a.load(Ordering::SeqCst) {
                println!("{} is probably dead", n);
                any_dead = true;
            }
            a.store(false, Ordering::SeqCst);
        }

        if !any_dead {
            println!("all alive");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added destructure tuple example<commit_after>fn main() {
    let pair = (0, -2);
    // TODO ^ Try different values for `pair`

    println!("Tell me about {:?}", pair);
    // Match can be used to destructure a tuple
    match pair {
        // Destructure the second
        (0, y) => println!("First is `0` and `y` is `{:?}`", y),
        (x, 0) => println!("`x` is `{:?}` and last is `0`", x),
        _      => println!("It doesn't matter what they are"),
        // `_` means don't bind the value to a variable
    }
}
<|endoftext|>


<commit_before><commit_msg>fix build<commit_after><|endoftext|>


<commit_before><commit_msg>Use char instead of string literal<commit_after><|endoftext|>


<commit_before><commit_msg>Add a comments example<commit_after>extern crate env_logger;
extern crate hyper;
extern crate hubcaps;
extern crate futures;
extern crate tokio_core;
#[macro_use(quick_main)]
extern crate error_chain;

use std::env;

use futures::Future;
use tokio_core::reactor::Core;

use hubcaps::{Credentials, Github, Result};
use hubcaps::comments::CommentOptions;

const USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

quick_main!(run);

fn run() -> Result<()> {
    drop(env_logger::init());
    match env::var("GITHUB_TOKEN").ok() {
        Some(token) => {
            let mut core = Core::new()?;
            let github = Github::new(
                USER_AGENT,
                Some(Credentials::Token(token)),
                &core.handle(),
            );

            let issue = github.repo("softprops", "hubcat").issues().get(1);
            let f = issue.comments()
                .create(&CommentOptions {
                    body: format!("Hello, world!\n---\nSent by {}", USER_AGENT),
                });

            match core.run(f) {
                Ok(comment) => println!("{:?}", comment),
                Err(err) => println!("err {}", err),
            }

            Ok(())
        }
        _ => Err("example missing GITHUB_TOKEN".into()),
    }
}
<|endoftext|>


<commit_before><commit_msg>Add ID reporting in imag-mv<commit_after><|endoftext|>