<commit_before>use std::time::{Duration, SystemTime, Instant};

use crate::stacked_borrows::Tag;
use crate::*;
use helpers::immty_from_int_checked;

/// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
    time.duration_since(SystemTime::UNIX_EPOCH)
        .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    // Foreign function used by linux
    fn clock_gettime(
        &mut self,
        clk_id_op: OpTy<'tcx, Tag>,
        tp_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.check_no_isolation("clock_gettime")?;

        let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
        let tp = this.deref_operand(tp_op)?;

        let duration = if clk_id == this.eval_libc_i32("CLOCK_REALTIME")? {
            system_time_to_duration(&SystemTime::now())?
        } else if clk_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
            // Absolute time does not matter, only relative time does, so we can just
            // use our own time anchor here.
            Instant::now().duration_since(this.machine.time_anchor)
        } else {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        };

        let tv_sec = duration.as_secs();
        let tv_nsec = duration.subsec_nanos();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
        ];

        this.write_packed_immediates(tp, &imms)?;

        Ok(0)
    }
    // Foreign function used by generic unix (in particular macOS)
    fn gettimeofday(
        &mut self,
        tv_op: OpTy<'tcx, Tag>,
        tz_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.check_no_isolation("gettimeofday")?;
        // Using tz is obsolete and should always be null
        let tz = this.read_scalar(tz_op)?.not_undef()?;
        if !this.is_null(tz)? {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        }

        let tv = this.deref_operand(tv_op)?;

        let duration = system_time_to_duration(&SystemTime::now())?;
        let tv_sec = duration.as_secs();
        let tv_usec = duration.subsec_micros();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
        ];

        this.write_packed_immediates(tv, &imms)?;

        Ok(0)
    }
}
<commit_msg>assert platform in time shims<commit_after>use std::time::{Duration, SystemTime, Instant};

use crate::stacked_borrows::Tag;
use crate::*;
use helpers::immty_from_int_checked;

/// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
    time.duration_since(SystemTime::UNIX_EPOCH)
        .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    // Foreign function used by linux
    fn clock_gettime(
        &mut self,
        clk_id_op: OpTy<'tcx, Tag>,
        tp_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.check_no_isolation("clock_gettime")?;
        this.assert_platform("linux");

        let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
        let tp = this.deref_operand(tp_op)?;

        let duration = if clk_id == this.eval_libc_i32("CLOCK_REALTIME")? {
            system_time_to_duration(&SystemTime::now())?
        } else if clk_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
            // Absolute time does not matter, only relative time does, so we can just
            // use our own time anchor here.
            Instant::now().duration_since(this.machine.time_anchor)
        } else {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        };

        let tv_sec = duration.as_secs();
        let tv_nsec = duration.subsec_nanos();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
        ];

        this.write_packed_immediates(tp, &imms)?;

        Ok(0)
    }
    // Foreign function used by generic unix (in particular macOS)
    fn gettimeofday(
        &mut self,
        tv_op: OpTy<'tcx, Tag>,
        tz_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.check_no_isolation("gettimeofday")?;
        this.assert_platform("macos");

        // Using tz is obsolete and should always be null
        let tz = this.read_scalar(tz_op)?.not_undef()?;
        if !this.is_null(tz)? {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        }

        let tv = this.deref_operand(tv_op)?;

        let duration = system_time_to_duration(&SystemTime::now())?;
        let tv_sec = duration.as_secs();
        let tv_usec = duration.subsec_micros();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
        ];

        this.write_packed_immediates(tv, &imms)?;

        Ok(0)
    }
}
<|endoftext|>


<commit_before>// Copyright © 2014, Peter Atashian

use image::{self, GenericImage, ImageBuffer, Pixel, RgbaImage};
use regex::{Regex};
use std::borrow::{ToOwned};
use std::cmp::{max};
use std::collections::{HashMap, HashSet};
use std::fs::{File, walk_dir};
use std::io::prelude::*;
use std::io::{BufWriter};
use std::mem::{swap};
use std::path::{Path};
use {FloatImage, decode_srgb, encode_srgb, resize, save};

struct Tilesheet {
    size: u32,
    img: RgbaImage,
}
impl Tilesheet {
    fn grow(&mut self, w: u32, h: u32) {
        let mut img = ImageBuffer::new(w, h);
        for (x, y, &pix) in self.img.enumerate_pixels() {
            img.put_pixel(x, y, pix);
        }
        swap(&mut self.img, &mut img);
    }
    fn insert(&mut self, x: u32, y: u32, img: &FloatImage) {
        let (width, height) = img.dimensions();
        assert!(width == height);
        let img = resize(img, self.size, self.size);
        let img = encode_srgb(&img);
        let (w, h) = self.img.dimensions();
        if (x + 1) * self.size > w || (y + 1) * self.size > h {
            let (nw, nh) = (max((x + 1) * self.size, w), max((y + 1) * self.size, h));
            self.grow(nw, nh)
        }
        let (x, y) = (x * self.size, y * self.size);
        for (xx, yy, &pix) in img.enumerate_pixels() {
            self.img.put_pixel(x + xx, y + yy, pix);
        }
    }
}
struct TilesheetManager {
    name: String,
    lookup: HashMap<String, (u32, u32)>,
    entries: HashMap<(u32, u32), String>,
    tilesheets: Vec<Tilesheet>,
    next: (u32, u32),
}
impl TilesheetManager {
    fn new(name: &str, sizes: &[u32]) -> TilesheetManager {
        let tilesheets = load_tilesheets(name, sizes);
        let lookup = load_tiles(name);
        let entries = load_entries(&lookup);
        TilesheetManager {
            name: name.to_owned(),
            lookup: lookup,
            entries: entries,
            tilesheets: tilesheets,
            next: (0, 0),
        }
    }
    fn update(&mut self) {
        let path = Path::new(r"work/tilesheets").join(&self.name);
        let mut file = File::create(&Path::new(r"work/tilesheets/Added.txt")).unwrap();
        let renames = if let Ok(mut file) = File::open(&path.join("renames.txt")) {
            let reg = Regex::new("(.*)=(.*)").unwrap();
            let mut s = String::new();
            file.read_to_string(&mut s).unwrap();
            s.lines().map(|line| {
                let cap = reg.captures(line).unwrap();
                (cap.at(1).unwrap().to_owned(), cap.at(2).unwrap().to_owned())
            }).collect()
        } else {
            HashMap::new()
        };
        for entry in walk_dir(&path).unwrap() {
            let path = entry.unwrap().path();
            if !path.is_file() { continue }
            if path.extension().and_then(|x| x.to_str()) != Some("png") { continue }
            let name = path.file_stem().unwrap().to_str().unwrap();
            let name = if let Some(r) = renames.get(name) { &**r } else { name };
            if name.contains(&['_', '[', ']'][..]) { panic!("Illegal name: {:?}", name) }
            let img = image::open(&path).unwrap().to_rgba();
            let img = decode_srgb(&img);
            let (x, y, new) = self.lookup(name);
            if new {
                writeln!(&mut file, "{} {} {}", x, y, name).unwrap();
            }
            for tilesheet in self.tilesheets.iter_mut() {
                tilesheet.insert(x, y, &img);
            }
        }
    }
    fn clear_unused(&mut self) {
        let path = Path::new(r"work/tilesheets").join(&self.name);
        let names: HashSet<_> = walk_dir(&path).unwrap().filter_map(|entry| {
            let path = match entry {
                Ok(x) => x.path(),
                Err(_) => return None,
            };
            if !path.is_file() { None }
            else if path.extension().and_then(|x| x.to_str()) != Some("png") { None }
            else { Some(path.file_stem().unwrap().to_str().unwrap().to_owned()) }
        }).collect();
        let mut file = File::create(&Path::new(r"work/tilesheets/Deleted.txt")).unwrap();
        let lookup = self.lookup.drain().filter(|&(ref name, _)| {
            if !names.contains(name) {
                writeln!(&mut file, "{}", name).unwrap();
                false
            } else { true }
        }).collect();
        let entries = self.entries.drain().filter(|&(_, ref name)| {
            names.contains(name)
        }).collect();
        self.lookup = lookup;
        self.entries = entries;
    }
    fn save(&self) {
        let _optipng = self.tilesheets.iter().map(|tilesheet| {
            let name = format!("Tilesheet {} {}.png", self.name, tilesheet.size);
            let path = Path::new(r"work/tilesheets").join(name);
            save(&tilesheet.img, &path);
            //Command::new("optipng").arg(path).stdin(Stdio::null()).stdout(Stdio::null())
                //.stderr(Stdio::null()).spawn().unwrap()
        }).collect::<Vec<_>>();
        let name = format!("Tilesheet {}.txt", self.name);
        let path = Path::new(r"work/tilesheets").join(name);
        let mut file = BufWriter::new(File::create(&path).unwrap());
        let mut stuff = self.entries.iter().map(|(&(x, y), tile)| (x, y, tile)).collect::<Vec<_>>();
        stuff.sort_by(|a, b| if a.1 == b.1 { a.0.cmp(&b.0) } else { a.1.cmp(&b.1) });
        for &(x, y, tile) in stuff.iter() {
            (writeln!(&mut file, "{} {} {}", x, y, tile)).unwrap();
        }
        println!("Waiting for optipng to finish");
    }
    fn increment(&mut self) {
        self.next.1 += 1;
        if self.next.1 > self.next.0 * 2 {
            self.next.0 += 1;
            self.next.1 = 0;
        }
    }
    fn next_pos(&self) -> (u32, u32) {
        if self.next.1 < self.next.0 {
            (self.next.1, self.next.0)
        } else {
            (self.next.0, self.next.1 - self.next.0)
        }
    }
    fn lookup(&mut self, name: &str) -> (u32, u32, bool) {
        match self.lookup.get(name) {
            Some(&(x, y)) => return (x, y, false),
            None => (),
        }
        while self.entries.get(&self.next_pos()).is_some() {
            self.increment();
        }
        let pos = self.next_pos();
        self.lookup.insert(name.to_owned(), pos);
        self.entries.insert(pos, name.to_owned());
        (pos.0, pos.1, true)
    }
}
fn load_tiles(name: &str) -> HashMap<String, (u32, u32)> {
    let reg = Regex::new(r"(\d+) (\d+) (.+?)\r?\n").unwrap();
    let name = format!("Tilesheet {}.txt", name);
    let path = Path::new(r"work/tilesheets").join(name);
    let mut file = match File::open(&path) {
        Ok(x) => x,
        Err(_) => {
            println!("No tilesheet found. Creating new tilesheet.");
            return HashMap::new();
        }
    };
    let mut data = String::new();
    file.read_to_string(&mut data).unwrap();
    reg.captures_iter(&data).map(|cap| {
        let x = cap.at(1).unwrap().parse().unwrap();
        let y = cap.at(2).unwrap().parse().unwrap();
        let name = cap.at(3).unwrap().to_owned();
        (name, (x, y))
    }).collect()
}
fn load_entries(tiles: &HashMap<String, (u32, u32)>) -> HashMap<(u32, u32), String> {
    tiles.iter().map(|(key, value)| (value.clone(), key.clone())).collect()
}
fn load_tilesheet(name: &str, size: u32) -> Tilesheet {
    let name = format!("Tilesheet {} {}.png", name, size);
    let path = Path::new(r"work/tilesheets").join(name);
    let img = match image::open(&path) {
        Ok(img) => img.to_rgba(),
        Err(_) => ImageBuffer::new(size, size),
    };
    Tilesheet { size: size, img: img }
}
fn load_tilesheets(name: &str, sizes: &[u32]) -> Vec<Tilesheet> {
    sizes.iter().map(|&size| load_tilesheet(name, size)).collect()
}
pub fn update_tilesheet(name: &str, sizes: &[u32], overwrite: bool) {
    println!("Loading tilesheet");
    let mut manager = TilesheetManager::new(name, sizes);
    println!("Updating tilesheet");
    if overwrite {
        manager.clear_unused();
    }
    manager.update();
    println!("Saving tilesheet");
    manager.save();
    println!("Done");
}
<commit_msg>Restored optipng crap after a bit of hair pulling.<commit_after>// Copyright © 2014, Peter Atashian

use image::{self, GenericImage, ImageBuffer, Pixel, RgbaImage};
use regex::{Regex};
use std::borrow::{ToOwned};
use std::cmp::{max};
use std::collections::{HashMap, HashSet};
use std::fs::{File, walk_dir};
use std::io::prelude::*;
use std::io::{BufWriter};
use std::process::{Command, Stdio};
use std::mem::{swap};
use std::path::{Path};
use {FloatImage, decode_srgb, encode_srgb, resize, save};

struct Tilesheet {
    size: u32,
    img: RgbaImage,
}
impl Tilesheet {
    fn grow(&mut self, w: u32, h: u32) {
        let mut img = ImageBuffer::new(w, h);
        for (x, y, &pix) in self.img.enumerate_pixels() {
            img.put_pixel(x, y, pix);
        }
        swap(&mut self.img, &mut img);
    }
    fn insert(&mut self, x: u32, y: u32, img: &FloatImage) {
        let (width, height) = img.dimensions();
        assert!(width == height);
        let img = resize(img, self.size, self.size);
        let img = encode_srgb(&img);
        let (w, h) = self.img.dimensions();
        if (x + 1) * self.size > w || (y + 1) * self.size > h {
            let (nw, nh) = (max((x + 1) * self.size, w), max((y + 1) * self.size, h));
            self.grow(nw, nh)
        }
        let (x, y) = (x * self.size, y * self.size);
        for (xx, yy, &pix) in img.enumerate_pixels() {
            self.img.put_pixel(x + xx, y + yy, pix);
        }
    }
}
struct TilesheetManager {
    name: String,
    lookup: HashMap<String, (u32, u32)>,
    entries: HashMap<(u32, u32), String>,
    tilesheets: Vec<Tilesheet>,
    next: (u32, u32),
}
impl TilesheetManager {
    fn new(name: &str, sizes: &[u32]) -> TilesheetManager {
        let tilesheets = load_tilesheets(name, sizes);
        let lookup = load_tiles(name);
        let entries = load_entries(&lookup);
        TilesheetManager {
            name: name.to_owned(),
            lookup: lookup,
            entries: entries,
            tilesheets: tilesheets,
            next: (0, 0),
        }
    }
    fn update(&mut self) {
        let path = Path::new(r"work/tilesheets").join(&self.name);
        let mut file = File::create(&Path::new(r"work/tilesheets/Added.txt")).unwrap();
        let renames = if let Ok(mut file) = File::open(&path.join("renames.txt")) {
            let reg = Regex::new("(.*)=(.*)").unwrap();
            let mut s = String::new();
            file.read_to_string(&mut s).unwrap();
            s.lines().map(|line| {
                let cap = reg.captures(line).unwrap();
                (cap.at(1).unwrap().to_owned(), cap.at(2).unwrap().to_owned())
            }).collect()
        } else {
            HashMap::new()
        };
        for entry in walk_dir(&path).unwrap() {
            let path = entry.unwrap().path();
            if !path.is_file() { continue }
            if path.extension().and_then(|x| x.to_str()) != Some("png") { continue }
            let name = path.file_stem().unwrap().to_str().unwrap();
            let name = if let Some(r) = renames.get(name) { &**r } else { name };
            if name.contains(&['_', '[', ']'][..]) { panic!("Illegal name: {:?}", name) }
            let img = image::open(&path).unwrap().to_rgba();
            let img = decode_srgb(&img);
            let (x, y, new) = self.lookup(name);
            if new {
                writeln!(&mut file, "{} {} {}", x, y, name).unwrap();
            }
            for tilesheet in self.tilesheets.iter_mut() {
                tilesheet.insert(x, y, &img);
            }
        }
    }
    fn clear_unused(&mut self) {
        let path = Path::new(r"work/tilesheets").join(&self.name);
        let names: HashSet<_> = walk_dir(&path).unwrap().filter_map(|entry| {
            let path = match entry {
                Ok(x) => x.path(),
                Err(_) => return None,
            };
            if !path.is_file() { None }
            else if path.extension().and_then(|x| x.to_str()) != Some("png") { None }
            else { Some(path.file_stem().unwrap().to_str().unwrap().to_owned()) }
        }).collect();
        let mut file = File::create(&Path::new(r"work/tilesheets/Deleted.txt")).unwrap();
        let lookup = self.lookup.drain().filter(|&(ref name, _)| {
            if !names.contains(name) {
                writeln!(&mut file, "{}", name).unwrap();
                false
            } else { true }
        }).collect();
        let entries = self.entries.drain().filter(|&(_, ref name)| {
            names.contains(name)
        }).collect();
        self.lookup = lookup;
        self.entries = entries;
    }
    fn save(&self) {
        let _optipng = self.tilesheets.iter().map(|tilesheet| {
            let name = format!("Tilesheet {} {}.png", self.name, tilesheet.size);
            let path = Path::new(r"work/tilesheets").join(name);
            save(&tilesheet.img, &path);
            Command::new("optipng").arg(path).stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null()).spawn().unwrap()
        }).collect::<Vec<_>>();
        let name = format!("Tilesheet {}.txt", self.name);
        let path = Path::new(r"work/tilesheets").join(name);
        let mut file = BufWriter::new(File::create(&path).unwrap());
        let mut stuff = self.entries.iter().map(|(&(x, y), tile)| (x, y, tile)).collect::<Vec<_>>();
        stuff.sort_by(|a, b| if a.1 == b.1 { a.0.cmp(&b.0) } else { a.1.cmp(&b.1) });
        for &(x, y, tile) in stuff.iter() {
            (writeln!(&mut file, "{} {} {}", x, y, tile)).unwrap();
        }
        println!("Waiting for optipng to finish");
    }
    fn increment(&mut self) {
        self.next.1 += 1;
        if self.next.1 > self.next.0 * 2 {
            self.next.0 += 1;
            self.next.1 = 0;
        }
    }
    fn next_pos(&self) -> (u32, u32) {
        if self.next.1 < self.next.0 {
            (self.next.1, self.next.0)
        } else {
            (self.next.0, self.next.1 - self.next.0)
        }
    }
    fn lookup(&mut self, name: &str) -> (u32, u32, bool) {
        match self.lookup.get(name) {
            Some(&(x, y)) => return (x, y, false),
            None => (),
        }
        while self.entries.get(&self.next_pos()).is_some() {
            self.increment();
        }
        let pos = self.next_pos();
        self.lookup.insert(name.to_owned(), pos);
        self.entries.insert(pos, name.to_owned());
        (pos.0, pos.1, true)
    }
}
fn load_tiles(name: &str) -> HashMap<String, (u32, u32)> {
    let reg = Regex::new(r"(\d+) (\d+) (.+?)\r?\n").unwrap();
    let name = format!("Tilesheet {}.txt", name);
    let path = Path::new(r"work/tilesheets").join(name);
    let mut file = match File::open(&path) {
        Ok(x) => x,
        Err(_) => {
            println!("No tilesheet found. Creating new tilesheet.");
            return HashMap::new();
        }
    };
    let mut data = String::new();
    file.read_to_string(&mut data).unwrap();
    reg.captures_iter(&data).map(|cap| {
        let x = cap.at(1).unwrap().parse().unwrap();
        let y = cap.at(2).unwrap().parse().unwrap();
        let name = cap.at(3).unwrap().to_owned();
        (name, (x, y))
    }).collect()
}
fn load_entries(tiles: &HashMap<String, (u32, u32)>) -> HashMap<(u32, u32), String> {
    tiles.iter().map(|(key, value)| (value.clone(), key.clone())).collect()
}
fn load_tilesheet(name: &str, size: u32) -> Tilesheet {
    let name = format!("Tilesheet {} {}.png", name, size);
    let path = Path::new(r"work/tilesheets").join(name);
    let img = match image::open(&path) {
        Ok(img) => img.to_rgba(),
        Err(_) => ImageBuffer::new(size, size),
    };
    Tilesheet { size: size, img: img }
}
fn load_tilesheets(name: &str, sizes: &[u32]) -> Vec<Tilesheet> {
    sizes.iter().map(|&size| load_tilesheet(name, size)).collect()
}
pub fn update_tilesheet(name: &str, sizes: &[u32], overwrite: bool) {
    println!("Loading tilesheet");
    let mut manager = TilesheetManager::new(name, sizes);
    println!("Updating tilesheet");
    if overwrite {
        manager.clear_unused();
    }
    manager.update();
    println!("Saving tilesheet");
    manager.save();
    println!("Done");
}
<|endoftext|>


<commit_before>
/// Ensures alignment of at least 16 bytes.
#[repr(align(16))]
pub struct Align16<T>(pub T);

/// Ensures alignment of at least 512 bytes.
#[repr(align(512))]
pub struct Align512<T>(pub T);

/// Ensures alignment of at least 4K bytes.
#[repr(align(4096))]
pub struct Align4K<T>(pub T);
<commit_msg>AlignTo utility (#152)<commit_after>
/// Ensures alignment of at least 16 bytes.
#[repr(align(16))]
pub struct Align16<T>(pub T);

/// Ensures alignment of at least 512 bytes.
#[repr(align(512))]
pub struct Align512<T>(pub T);

/// Ensures alignment of at least 4K bytes.
#[repr(align(4096))]
pub struct Align4K<T>(pub T);

/// Helper to implement generic alignment operator.
pub trait AlignTo {
	fn align_to(self, align: Self) -> Self;
}

macro_rules! impl_align_to {
	($ty:ty) => {
		impl AlignTo for $ty {
			fn align_to(self, align: $ty) -> $ty {
				debug_assert!(align.is_power_of_two());
				(self.wrapping_sub(1) & !(align - 1)).wrapping_add(align)
			}
		}
	};
}
impl_align_to!(u8);
impl_align_to!(u16);
impl_align_to!(u32);
impl_align_to!(u64);
impl_align_to!(u128);
impl_align_to!(usize);

/// Aligns the given value to a multiple of the align value.
///
/// Debug asserts that align is a power of two, otherwise calculates an incorrect result.
pub fn align_to<T: AlignTo>(value: T, align: T) -> T {
	value.align_to(align)
}

#[test]
fn test_align_to() {
	assert_eq!(0, align_to(0_u32, 256_u32));
	assert_eq!(0, align_to(!0_u32, 256_u32));
	assert_eq!(128, align_to(65_u32, 64_u32));
	assert_eq!(64, align_to(64_u32, 64_u32));
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::clone::Clone;

use std::fmt;

// TODO: we can get rid of a lot of these `pub`s by making `Assoc` iterable

// Potential optimization: replace a run of ten nodes with a `HashMap`.
// Recursively replace runs of those, too...

// this is a functional data structure; dropping it on the floor is usually bad
#[must_use]
#[derive(PartialEq, Eq)]
pub struct Assoc<K: PartialEq, V> {
    pub n: Option<Rc<AssocNode<K, V>>>
}

impl<K : PartialEq + Clone, V: Clone> Clone for Assoc<K, V> {
    fn clone(&self) -> Assoc<K, V> {
        self.map(&|rc| rc)
    }
}

#[derive(PartialEq, Eq, Clone)]
pub struct AssocNode<K : PartialEq, V> {
    pub k: K,
    pub v: V,
    pub next: Assoc<K,V>
}

impl<K : PartialEq, V> Assoc<K, V> {
    pub fn find<'assoc, 'f>(&'assoc self, target: &'f K) -> Option<&'assoc V> {
        match self.n {
            None => None,
            Some(ref node) => {
                if (*node).k == *target {
                    Some(&node.v)
                } else {
                    (*node).next.find(target)
                }
            }
        }
    }

    pub fn set(&self, k: K, v: V) -> Assoc<K, V> {
        Assoc{
            n: Some(Rc::new(AssocNode {
                k: k, v: v, next: Assoc { n: self.n.clone() }
        }))}
    }

    pub fn new() -> Assoc<K, V> {
        Assoc{ n: None }
    }

    pub fn iter_keys<'assoc>(&'assoc self) -> KeyIter<'assoc, K, V> {
        KeyIter{ cur: self }
    }

    pub fn iter_values<'assoc>(&'assoc self) -> ValueIter<'assoc, K, V> {
        ValueIter{ cur: self }
    }

}

impl<K: PartialEq + fmt::Debug, V: fmt::Debug> Assoc<K, V> {
    pub fn find_or_panic<'assoc, 'f>(&'assoc self, target: &'f K) -> &'assoc V {
        match self.find(target) {
            None => {
                panic!("{:?} not found in {:?}", target, self)
            },
            Some(ref v) => v
        }
    }
}

impl<K : PartialEq + fmt::Debug, V : fmt::Debug> fmt::Debug for Assoc<K, V> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "<|"));
        let mut cur = &self.n;
        let mut first = true;
        while let &Some(ref node) = cur {
            if !first { try!(write!(f, ", ")); }
            try!(write!(f, "{:?} => {:?}", node.k, node.v));
            first = false;
            cur = &node.next.n;
        }
        write!(f, "|>")
    }
}

impl<K : PartialEq + Clone, V : Clone> Assoc<K, V> {

    pub fn set_assoc(&self, other: &Assoc<K, V>) -> Assoc<K, V> {
        match other.n {
            None => (*self).clone(),
            Some(ref node) => {
                self.set_assoc(&node.next).set(node.k.clone(), node.v.clone())
            }
        }
    }

    pub fn map<NewV>(&self, f: &Fn(V) -> NewV) -> Assoc<K, NewV> {
        match self.n {
            None => Assoc{ n: None },
            Some(ref node) => {
                Assoc{
                    n: Some(Rc::new(AssocNode {
                        k: node.k.clone(), v: f(node.v.clone()),
                        next: node.next.map(f)
                    }))
                }
            }
        }
    }
}

pub struct KeyIter<'assoc, K: PartialEq + 'assoc, V: 'assoc> {
    cur: &'assoc Assoc<K, V>
}

impl<'assoc, K: PartialEq, V> Iterator for KeyIter<'assoc, K, V> {
    type Item = &'assoc K;
    fn next(&mut self) -> Option<&'assoc K> {
        match self.cur.n {
            None => None,
            Some(ref node) => {
                self.cur = &(*node).next;
                Some(&(*node).k)
            }
        }
    }
}

pub struct ValueIter<'assoc, K: PartialEq + 'assoc, V: 'assoc> {
    cur: &'assoc Assoc<K, V>
}

impl<'assoc, K: PartialEq, V> Iterator for ValueIter<'assoc, K, V> {
    type Item = &'assoc V;
    fn next(&mut self) -> Option<&'assoc V> {
        match self.cur.n {
            None => None,
            Some(ref node) => {
                self.cur = &(*node).next;
                Some(&(*node).v)
            }
        }
    }
}

#[test]
fn test_assoc() {
    let mt : Assoc<i32, i32> = Assoc::new();
    let a1 = mt.set(5,6);
    let a2 = a1.set(6,7);
    let a_override = a2.set(5,500);

    assert_eq!(mt.find(&5), None);
    assert_eq!(a1.find(&6), None);
    assert_eq!(a2.find(&999), None);
    assert_eq!(a_override.find(&999), None);
    assert_eq!(a1.find(&5), Some(&6));
    assert_eq!(a2.find(&5), Some(&6));
    assert_eq!(a2.find(&6), Some(&7));
    assert_eq!(a2.find(&5), Some(&6));
    assert_eq!(a_override.find(&5), Some(&500));
    assert_eq!(a_override.find(&6), Some(&7));
}
<commit_msg>Make PartialEq order-independent on `Assoc`s, and make iterators skip overridden elements.<commit_after>use std::rc::Rc;
use std::clone::Clone;

use std::fmt;

// TODO: we can get rid of a lot of these `pub`s by making `Assoc` iterable

// Potential optimization: replace a run of ten nodes with a `HashMap`.
// Recursively replace runs of those, too...

// this is a functional data structure; dropping it on the floor is usually bad
#[must_use]
pub struct Assoc<K: PartialEq, V> {
    pub n: Option<Rc<AssocNode<K, V>>>
}

impl<K : PartialEq + Clone, V: Clone> Clone for Assoc<K, V> {
    fn clone(&self) -> Assoc<K, V> {
        self.map(&|rc| rc)
    }
}

impl <K : PartialEq + Clone, V: PartialEq> PartialEq for Assoc<K, V> {
    fn eq(&self, other: &Assoc<K, V>) -> bool {
        for (k, v) in self.iter_pairs() {
            if let Some(other_v) = other.find(k) {
                if !(v == other_v) { return false; }
            } else { return false; }
        }

        for (other_k, other_v) in other.iter_pairs() {
            if let Some(v) = other.find(other_k) {
                if !(v == other_v) { return false; }
            } else { return false; }
        }

        return true;
    }
}

impl <K : PartialEq + Clone, V: PartialEq> Eq for Assoc<K, V> {}

#[derive(Clone)]
pub struct AssocNode<K : PartialEq, V> {
    pub k: K,
    pub v: V,
    pub next: Assoc<K,V>
}

impl<K : PartialEq, V> Assoc<K, V> {
    pub fn find<'assoc, 'f>(&'assoc self, target: &'f K) -> Option<&'assoc V> {
        match self.n {
            None => None,
            Some(ref node) => {
                if (*node).k == *target {
                    Some(&node.v)
                } else {
                    (*node).next.find(target)
                }
            }
        }
    }

    pub fn set(&self, k: K, v: V) -> Assoc<K, V> {
        Assoc{
            n: Some(Rc::new(AssocNode {
                k: k, v: v, next: Assoc { n: self.n.clone() }
        }))}
    }

    pub fn new() -> Assoc<K, V> {
        Assoc{ n: None }
    }

    pub fn iter_pairs<'assoc>(&'assoc self) -> PairIter<'assoc, K, V> {
        PairIter{ seen: Assoc::new(), cur: self }
    }

}

impl<K: PartialEq + Clone, V> Assoc<K,V> {
    pub fn iter_keys<'assoc>(&'assoc self) -> Box<Iterator<Item=K> +'assoc> {
        Box::new(self.iter_pairs().map(|p| (*p.0).clone()))
    }
}

impl<K: PartialEq + Clone, V: Clone> Assoc<K,V> {
    pub fn iter_values<'assoc>(&'assoc self) -> Box<Iterator<Item=V> + 'assoc> {
        Box::new(self.iter_pairs().map(|p| (*p.1).clone()))
    }
}

impl<K: PartialEq + fmt::Debug, V: fmt::Debug> Assoc<K, V> {
    pub fn find_or_panic<'assoc, 'f>(&'assoc self, target: &'f K) -> &'assoc V {
        match self.find(target) {
            None => {
                panic!("{:?} not found in {:?}", target, self)
            },
            Some(ref v) => v
        }
    }
}

impl<K : PartialEq + fmt::Debug, V : fmt::Debug> fmt::Debug for Assoc<K, V> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "<|"));
        let mut cur = &self.n;
        let mut first = true;
        while let &Some(ref node) = cur {
            if !first { try!(write!(f, ", ")); }
            try!(write!(f, "{:?} => {:?}", node.k, node.v));
            first = false;
            cur = &node.next.n;
        }
        write!(f, "|>")
    }
}

impl<K : PartialEq + Clone, V : Clone> Assoc<K, V> {

    pub fn set_assoc(&self, other: &Assoc<K, V>) -> Assoc<K, V> {
        match other.n {
            None => (*self).clone(),
            Some(ref node) => {
                self.set_assoc(&node.next).set(node.k.clone(), node.v.clone())
            }
        }
    }

    pub fn map<NewV>(&self, f: &Fn(V) -> NewV) -> Assoc<K, NewV> {
        match self.n {
            None => Assoc{ n: None },
            Some(ref node) => {
                Assoc{
                    n: Some(Rc::new(AssocNode {
                        k: node.k.clone(), v: f(node.v.clone()),
                        next: node.next.map(f)
                    }))
                }
            }
        }
    }

    /* This isn't right without deduplication before hand...
    pub fn filter(&self, f: &Fn(&V) -> bool) -> Assoc<K, V> {
        match self.n {
            None => Assoc{ n: None },
            Some(ref node) => {
                let v = node.v.clone();
                if f(&v) {
                    Assoc{
                        n: Some(Rc::new(AssocNode {
                            k: node.k.clone(), v: v,
                            next: node.next.filter(f)
                        }))
                    }
                } else {
                    node.next.filter(f)
                }
            }
        }
    }*/
}

pub struct KeyIter<'assoc, K: PartialEq + 'assoc, V: 'assoc> {
    cur: &'assoc Assoc<K, V>
}

impl<'assoc, K: PartialEq, V> Iterator for KeyIter<'assoc, K, V> {
    type Item = &'assoc K;
    fn next(&mut self) -> Option<&'assoc K> {
        match self.cur.n {
            None => None,
            Some(ref node) => {
                self.cur = &(*node).next;
                Some(&(*node).k)
            }
        }
    }
}

pub struct ValueIter<'assoc, K: PartialEq + 'assoc, V: 'assoc> {
    cur: &'assoc Assoc<K, V>
}

impl<'assoc, K: PartialEq, V> Iterator for ValueIter<'assoc, K, V> {
    type Item = &'assoc V;
    fn next(&mut self) -> Option<&'assoc V> {
        match self.cur.n {
            None => None,
            Some(ref node) => {
                self.cur = &(*node).next;
                Some(&(*node).v)
            }
        }
    }
}

pub struct PairIter<'assoc, K: PartialEq + 'assoc, V: 'assoc> {
    seen: Assoc<K, ()>,
    cur: &'assoc Assoc<K, V>
}

impl<'assoc, K: PartialEq + Clone, V> Iterator for PairIter<'assoc, K, V> {
    type Item = (&'assoc K, &'assoc V);
    fn next(&mut self) -> Option<(&'assoc K, &'assoc V)> {
        match self.cur.n {
            None => None,
            Some(ref node) => {
                self.cur = &(*node).next;
                if self.seen.find(&(*node).k).is_none() { // have we done this key already?
                    self.seen = self.seen.set((*node).k.clone(), ());
                    Some((&(*node).k, &(*node).v))
                } else {
                    self.next() // try the next one
                }
            }
        }
    }
}

#[test]
fn test_assoc() {
    let mt : Assoc<i32, i32> = Assoc::new();
    let a1 = mt.set(5,6);
    let a2 = a1.set(6,7);
    let a_override = a2.set(5,500);

    assert_eq!(mt.find(&5), None);
    assert_eq!(a1.find(&6), None);
    assert_eq!(a2.find(&999), None);
    assert_eq!(a_override.find(&999), None);
    assert_eq!(a1.find(&5), Some(&6));
    assert_eq!(a2.find(&5), Some(&6));
    assert_eq!(a2.find(&6), Some(&7));
    assert_eq!(a2.find(&5), Some(&6));
    assert_eq!(a_override.find(&5), Some(&500));
    assert_eq!(a_override.find(&6), Some(&7));
}

#[test]
fn test_assoc_eq() {
    let mt : Assoc<i32, i32> = Assoc::new();
    let a1 = mt.set(5,6);
    let a2 = a1.set(6,7);
    let a_override = a2.set(5,500);

    let a2_opposite = mt.set(6,7).set(5,6);
    let a_override_direct = mt.set(5,500).set(6,7);

    assert_eq!(mt, Assoc::new());
    assert_eq!(a1, a1);
    assert!(a1 != mt);
    assert_eq!(a2, a2);
    assert_eq!(a2, a2_opposite);
    assert_eq!(a_override, a_override_direct);
    assert!(a2 != a_override);
}<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
* __ears__ initialization (optional).
*
* This module provide a unique function to initialize __ears__.
* Use this function in the case of you don't use __ears__ for the first time
* in you program in the main task. This prevent that the context was created and destroyed
* in a another task.
*/

use internal::*;

pub fn ears_init() -> bool {
    match OpenAlData::check_al_context() {
        Ok(_)       => true,
        Err(err)    => { println!("{}", err); false }
    }
}<commit_msg>add doc for ears_init<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/*!
* __ears__ initialization (optional).
*
* This module provide a unique function to initialize __ears__.
* Use this function in the case of you don't use __ears__ for the first time
* in you program in the main task. This prevent that the context was created and destroyed
* in a another task.
*/

use internal::*;

/**
* Initialize the internal context
*
* # Return
* true if initialization is made with success, false otherwise
*/
pub fn ears_init() -> bool {
    match OpenAlData::check_al_context() {
        Ok(_)       => true,
        Err(err)    => { println!("{}", err); false }
    }
}<|endoftext|>


<commit_before>use std::collections::HashMap;
use lexer::{Token, Tokens};
// use constants::KEYWORDS;
use function::{Function, Functions, functions};
use error::EvaluatorError;

type Identifiers = HashMap<String, String>;

pub struct Evaluator {
    identifiers: Identifiers,
    functions: Functions,
}

impl Evaluator {
    pub fn new() -> Evaluator {
        Evaluator {
            identifiers: Identifiers::new(),
            functions: Functions::new(),
        }
    }

    // fn is_keyword(&mut self, identifier: &String) -> bool {
    //     for keyword in KEYWORDS {
    //         if keyword.to_string() == identifier.to_lowercase() {
    //             return true;
    //         }
    //     }
    //     return false;
    // }

    pub fn evaluate(&mut self, tokens: &Tokens) -> Result<Vec<String>, EvaluatorError> {
        let mut result: Vec<String> = Vec::with_capacity(3);
        let mut stack: Vec<i32> = Vec::with_capacity(3);

        for &(position, ref token) in tokens {
            match *token {
                Token::Decimal(ref dec) => {
                    stack.push(dec.parse().unwrap());
                }
                Token::Operator(ref op) => {
                    let function = self.functions.get::<str>(&op).unwrap();
                    if stack.len() >= function.arity {
                        let l = stack.len();
                        let args: Vec<i32> = stack.split_off(l - function.arity);
                        let interm_result = (function.handle)(args).unwrap();
                        stack.push(interm_result.0);
                        result.push(interm_result.1);
                        result.push(interm_result.0.to_string());
                    } else {
                        return Err(EvaluatorError::MissingArgument(position));
                    }
                }
                _ => continue,

            }
        }
        Ok(result)
    }
}

impl Default for Evaluator {
    fn default() -> Evaluator {
        let mut evaluator = Evaluator::new();

        evaluator.functions.insert("~", Function::new(1, Box::new(functions::not)));
        evaluator.functions.insert("^", Function::new(2, Box::new(functions::xor)));
        evaluator.functions.insert("|", Function::new(2, Box::new(functions::or)));
        evaluator.functions.insert("&", Function::new(2, Box::new(functions::and)));
        evaluator.functions.insert("<<", Function::new(2, Box::new(functions::lshift)));
        evaluator.functions.insert(">>", Function::new(2, Box::new(functions::rshift)));

        evaluator
    }
}
<commit_msg>Rename variable to stack_len<commit_after>use std::collections::HashMap;
use lexer::{Token, Tokens};
// use constants::KEYWORDS;
use function::{Function, Functions, functions};
use error::EvaluatorError;

type Identifiers = HashMap<String, String>;

pub struct Evaluator {
    identifiers: Identifiers,
    functions: Functions,
}

impl Evaluator {
    pub fn new() -> Evaluator {
        Evaluator {
            identifiers: Identifiers::new(),
            functions: Functions::new(),
        }
    }

    // fn is_keyword(&mut self, identifier: &String) -> bool {
    //     for keyword in KEYWORDS {
    //         if keyword.to_string() == identifier.to_lowercase() {
    //             return true;
    //         }
    //     }
    //     return false;
    // }

    pub fn evaluate(&mut self, tokens: &Tokens) -> Result<Vec<String>, EvaluatorError> {
        let mut result: Vec<String> = Vec::with_capacity(3);
        let mut stack: Vec<i32> = Vec::with_capacity(3);

        for &(position, ref token) in tokens {
            match *token {
                Token::Decimal(ref dec) => {
                    stack.push(dec.parse().unwrap());
                }
                Token::Operator(ref op) => {
                    let function = self.functions.get::<str>(&op).unwrap();
                    if stack.len() >= function.arity {
                        let stack_len = stack.len();
                        let args: Vec<i32> = stack.split_off(stack_len - function.arity);
                        let interm_result = (function.handle)(args).unwrap();
                        stack.push(interm_result.0);
                        result.push(interm_result.1);
                        result.push(interm_result.0.to_string());
                    } else {
                        return Err(EvaluatorError::MissingArgument(position));
                    }
                }
                _ => continue,

            }
        }
        Ok(result)
    }
}

impl Default for Evaluator {
    fn default() -> Evaluator {
        let mut evaluator = Evaluator::new();

        evaluator.functions.insert("~", Function::new(1, Box::new(functions::not)));
        evaluator.functions.insert("^", Function::new(2, Box::new(functions::xor)));
        evaluator.functions.insert("|", Function::new(2, Box::new(functions::or)));
        evaluator.functions.insert("&", Function::new(2, Box::new(functions::and)));
        evaluator.functions.insert("<<", Function::new(2, Box::new(functions::lshift)));
        evaluator.functions.insert(">>", Function::new(2, Box::new(functions::rshift)));

        evaluator
    }
}
<|endoftext|>


<commit_before>use std::os::raw::{c_char, c_void, c_int};
use std::mem;
use std::default::Default;
use std::fmt;
use ffi;

pub type PmDeviceId = c_int;
pub type PortMidiStream = c_void;
pub type PmMessage = c_int;

pub type PmTimestamp = u32;
pub const PM_NO_DEVICE: PmDeviceId = -1;

#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct PmEvent {
    pub message: PmMessage,
    pub timestamp: PmTimestamp,
}
impl Default for PmEvent {
    fn default() -> Self {
        PmEvent {
            message: 0,
            timestamp: 0,
        }
    }
}

#[repr(C)]
pub struct PmDeviceInfo {
    /// this internal structure version
    pub struct_version: c_int,
    /// underlying MIDI API, e.g. MMSystem or DirectX
    pub interf: *const c_char,
    /// device name, e.g. USB MidiSport 1x1
    pub name: *const c_char,
    /// true iff input is available
    pub input: c_int,
    /// true iff output is available
    pub output: c_int,
    /// used by generic PortMidi code to do error checking on arguments
    pub opened: c_int,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub enum PmError {
    /// "no error" return that also indicates data available
    PmNoError = 0,
    /// "no error" return that also indicates data available
    PmGotData = 1,
    PmHostError = -10000,
    /// out of range or
    /// output device when input is requested or
    /// input device when output is requested or
    /// device is already opened
    PmInvalidDeviceId = -9999,
    PmInsufficientMemory = -9998,
    PmBufferTooSmall = -9997,
    PmBufferOverflow = -9996,
    /// PortMidiStream parameter is NULL or
    /// stream is not opened or
    /// stream is output when input is required or
    /// stream is input when output is required
    PmBadPtr = -9995,
    /// illegal midi data, e.g. missing EOX
    PmBadData = -9994,
    PmInternalError = -9993,
    /// buffer is already as large as it can be
    PmBufferMaxSize = -9992,
}
impl fmt::Display for PmError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { ffi::Pm_GetErrorText(*self) };
        write!(f, "{}", ffi::ptr_to_string(str_ptr).unwrap())
    }
}
pub trait MaybeError<T> {
    fn try_from(err_code: T) -> Result<T, PmError>;
}
impl MaybeError<c_int> for PmError {
    fn try_from(err_code: c_int) -> Result<c_int, PmError> {
        match err_code {
            -10_000...-9992 | 0 | 1 => unsafe { Err(mem::transmute(err_code)) },
            _ => Ok(err_code),
        }
    }
}
<commit_msg>Do not return `PmGotData` as `Err`<commit_after>use std::os::raw::{c_char, c_void, c_int};
use std::mem;
use std::default::Default;
use std::fmt;
use ffi;

pub type PmDeviceId = c_int;
pub type PortMidiStream = c_void;
pub type PmMessage = c_int;

pub type PmTimestamp = u32;
pub const PM_NO_DEVICE: PmDeviceId = -1;

#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct PmEvent {
    pub message: PmMessage,
    pub timestamp: PmTimestamp,
}
impl Default for PmEvent {
    fn default() -> Self {
        PmEvent {
            message: 0,
            timestamp: 0,
        }
    }
}

#[repr(C)]
pub struct PmDeviceInfo {
    /// this internal structure version
    pub struct_version: c_int,
    /// underlying MIDI API, e.g. MMSystem or DirectX
    pub interf: *const c_char,
    /// device name, e.g. USB MidiSport 1x1
    pub name: *const c_char,
    /// true iff input is available
    pub input: c_int,
    /// true iff output is available
    pub output: c_int,
    /// used by generic PortMidi code to do error checking on arguments
    pub opened: c_int,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
pub enum PmError {
    /// "no error" return that also indicates data available
    PmNoError = 0,
    /// "no error" return that also indicates data available
    PmGotData = 1,
    PmHostError = -10000,
    /// out of range or
    /// output device when input is requested or
    /// input device when output is requested or
    /// device is already opened
    PmInvalidDeviceId = -9999,
    PmInsufficientMemory = -9998,
    PmBufferTooSmall = -9997,
    PmBufferOverflow = -9996,
    /// PortMidiStream parameter is NULL or
    /// stream is not opened or
    /// stream is output when input is required or
    /// stream is input when output is required
    PmBadPtr = -9995,
    /// illegal midi data, e.g. missing EOX
    PmBadData = -9994,
    PmInternalError = -9993,
    /// buffer is already as large as it can be
    PmBufferMaxSize = -9992,
}
impl fmt::Display for PmError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str_ptr = unsafe { ffi::Pm_GetErrorText(*self) };
        write!(f, "{}", ffi::ptr_to_string(str_ptr).unwrap())
    }
}
pub trait MaybeError<T> {
    fn try_from(err_code: T) -> Result<T, PmError>;
}
impl MaybeError<c_int> for PmError {
    fn try_from(err_code: c_int) -> Result<c_int, PmError> {
        match err_code {
            -10_000...-9992 | 0 => unsafe { Err(mem::transmute(err_code)) },
            _ => Ok(err_code),
        }
    }
}
<|endoftext|>


<commit_before>use core::num::Wrapping;
use float::Float;

macro_rules! add {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a + b`
        #[allow(unused_parens)]
        #[cfg_attr(not(test), no_mangle)]
        pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty {
            let one = Wrapping(1 as <$ty as Float>::Int);
            let zero = Wrapping(0 as <$ty as Float>::Int);

            let bits =             Wrapping(<$ty>::bits() as <$ty as Float>::Int);
            let significand_bits = Wrapping(<$ty>::significand_bits() as <$ty as Float>::Int);
            let exponent_bits =    bits - significand_bits - one;
            let max_exponent =     (one << exponent_bits.0 as usize) - one;

            let implicit_bit =     one << significand_bits.0 as usize;
            let significand_mask = implicit_bit - one;
            let sign_bit =         one << (significand_bits + exponent_bits).0 as usize;
            let abs_mask =         sign_bit - one;
            let exponent_mask =    abs_mask ^ significand_mask;
            let inf_rep =          exponent_mask;
            let quiet_bit =        implicit_bit >> 1;
            let qnan_rep =         exponent_mask | quiet_bit;

            let mut a_rep = Wrapping(a.repr());
            let mut b_rep = Wrapping(b.repr());
            let a_abs = a_rep & abs_mask;
            let b_abs = b_rep & abs_mask;

            // Detect if a or b is zero, infinity, or NaN.
            if a_abs - one >= inf_rep - one ||
                b_abs - one >= inf_rep - one {
                // NaN + anything = qNaN
                if a_abs > inf_rep {
                    return (<$ty as Float>::from_repr((a_abs | quiet_bit).0));
                }
                // anything + NaN = qNaN
                if b_abs > inf_rep {
                    return (<$ty as Float>::from_repr((b_abs | quiet_bit).0));
                }

                if a_abs == inf_rep {
                    // +/-infinity + -/+infinity = qNaN
                    if (a.repr() ^ b.repr()) == sign_bit.0 {
                        return (<$ty as Float>::from_repr(qnan_rep.0));
                    } else {
                        // +/-infinity + anything remaining = +/- infinity
                        return a;
                    }
                }

                // anything remaining + +/-infinity = +/-infinity
                if b_abs == inf_rep {
                    return b;
                }

                // zero + anything = anything
                if a_abs.0 == 0 {
                    // but we need to get the sign right for zero + zero
                    if b_abs.0 == 0 {
                        return (<$ty as Float>::from_repr(a.repr() & b.repr()));
                    } else {
                        return b;
                    }
                }

                // anything + zero = anything
                if b_abs.0 == 0 {
                     return a;
                }
            }

            // Swap a and b if necessary so that a has the larger absolute value.
            if b_abs > a_abs {
                let temp = a_rep;
                a_rep = b_rep;
                b_rep = temp;
            }

            // Extract the exponent and significand from the (possibly swapped) a and b.
            let mut a_exponent = Wrapping((a_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut b_exponent = Wrapping((b_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut a_significand = a_rep & significand_mask;
            let mut b_significand = b_rep & significand_mask;

            // normalize any denormals, and adjust the exponent accordingly.
            if a_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(a_significand.0);
                a_exponent = Wrapping(exponent);
                a_significand = Wrapping(significand);
            }
            if b_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(b_significand.0);
                b_exponent = Wrapping(exponent);
                b_significand = Wrapping(significand);
            }

            // The sign of the result is the sign of the larger operand, a.  If they
            // have opposite signs, we are performing a subtraction; otherwise addition.
            let result_sign = a_rep & sign_bit;
            let subtraction = ((a_rep ^ b_rep) & sign_bit) != zero;

            // Shift the significands to give us round, guard and sticky, and or in the
            // implicit significand bit.  (If we fell through from the denormal path it
            // was already set by normalize(), but setting it twice won't hurt
            // anything.)
            a_significand = (a_significand | implicit_bit) << 3;
            b_significand = (b_significand | implicit_bit) << 3;

            // Shift the significand of b by the difference in exponents, with a sticky
            // bottom bit to get rounding correct.
            let align = Wrapping((a_exponent - b_exponent).0 as <$ty as Float>::Int);
            if align.0 != 0 {
                if align < bits {
                    let sticky = ((b_significand << (bits - align).0 as usize).0 != 0) as <$ty as Float>::Int;
                    b_significand = (b_significand >> align.0 as usize) | Wrapping(sticky);
                } else {
                    b_significand = one; // sticky; b is known to be non-zero.
                }
            }
            if subtraction {
                a_significand -= b_significand;
                // If a == -b, return +zero.
                if a_significand.0 == 0 {
                    return (<$ty as Float>::from_repr(0));
                }

                // If partial cancellation occured, we need to left-shift the result
                // and adjust the exponent:
                if a_significand < implicit_bit << 3 {
                    let shift = a_significand.0.leading_zeros() as i32
                        - (implicit_bit << 3).0.leading_zeros() as i32;
                    a_significand <<= shift as usize;
                    a_exponent -= Wrapping(shift);
                }
            } else /* addition */ {
                a_significand += b_significand;

                // If the addition carried up, we need to right-shift the result and
                // adjust the exponent:
                if (a_significand & implicit_bit << 4).0 != 0 {
                    let sticky = ((a_significand & one).0 != 0) as <$ty as Float>::Int;
                    a_significand = a_significand >> 1 | Wrapping(sticky);
                    a_exponent += Wrapping(1);
                }
            }

            // If we have overflowed the type, return +/- infinity:
            if a_exponent >= Wrapping(max_exponent.0 as i32) {
                return (<$ty>::from_repr((inf_rep | result_sign).0));
            }

            if a_exponent.0 <= 0 {
                // Result is denormal before rounding; the exponent is zero and we
                // need to shift the significand.
                let shift = Wrapping((Wrapping(1) - a_exponent).0 as <$ty as Float>::Int);
                let sticky = ((a_significand << (bits - shift).0 as usize).0 != 0) as <$ty as Float>::Int;
                a_significand = a_significand >> shift.0 as usize | Wrapping(sticky);
                a_exponent = Wrapping(0);
            }

            // Low three bits are round, guard, and sticky.
            let round_guard_sticky: i32 = (a_significand.0 & 0x7) as i32;

            // Shift the significand into place, and mask off the implicit bit.
            let mut result = a_significand >> 3 & significand_mask;

            // Insert the exponent and sign.
            result |= Wrapping(a_exponent.0 as <$ty as Float>::Int) << significand_bits.0 as usize;
            result |= result_sign;

            // Final rounding.  The result may overflow to infinity, but that is the
            // correct result in that case.
            if round_guard_sticky > 0x4 { result += one; }
            if round_guard_sticky == 0x4 { result += result & one; }
            return (<$ty>::from_repr(result.0));
        }
    }
}

add!(__addsf3: f32);
add!(__adddf3: f64);

// FIXME: Implement these using aliases
#[cfg(target_arch = "arm")]
#[cfg_attr(not(test), no_mangle)]
pub extern fn __aeabi_dadd(a: f64, b: f64) -> f64 {
    __adddf3(a, b)
}

#[cfg(target_arch = "arm")]
#[cfg_attr(not(test), no_mangle)]
pub extern fn __aeabi_fadd(a: f32, b: f32) -> f32 {
    __addsf3(a, b)
}

#[cfg(test)]
mod tests {
    use core::{f32, f64};
    use qc::{U32, U64};
    use float::Float;

    // NOTE The tests below have special handing for NaN values.
    // Because NaN != NaN, the floating-point representations must be used
    // Because there are many diffferent values of NaN, and the implementation
    // doesn't care about calculating the 'correct' one, if both values are NaN
    // the values are considered equivalent.

    // TODO: Add F32/F64 to qc so that they print the right values (at the very least)
    quickcheck! {
        fn addsf3(a: U32, b: U32) -> bool {
            let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
            let x = super::__addsf3(a, b);
            let y = a + b;
            if !(x.is_nan() && y.is_nan()) {
                x.repr() == y.repr()
            } else {
                true
            }
        }

        fn adddf3(a: U64, b: U64) -> bool {
            let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
            let x = super::__adddf3(a, b);
            let y = a + b;
            if !(x.is_nan() && y.is_nan()) {
                x.repr() == y.repr()
            } else {
                true
            }
        }
    }

    // More tests for special float values

    #[test]
    fn test_float_tiny_plus_tiny() {
        let tiny = f32::from_repr(1);
        let r = super::__addsf3(tiny, tiny);
        assert_eq!(r, tiny + tiny);
    }

    #[test]
    fn test_double_tiny_plus_tiny() {
        let tiny = f64::from_repr(1);
        let r = super::__adddf3(tiny, tiny);
        assert_eq!(r, tiny + tiny);
    }

    #[test]
    fn test_float_small_plus_small() {
        let a = f32::from_repr(327);
        let b = f32::from_repr(256);
        let r = super::__addsf3(a, b);
        assert_eq!(r, a + b);
    }

    #[test]
    fn test_double_small_plus_small() {
        let a = f64::from_repr(327);
        let b = f64::from_repr(256);
        let r = super::__adddf3(a, b);
        assert_eq!(r, a + b);
    }

    #[test]
    fn test_float_one_plus_one() {
        let r = super::__addsf3(1f32, 1f32);
        assert_eq!(r, 1f32 + 1f32);
    }

    #[test]
    fn test_double_one_plus_one() {
        let r = super::__adddf3(1f64, 1f64);
        assert_eq!(r, 1f64 + 1f64);
    }

    #[test]
    fn test_float_different_nan() {
        let a = f32::from_repr(1);
        let b = f32::from_repr(0b11111111100100010001001010101010);
        let x = super::__addsf3(a, b);
        let y = a + b;
        if !(x.is_nan() && y.is_nan()) {
            assert_eq!(x.repr(), y.repr());
        }
    }

    #[test]
    fn test_double_different_nan() {
        let a = f64::from_repr(1);
        let b = f64::from_repr(
            0b1111111111110010001000100101010101001000101010000110100011101011);
        let x = super::__adddf3(a, b);
        let y = a + b;
        if !(x.is_nan() && y.is_nan()) {
            assert_eq!(x.repr(), y.repr());
        }
    }

    #[test]
    fn test_float_nan() {
        let r = super::__addsf3(f32::NAN, 1.23);
        assert_eq!(r.repr(), f32::NAN.repr());
    }

    #[test]
    fn test_double_nan() {
        let r = super::__adddf3(f64::NAN, 1.23);
        assert_eq!(r.repr(), f64::NAN.repr());
    }

    #[test]
    fn test_float_inf() {
        let r = super::__addsf3(f32::INFINITY, -123.4);
        assert_eq!(r, f32::INFINITY);
    }

    #[test]
    fn test_double_inf() {
        let r = super::__adddf3(f64::INFINITY, -123.4);
        assert_eq!(r, f64::INFINITY);
    }
}
<commit_msg>Use mem::swap to swap variables<commit_after>use core::num::Wrapping;
use float::Float;

macro_rules! add {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a + b`
        #[allow(unused_parens)]
        #[cfg_attr(not(test), no_mangle)]
        pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty {
            let one = Wrapping(1 as <$ty as Float>::Int);
            let zero = Wrapping(0 as <$ty as Float>::Int);

            let bits =             Wrapping(<$ty>::bits() as <$ty as Float>::Int);
            let significand_bits = Wrapping(<$ty>::significand_bits() as <$ty as Float>::Int);
            let exponent_bits =    bits - significand_bits - one;
            let max_exponent =     (one << exponent_bits.0 as usize) - one;

            let implicit_bit =     one << significand_bits.0 as usize;
            let significand_mask = implicit_bit - one;
            let sign_bit =         one << (significand_bits + exponent_bits).0 as usize;
            let abs_mask =         sign_bit - one;
            let exponent_mask =    abs_mask ^ significand_mask;
            let inf_rep =          exponent_mask;
            let quiet_bit =        implicit_bit >> 1;
            let qnan_rep =         exponent_mask | quiet_bit;

            let mut a_rep = Wrapping(a.repr());
            let mut b_rep = Wrapping(b.repr());
            let a_abs = a_rep & abs_mask;
            let b_abs = b_rep & abs_mask;

            // Detect if a or b is zero, infinity, or NaN.
            if a_abs - one >= inf_rep - one ||
                b_abs - one >= inf_rep - one {
                // NaN + anything = qNaN
                if a_abs > inf_rep {
                    return (<$ty as Float>::from_repr((a_abs | quiet_bit).0));
                }
                // anything + NaN = qNaN
                if b_abs > inf_rep {
                    return (<$ty as Float>::from_repr((b_abs | quiet_bit).0));
                }

                if a_abs == inf_rep {
                    // +/-infinity + -/+infinity = qNaN
                    if (a.repr() ^ b.repr()) == sign_bit.0 {
                        return (<$ty as Float>::from_repr(qnan_rep.0));
                    } else {
                        // +/-infinity + anything remaining = +/- infinity
                        return a;
                    }
                }

                // anything remaining + +/-infinity = +/-infinity
                if b_abs == inf_rep {
                    return b;
                }

                // zero + anything = anything
                if a_abs.0 == 0 {
                    // but we need to get the sign right for zero + zero
                    if b_abs.0 == 0 {
                        return (<$ty as Float>::from_repr(a.repr() & b.repr()));
                    } else {
                        return b;
                    }
                }

                // anything + zero = anything
                if b_abs.0 == 0 {
                     return a;
                }
            }

            // Swap a and b if necessary so that a has the larger absolute value.
            if b_abs > a_abs {
                ::core::mem::swap(&mut a_rep, &mut b_rep);
            }

            // Extract the exponent and significand from the (possibly swapped) a and b.
            let mut a_exponent = Wrapping((a_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut b_exponent = Wrapping((b_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut a_significand = a_rep & significand_mask;
            let mut b_significand = b_rep & significand_mask;

            // normalize any denormals, and adjust the exponent accordingly.
            if a_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(a_significand.0);
                a_exponent = Wrapping(exponent);
                a_significand = Wrapping(significand);
            }
            if b_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(b_significand.0);
                b_exponent = Wrapping(exponent);
                b_significand = Wrapping(significand);
            }

            // The sign of the result is the sign of the larger operand, a.  If they
            // have opposite signs, we are performing a subtraction; otherwise addition.
            let result_sign = a_rep & sign_bit;
            let subtraction = ((a_rep ^ b_rep) & sign_bit) != zero;

            // Shift the significands to give us round, guard and sticky, and or in the
            // implicit significand bit.  (If we fell through from the denormal path it
            // was already set by normalize(), but setting it twice won't hurt
            // anything.)
            a_significand = (a_significand | implicit_bit) << 3;
            b_significand = (b_significand | implicit_bit) << 3;

            // Shift the significand of b by the difference in exponents, with a sticky
            // bottom bit to get rounding correct.
            let align = Wrapping((a_exponent - b_exponent).0 as <$ty as Float>::Int);
            if align.0 != 0 {
                if align < bits {
                    let sticky = ((b_significand << (bits - align).0 as usize).0 != 0) as <$ty as Float>::Int;
                    b_significand = (b_significand >> align.0 as usize) | Wrapping(sticky);
                } else {
                    b_significand = one; // sticky; b is known to be non-zero.
                }
            }
            if subtraction {
                a_significand -= b_significand;
                // If a == -b, return +zero.
                if a_significand.0 == 0 {
                    return (<$ty as Float>::from_repr(0));
                }

                // If partial cancellation occured, we need to left-shift the result
                // and adjust the exponent:
                if a_significand < implicit_bit << 3 {
                    let shift = a_significand.0.leading_zeros() as i32
                        - (implicit_bit << 3).0.leading_zeros() as i32;
                    a_significand <<= shift as usize;
                    a_exponent -= Wrapping(shift);
                }
            } else /* addition */ {
                a_significand += b_significand;

                // If the addition carried up, we need to right-shift the result and
                // adjust the exponent:
                if (a_significand & implicit_bit << 4).0 != 0 {
                    let sticky = ((a_significand & one).0 != 0) as <$ty as Float>::Int;
                    a_significand = a_significand >> 1 | Wrapping(sticky);
                    a_exponent += Wrapping(1);
                }
            }

            // If we have overflowed the type, return +/- infinity:
            if a_exponent >= Wrapping(max_exponent.0 as i32) {
                return (<$ty>::from_repr((inf_rep | result_sign).0));
            }

            if a_exponent.0 <= 0 {
                // Result is denormal before rounding; the exponent is zero and we
                // need to shift the significand.
                let shift = Wrapping((Wrapping(1) - a_exponent).0 as <$ty as Float>::Int);
                let sticky = ((a_significand << (bits - shift).0 as usize).0 != 0) as <$ty as Float>::Int;
                a_significand = a_significand >> shift.0 as usize | Wrapping(sticky);
                a_exponent = Wrapping(0);
            }

            // Low three bits are round, guard, and sticky.
            let round_guard_sticky: i32 = (a_significand.0 & 0x7) as i32;

            // Shift the significand into place, and mask off the implicit bit.
            let mut result = a_significand >> 3 & significand_mask;

            // Insert the exponent and sign.
            result |= Wrapping(a_exponent.0 as <$ty as Float>::Int) << significand_bits.0 as usize;
            result |= result_sign;

            // Final rounding.  The result may overflow to infinity, but that is the
            // correct result in that case.
            if round_guard_sticky > 0x4 { result += one; }
            if round_guard_sticky == 0x4 { result += result & one; }
            return (<$ty>::from_repr(result.0));
        }
    }
}

add!(__addsf3: f32);
add!(__adddf3: f64);

// FIXME: Implement these using aliases
#[cfg(target_arch = "arm")]
#[cfg_attr(not(test), no_mangle)]
pub extern fn __aeabi_dadd(a: f64, b: f64) -> f64 {
    __adddf3(a, b)
}

#[cfg(target_arch = "arm")]
#[cfg_attr(not(test), no_mangle)]
pub extern fn __aeabi_fadd(a: f32, b: f32) -> f32 {
    __addsf3(a, b)
}

#[cfg(test)]
mod tests {
    use core::{f32, f64};
    use qc::{U32, U64};
    use float::Float;

    // NOTE The tests below have special handing for NaN values.
    // Because NaN != NaN, the floating-point representations must be used
    // Because there are many diffferent values of NaN, and the implementation
    // doesn't care about calculating the 'correct' one, if both values are NaN
    // the values are considered equivalent.

    // TODO: Add F32/F64 to qc so that they print the right values (at the very least)
    quickcheck! {
        fn addsf3(a: U32, b: U32) -> bool {
            let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
            let x = super::__addsf3(a, b);
            let y = a + b;
            if !(x.is_nan() && y.is_nan()) {
                x.repr() == y.repr()
            } else {
                true
            }
        }

        fn adddf3(a: U64, b: U64) -> bool {
            let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
            let x = super::__adddf3(a, b);
            let y = a + b;
            if !(x.is_nan() && y.is_nan()) {
                x.repr() == y.repr()
            } else {
                true
            }
        }
    }

    // More tests for special float values

    #[test]
    fn test_float_tiny_plus_tiny() {
        let tiny = f32::from_repr(1);
        let r = super::__addsf3(tiny, tiny);
        assert_eq!(r, tiny + tiny);
    }

    #[test]
    fn test_double_tiny_plus_tiny() {
        let tiny = f64::from_repr(1);
        let r = super::__adddf3(tiny, tiny);
        assert_eq!(r, tiny + tiny);
    }

    #[test]
    fn test_float_small_plus_small() {
        let a = f32::from_repr(327);
        let b = f32::from_repr(256);
        let r = super::__addsf3(a, b);
        assert_eq!(r, a + b);
    }

    #[test]
    fn test_double_small_plus_small() {
        let a = f64::from_repr(327);
        let b = f64::from_repr(256);
        let r = super::__adddf3(a, b);
        assert_eq!(r, a + b);
    }

    #[test]
    fn test_float_one_plus_one() {
        let r = super::__addsf3(1f32, 1f32);
        assert_eq!(r, 1f32 + 1f32);
    }

    #[test]
    fn test_double_one_plus_one() {
        let r = super::__adddf3(1f64, 1f64);
        assert_eq!(r, 1f64 + 1f64);
    }

    #[test]
    fn test_float_different_nan() {
        let a = f32::from_repr(1);
        let b = f32::from_repr(0b11111111100100010001001010101010);
        let x = super::__addsf3(a, b);
        let y = a + b;
        if !(x.is_nan() && y.is_nan()) {
            assert_eq!(x.repr(), y.repr());
        }
    }

    #[test]
    fn test_double_different_nan() {
        let a = f64::from_repr(1);
        let b = f64::from_repr(
            0b1111111111110010001000100101010101001000101010000110100011101011);
        let x = super::__adddf3(a, b);
        let y = a + b;
        if !(x.is_nan() && y.is_nan()) {
            assert_eq!(x.repr(), y.repr());
        }
    }

    #[test]
    fn test_float_nan() {
        let r = super::__addsf3(f32::NAN, 1.23);
        assert_eq!(r.repr(), f32::NAN.repr());
    }

    #[test]
    fn test_double_nan() {
        let r = super::__adddf3(f64::NAN, 1.23);
        assert_eq!(r.repr(), f64::NAN.repr());
    }

    #[test]
    fn test_float_inf() {
        let r = super::__addsf3(f32::INFINITY, -123.4);
        assert_eq!(r, f32::INFINITY);
    }

    #[test]
    fn test_double_inf() {
        let r = super::__adddf3(f64::INFINITY, -123.4);
        assert_eq!(r, f64::INFINITY);
    }
}
<|endoftext|>


<commit_before>//! Functions related to formatting and printing lines from a `Tokenizer`.

use crate::{extensions::FindFrom, types::LineType};

use log::debug;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// Represents a snippet from a page of a specific highlighting class.
pub enum PageSnippet<'a> {
    CommandName(&'a str),
    Variable(&'a str),
    NormalCode(&'a str),
    Description(&'a str),
    Text(&'a str),
    Linebreak,
}

impl<'a> PageSnippet<'a> {
    pub fn is_empty(&self) -> bool {
        use PageSnippet::*;

        match self {
            CommandName(s) | Variable(s) | NormalCode(s) | Description(s) | Text(s) => s.is_empty(),
            Linebreak => false,
        }
    }
}

/// Parse the content of each line yielded by `lines` and yield `HighLightingSnippet`s accordingly.
pub fn highlight_lines<L, F, E>(
    lines: L,
    process_snippet: &mut F,
    keep_empty_lines: bool,
) -> Result<(), E>
where
    L: Iterator<Item = LineType>,
    F: for<'snip> FnMut(PageSnippet<'snip>) -> Result<(), E>,
{
    let mut command = String::new();
    for line in lines {
        match line {
            LineType::Empty => {
                if keep_empty_lines {
                    process_snippet(PageSnippet::Linebreak)?;
                }
            }
            LineType::Title(title) => {
                debug!("Ignoring title");

                // This is safe as long as the parsed title is only the command,
                // and the iterator yields values in order of appearance.
                command = title;
                debug!("Detected command name: {}", &command);
            }
            LineType::Description(text) => process_snippet(PageSnippet::Description(&text))?,
            LineType::ExampleText(text) => process_snippet(PageSnippet::Text(&text))?,
            LineType::ExampleCode(text) => {
                process_snippet(PageSnippet::NormalCode("      "))?;
                highlight_code(&command, &text, process_snippet)?;
                process_snippet(PageSnippet::Linebreak)?;
            }

            LineType::Other(text) => debug!("Unknown line type: {:?}", text),
        }
    }
    process_snippet(PageSnippet::Linebreak)?;
    Ok(())
}

/// Highlight code examples including user variables in {{ curly braces }}.
fn highlight_code<'a, E>(
    command: &'a str,
    text: &'a str,
    process_snippet: &mut impl FnMut(PageSnippet<'a>) -> Result<(), E>,
) -> Result<(), E> {
    let variable_splits = text
        .split("}}")
        .map(|s| s.split_once("{{").unwrap_or((s, "")));
    for (code_segment, variable) in variable_splits {
        highlight_code_segment(command, code_segment, process_snippet)?;
        process_snippet(PageSnippet::Variable(variable))?;
    }
    Ok(())
}

/// Yields `NormalCode` and `CommandName` in alternating order according to the occurences of
/// `command_name` in `segment`. Variables are not detected here, see `highlight_code`
/// instead.
fn highlight_code_segment<'a, E>(
    command_name: &'a str,
    mut segment: &'a str,
    process_snippet: &mut impl FnMut(PageSnippet<'a>) -> Result<(), E>,
) -> Result<(), E> {
    if !command_name.is_empty() {
        let mut search_start = 0;
        while let Some(match_start) = segment.find_from(command_name, search_start) {
            let match_end = match_start + command_name.len();
            if is_freestanding_substring(segment, (match_start, match_end)) {
                process_snippet(PageSnippet::NormalCode(&segment[..match_start]))?;
                process_snippet(PageSnippet::CommandName(command_name))?;
                segment = &segment[match_end..];
                search_start = 0;
            } else {
                search_start = segment[match_start..]
                    .char_indices()
                    .nth(1)
                    .map_or(segment.len(), |(i, _)| match_start + i);
            }
        }
    }
    process_snippet(PageSnippet::NormalCode(segment))?;
    Ok(())
}

/// Checks whether the characters right before and after the substring (given by half-open index interval) are whitespace (if they exist).
fn is_freestanding_substring(surrouding: &str, substring: (usize, usize)) -> bool {
    let (start, end) = substring;
    // "okay" meaning <exists and is whitespace> or <doesn't exist>
    let char_before_is_okay = surrouding[..start]
        .chars()
        .last()
        .filter(|prev_char| !prev_char.is_whitespace())
        .is_none();
    let char_after_is_okay = surrouding[end..]
        .chars()
        .next()
        .filter(|next_char| !next_char.is_whitespace())
        .is_none();
    char_before_is_okay && char_after_is_okay
}

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

    #[test]
    fn test_is_freestanding_substring() {
        assert!(is_freestanding_substring("I love tldr", (0, 1)));
        assert!(is_freestanding_substring("I love tldr", (2, 6)));
        assert!(is_freestanding_substring("I love tldr", (7, 11)));

        assert!(is_freestanding_substring("tldr", (0, 4)));
        assert!(is_freestanding_substring("tldr ", (0, 4)));
        assert!(is_freestanding_substring(" tldr", (1, 5)));
        assert!(is_freestanding_substring(" tldr ", (1, 5)));

        assert!(!is_freestanding_substring("tldr", (1, 3)));
        assert!(!is_freestanding_substring("tldr ", (1, 4)));
        assert!(!is_freestanding_substring(" tldr", (1, 4)));

        assert!(is_freestanding_substring(
            " épicé ",
            (1, " épicé".len()) // note the missing trailing space
        ));
        assert!(!is_freestanding_substring(
            " épicé ",
            (1, " épic".len()) // note the missing trailing space and character
        ));
    }

    fn run<'a>(cmd: &'a str, segment: &'a str) -> Vec<PageSnippet<'a>> {
        let mut yielded = Vec::new();
        let mut process_snippet = |snip: PageSnippet<'a>| {
            if !snip.is_empty() {
                yielded.push(snip);
            }
            Ok::<(), ()>(())
        };

        highlight_code_segment(cmd, segment, &mut process_snippet)
            .expect("highlight code segment failed");
        yielded
    }

    #[test]
    fn test_highlight_code_segment() {
        assert!(run("make", "").is_empty());
        assert_eq!(
            &run("make", "make all CC=clang -q"),
            &[CommandName("make"), NormalCode(" all CC=clang -q")]
        );
        assert_eq!(
            &run("make", "  make money --always-make"),
            &[
                NormalCode("  "),
                CommandName("make"),
                NormalCode(" money --always-make")
            ]
        );
        assert_eq!(
            &run("git commit", "git commit -m 'git commit'"),
            &[CommandName("git commit"), NormalCode(" -m 'git commit'"),]
        );
    }

    #[test]
    fn test_i18n() {
        assert_eq!(
            &run("mäke", "mäke höhlenrätselbücher"),
            &[CommandName("mäke"), NormalCode(" höhlenrätselbücher")]
        );
        assert_eq!(
            &run(
                "Müll",
                "1000 Gründe warum Müll heute größer ist als Müll früher, ärgerlich"
            ),
            &[
                NormalCode("1000 Gründe warum "),
                CommandName("Müll"),
                NormalCode(" heute größer ist als "),
                CommandName("Müll"),
                NormalCode(" früher, ärgerlich")
            ]
        );
        assert_eq!(
            &run(
                "übergang",
                "die Zustandsübergangsfunktion übergang Änderungen",
            ),
            &[
                NormalCode("die Zustandsübergangsfunktion "),
                CommandName("übergang"),
                NormalCode(" Änderungen")
            ],
        );
    }
}
<commit_msg>Add test for hightlighting with empty command (#178)<commit_after>//! Functions related to formatting and printing lines from a `Tokenizer`.

use crate::{extensions::FindFrom, types::LineType};

use log::debug;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// Represents a snippet from a page of a specific highlighting class.
pub enum PageSnippet<'a> {
    CommandName(&'a str),
    Variable(&'a str),
    NormalCode(&'a str),
    Description(&'a str),
    Text(&'a str),
    Linebreak,
}

impl<'a> PageSnippet<'a> {
    pub fn is_empty(&self) -> bool {
        use PageSnippet::*;

        match self {
            CommandName(s) | Variable(s) | NormalCode(s) | Description(s) | Text(s) => s.is_empty(),
            Linebreak => false,
        }
    }
}

/// Parse the content of each line yielded by `lines` and yield `HighLightingSnippet`s accordingly.
pub fn highlight_lines<L, F, E>(
    lines: L,
    process_snippet: &mut F,
    keep_empty_lines: bool,
) -> Result<(), E>
where
    L: Iterator<Item = LineType>,
    F: for<'snip> FnMut(PageSnippet<'snip>) -> Result<(), E>,
{
    let mut command = String::new();
    for line in lines {
        match line {
            LineType::Empty => {
                if keep_empty_lines {
                    process_snippet(PageSnippet::Linebreak)?;
                }
            }
            LineType::Title(title) => {
                debug!("Ignoring title");

                // This is safe as long as the parsed title is only the command,
                // and the iterator yields values in order of appearance.
                command = title;
                debug!("Detected command name: {}", &command);
            }
            LineType::Description(text) => process_snippet(PageSnippet::Description(&text))?,
            LineType::ExampleText(text) => process_snippet(PageSnippet::Text(&text))?,
            LineType::ExampleCode(text) => {
                process_snippet(PageSnippet::NormalCode("      "))?;
                highlight_code(&command, &text, process_snippet)?;
                process_snippet(PageSnippet::Linebreak)?;
            }

            LineType::Other(text) => debug!("Unknown line type: {:?}", text),
        }
    }
    process_snippet(PageSnippet::Linebreak)?;
    Ok(())
}

/// Highlight code examples including user variables in {{ curly braces }}.
fn highlight_code<'a, E>(
    command: &'a str,
    text: &'a str,
    process_snippet: &mut impl FnMut(PageSnippet<'a>) -> Result<(), E>,
) -> Result<(), E> {
    let variable_splits = text
        .split("}}")
        .map(|s| s.split_once("{{").unwrap_or((s, "")));
    for (code_segment, variable) in variable_splits {
        highlight_code_segment(command, code_segment, process_snippet)?;
        process_snippet(PageSnippet::Variable(variable))?;
    }
    Ok(())
}

/// Yields `NormalCode` and `CommandName` in alternating order according to the occurences of
/// `command_name` in `segment`. Variables are not detected here, see `highlight_code`
/// instead.
fn highlight_code_segment<'a, E>(
    command_name: &'a str,
    mut segment: &'a str,
    process_snippet: &mut impl FnMut(PageSnippet<'a>) -> Result<(), E>,
) -> Result<(), E> {
    if !command_name.is_empty() {
        let mut search_start = 0;
        while let Some(match_start) = segment.find_from(command_name, search_start) {
            let match_end = match_start + command_name.len();
            if is_freestanding_substring(segment, (match_start, match_end)) {
                process_snippet(PageSnippet::NormalCode(&segment[..match_start]))?;
                process_snippet(PageSnippet::CommandName(command_name))?;
                segment = &segment[match_end..];
                search_start = 0;
            } else {
                search_start = segment[match_start..]
                    .char_indices()
                    .nth(1)
                    .map_or(segment.len(), |(i, _)| match_start + i);
            }
        }
    }
    process_snippet(PageSnippet::NormalCode(segment))?;
    Ok(())
}

/// Checks whether the characters right before and after the substring (given by half-open index interval) are whitespace (if they exist).
fn is_freestanding_substring(surrouding: &str, substring: (usize, usize)) -> bool {
    let (start, end) = substring;
    // "okay" meaning <exists and is whitespace> or <doesn't exist>
    let char_before_is_okay = surrouding[..start]
        .chars()
        .last()
        .filter(|prev_char| !prev_char.is_whitespace())
        .is_none();
    let char_after_is_okay = surrouding[end..]
        .chars()
        .next()
        .filter(|next_char| !next_char.is_whitespace())
        .is_none();
    char_before_is_okay && char_after_is_okay
}

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

    #[test]
    fn test_is_freestanding_substring() {
        assert!(is_freestanding_substring("I love tldr", (0, 1)));
        assert!(is_freestanding_substring("I love tldr", (2, 6)));
        assert!(is_freestanding_substring("I love tldr", (7, 11)));

        assert!(is_freestanding_substring("tldr", (0, 4)));
        assert!(is_freestanding_substring("tldr ", (0, 4)));
        assert!(is_freestanding_substring(" tldr", (1, 5)));
        assert!(is_freestanding_substring(" tldr ", (1, 5)));

        assert!(!is_freestanding_substring("tldr", (1, 3)));
        assert!(!is_freestanding_substring("tldr ", (1, 4)));
        assert!(!is_freestanding_substring(" tldr", (1, 4)));

        assert!(is_freestanding_substring(
            " épicé ",
            (1, " épicé".len()) // note the missing trailing space
        ));
        assert!(!is_freestanding_substring(
            " épicé ",
            (1, " épic".len()) // note the missing trailing space and character
        ));
    }

    fn run<'a>(cmd: &'a str, segment: &'a str) -> Vec<PageSnippet<'a>> {
        let mut yielded = Vec::new();
        let mut process_snippet = |snip: PageSnippet<'a>| {
            if !snip.is_empty() {
                yielded.push(snip);
            }
            Ok::<(), ()>(())
        };

        highlight_code_segment(cmd, segment, &mut process_snippet)
            .expect("highlight code segment failed");
        yielded
    }

    #[test]
    fn test_highlight_code_segment() {
        assert!(run("make", "").is_empty());
        assert_eq!(
            &run("make", "make all CC=clang -q"),
            &[CommandName("make"), NormalCode(" all CC=clang -q")]
        );
        assert_eq!(
            &run("make", "  make money --always-make"),
            &[
                NormalCode("  "),
                CommandName("make"),
                NormalCode(" money --always-make")
            ]
        );
        assert_eq!(
            &run("git commit", "git commit -m 'git commit'"),
            &[CommandName("git commit"), NormalCode(" -m 'git commit'"),]
        );
    }

    #[test]
    fn test_i18n() {
        assert_eq!(
            &run("mäke", "mäke höhlenrätselbücher"),
            &[CommandName("mäke"), NormalCode(" höhlenrätselbücher")]
        );
        assert_eq!(
            &run(
                "Müll",
                "1000 Gründe warum Müll heute größer ist als Müll früher, ärgerlich"
            ),
            &[
                NormalCode("1000 Gründe warum "),
                CommandName("Müll"),
                NormalCode(" heute größer ist als "),
                CommandName("Müll"),
                NormalCode(" früher, ärgerlich")
            ]
        );
        assert_eq!(
            &run(
                "übergang",
                "die Zustandsübergangsfunktion übergang Änderungen",
            ),
            &[
                NormalCode("die Zustandsübergangsfunktion "),
                CommandName("übergang"),
                NormalCode(" Änderungen")
            ],
        );
    }

    #[test]
    fn test_empty_command() {
        let segment = "some code";
        let snippets = [NormalCode(segment)];

        assert_eq!(run("", segment), snippets);
        assert_eq!(run(" ", segment), snippets);
        assert_eq!(run("  \t ", segment), snippets);
    }
}
<|endoftext|>


<commit_before>use calx::color;
use calx::Context;
use calx::event;
use calx::key;
use calx::{Fonter, V2};
use world;
use world::action;
use world::action::{Step};
use world::dir6::*;
use worldview;
use sprite::{WorldSprites};

pub struct GameState {
    world_spr: WorldSprites,
}

impl GameState {
    pub fn new(seed: Option<u32>) -> GameState {
        world::init_world(seed);
        GameState {
            world_spr: WorldSprites::new(),
        }
    }

    /// Repaint view, update game world if needed.
    pub fn update(&mut self, ctx: &mut Context) {
        ctx.clear(&color::BLACK);
        let camera = world::camera();
        worldview::draw_world(&camera, ctx);

        // TODO use FOV for sprite draw.
        self.world_spr.draw(|_| true, &camera, ctx);
        self.world_spr.update();

        let fps = 1.0 / ctx.render_duration;
        let _ = write!(&mut ctx.text_writer(V2(0, 8), 0.1, color::LIGHTGREEN)
                       .set_border(color::BLACK),
                       "FPS {}", fps);

        if action::control_state() == action::ReadyToUpdate {
            action::update();
        }
    }

    /// Process a player control keypress.
    pub fn process_key(&mut self, key: key::Key) -> bool {
        if action::control_state() != action::AwaitingInput {
            return false;
        }

        match key {
            key::KeyQ | key::KeyPad7 => { action::input(Step(NorthWest)); }
            key::KeyW | key::KeyPad8 | key::KeyUp => { action::input(Step(North)); }
            key::KeyE | key::KeyPad9 => { action::input(Step(NorthEast)); }
            key::KeyA | key::KeyPad1 => { action::input(Step(SouthWest)); }
            key::KeyS | key::KeyPad2 | key::KeyDown => { action::input(Step(South)); }
            key::KeyD | key::KeyPad3 => { action::input(Step(SouthEast)); }
            _ => { return false; }
        }
        return true;
    }

    pub fn process(&mut self, event: event::Event) -> bool {
        match event {
            event::Render(ctx) => {
                self.update(ctx);
            }
            event::KeyPressed(key::KeyEscape) => {
                return false;
            }
            event::KeyPressed(k) => {
                self.process_key(k);
            }
            _ => ()
        }
        true
    }
}
<commit_msg>Save/load game<commit_after>use std::io::File;
use std::io::fs::PathExtensions;

use calx::color;
use calx::Context;
use calx::event;
use calx::key;
use calx::{Fonter, V2};
use world;
use world::action;
use world::action::{Step};
use world::dir6::*;
use worldview;
use sprite::{WorldSprites};

pub struct GameState {
    world_spr: WorldSprites,
}

impl GameState {
    pub fn new(seed: Option<u32>) -> GameState {
        world::init_world(seed);
        GameState {
            world_spr: WorldSprites::new(),
        }
    }

    /// Repaint view, update game world if needed.
    pub fn update(&mut self, ctx: &mut Context) {
        ctx.clear(&color::BLACK);
        let camera = world::camera();
        worldview::draw_world(&camera, ctx);

        // TODO use FOV for sprite draw.
        self.world_spr.draw(|_| true, &camera, ctx);
        self.world_spr.update();

        let fps = 1.0 / ctx.render_duration;
        let _ = write!(&mut ctx.text_writer(V2(0, 8), 0.1, color::LIGHTGREEN)
                       .set_border(color::BLACK),
                       "FPS {}", fps);

        if action::control_state() == action::ReadyToUpdate {
            action::update();
        }
    }

    pub fn save_game(&self) {
        let save_data = world::save();
        let mut file = File::create(&Path::new("/tmp/magog_save.json"));
        file.write_str(save_data.as_slice());
    }

    pub fn load_game(&mut self) {
        let path = Path::new("/tmp/magog_save.json");
        if !path.exists() { return; }
        let save_data = File::open(&path).read_to_string().unwrap();
        world::load(save_data.as_slice());
    }

    /// Process a player control keypress.
    pub fn process_key(&mut self, key: key::Key) -> bool {
        if action::control_state() != action::AwaitingInput {
            return false;
        }

        match key {
            key::KeyQ | key::KeyPad7 => { action::input(Step(NorthWest)); }
            key::KeyW | key::KeyPad8 | key::KeyUp => { action::input(Step(North)); }
            key::KeyE | key::KeyPad9 => { action::input(Step(NorthEast)); }
            key::KeyA | key::KeyPad1 => { action::input(Step(SouthWest)); }
            key::KeyS | key::KeyPad2 | key::KeyDown => { action::input(Step(South)); }
            key::KeyD | key::KeyPad3 => { action::input(Step(SouthEast)); }
            key::KeyF5 => { self.save_game(); }
            key::KeyF9 => { self.load_game(); }
            _ => { return false; }
        }
        return true;
    }

    pub fn process(&mut self, event: event::Event) -> bool {
        match event {
            event::Render(ctx) => {
                self.update(ctx);
            }
            event::KeyPressed(key::KeyEscape) => {
                return false;
            }
            event::KeyPressed(k) => {
                self.process_key(k);
            }
            _ => ()
        }
        true
    }
}
<|endoftext|>